Skip to content

Commit 929cf8f

Browse files
ersinkocclaude
andcommitted
🔧 fix(ci): move deploy workflow to repo root, fix formatting
- Move website deploy workflow from website/.github/ to .github/workflows/deploy-website.yml (GitHub only reads workflows from repo root) - Fix Prettier formatting on all 45 website files Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3735e63 commit 929cf8f

45 files changed

Lines changed: 3105 additions & 1510 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
name: Deploy to GitHub Pages
1+
name: Deploy Website
22

33
on:
44
push:
55
branches: [main]
66
paths:
7-
- "website/**"
7+
- 'website/**'
8+
- '.github/workflows/deploy-website.yml'
89
workflow_dispatch:
910

1011
permissions:
@@ -13,7 +14,7 @@ permissions:
1314
id-token: write
1415

1516
concurrency:
16-
group: "pages"
17+
group: pages
1718
cancel-in-progress: false
1819

1920
jobs:
@@ -29,8 +30,8 @@ jobs:
2930
- name: Setup Node.js
3031
uses: actions/setup-node@v4
3132
with:
32-
node-version: "22"
33-
cache: "npm"
33+
node-version: '22'
34+
cache: 'npm'
3435
cache-dependency-path: website/package-lock.json
3536

3637
- name: Install dependencies
@@ -40,7 +41,7 @@ jobs:
4041
run: npm run build
4142

4243
- name: Setup Pages
43-
uses: actions/configure-pages@v4
44+
uses: actions/configure-pages@v5
4445

4546
- name: Upload artifact
4647
uses: actions/upload-pages-artifact@v3

website/index.html

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,25 @@
44
<meta charset="UTF-8" />
55
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7-
<meta name="description" content="OwnPilot — Privacy-first personal AI assistant platform. Self-hosted, 190+ tools, soul agents, multi-provider AI, workflows, and more." />
7+
<meta
8+
name="description"
9+
content="OwnPilot — Privacy-first personal AI assistant platform. Self-hosted, 190+ tools, soul agents, multi-provider AI, workflows, and more."
10+
/>
811
<meta property="og:title" content="OwnPilot — Privacy-First Personal AI Assistant" />
9-
<meta property="og:description" content="Self-hosted AI assistant with 190+ tools, soul agents, workflows, and 96 AI providers. Your data stays yours." />
12+
<meta
13+
property="og:description"
14+
content="Self-hosted AI assistant with 190+ tools, soul agents, workflows, and 96 AI providers. Your data stays yours."
15+
/>
1016
<meta property="og:type" content="website" />
1117
<meta property="og:url" content="https://ownpilot.dev" />
1218
<meta name="twitter:card" content="summary_large_image" />
1319
<title>OwnPilot — Privacy-First Personal AI Assistant</title>
1420
<link rel="preconnect" href="https://fonts.googleapis.com" />
1521
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
16-
<link href="https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700;800&family=Geist+Mono:wght@400;500&display=swap" rel="stylesheet" />
22+
<link
23+
href="https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700;800&family=Geist+Mono:wght@400;500&display=swap"
24+
rel="stylesheet"
25+
/>
1726
</head>
1827
<body>
1928
<div id="root"></div>

website/public/404.html

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
var l = window.location;
99
l.replace(
1010
l.protocol +
11-
"//" +
11+
'//' +
1212
l.hostname +
13-
(l.port ? ":" + l.port : "") +
14-
l.pathname.split("/").slice(0, 1).join("/") +
15-
"/?/" +
16-
l.pathname.slice(1).replace(/&/g, "~and~") +
17-
(l.search ? "&" + l.search.slice(1).replace(/&/g, "~and~") : "") +
13+
(l.port ? ':' + l.port : '') +
14+
l.pathname.split('/').slice(0, 1).join('/') +
15+
'/?/' +
16+
l.pathname.slice(1).replace(/&/g, '~and~') +
17+
(l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') +
1818
l.hash
1919
);
2020
</script>

website/src/App.tsx

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,63 @@
1-
import { HashRouter, Routes, Route } from "react-router";
2-
import { Suspense, lazy, useEffect } from "react";
3-
import { useThemeStore } from "@/hooks/useTheme";
1+
import { HashRouter, Routes, Route } from 'react-router';
2+
import { Suspense, lazy, useEffect } from 'react';
3+
import { useThemeStore } from '@/hooks/useTheme';
44

55
// Pages
6-
import { HomePage } from "@/pages/HomePage";
7-
import { NotFoundPage } from "@/pages/NotFoundPage";
6+
import { HomePage } from '@/pages/HomePage';
7+
import { NotFoundPage } from '@/pages/NotFoundPage';
88

99
// Lazy-loaded pages
1010
const ChangelogPage = lazy(() =>
11-
import("@/pages/ChangelogPage").then((m) => ({ default: m.ChangelogPage }))
11+
import('@/pages/ChangelogPage').then((m) => ({ default: m.ChangelogPage }))
1212
);
1313
const IntroductionPage = lazy(() =>
14-
import("@/pages/docs/IntroductionPage").then((m) => ({ default: m.IntroductionPage }))
14+
import('@/pages/docs/IntroductionPage').then((m) => ({ default: m.IntroductionPage }))
1515
);
1616
const QuickStartPage = lazy(() =>
17-
import("@/pages/docs/QuickStartPage").then((m) => ({ default: m.QuickStartPage }))
17+
import('@/pages/docs/QuickStartPage').then((m) => ({ default: m.QuickStartPage }))
1818
);
1919
const InstallationPage = lazy(() =>
20-
import("@/pages/docs/InstallationPage").then((m) => ({ default: m.InstallationPage }))
20+
import('@/pages/docs/InstallationPage').then((m) => ({ default: m.InstallationPage }))
2121
);
2222
const ArchitecturePage = lazy(() =>
23-
import("@/pages/docs/ArchitecturePage").then((m) => ({ default: m.ArchitecturePage }))
23+
import('@/pages/docs/ArchitecturePage').then((m) => ({ default: m.ArchitecturePage }))
2424
);
2525
const ProvidersPage = lazy(() =>
26-
import("@/pages/docs/ProvidersPage").then((m) => ({ default: m.ProvidersPage }))
26+
import('@/pages/docs/ProvidersPage').then((m) => ({ default: m.ProvidersPage }))
2727
);
2828
const AgentsPage = lazy(() =>
29-
import("@/pages/docs/AgentsPage").then((m) => ({ default: m.AgentsPage }))
29+
import('@/pages/docs/AgentsPage').then((m) => ({ default: m.AgentsPage }))
3030
);
3131
const ToolsPage = lazy(() =>
32-
import("@/pages/docs/ToolsPage").then((m) => ({ default: m.ToolsPage }))
32+
import('@/pages/docs/ToolsPage').then((m) => ({ default: m.ToolsPage }))
3333
);
3434
const WorkflowsPage = lazy(() =>
35-
import("@/pages/docs/WorkflowsPage").then((m) => ({ default: m.WorkflowsPage }))
35+
import('@/pages/docs/WorkflowsPage').then((m) => ({ default: m.WorkflowsPage }))
3636
);
3737
const SecurityPage = lazy(() =>
38-
import("@/pages/docs/SecurityPage").then((m) => ({ default: m.SecurityPage }))
38+
import('@/pages/docs/SecurityPage').then((m) => ({ default: m.SecurityPage }))
3939
);
4040
const ApiReferencePage = lazy(() =>
41-
import("@/pages/docs/ApiReferencePage").then((m) => ({ default: m.ApiReferencePage }))
41+
import('@/pages/docs/ApiReferencePage').then((m) => ({ default: m.ApiReferencePage }))
4242
);
4343
const DeploymentPage = lazy(() =>
44-
import("@/pages/docs/DeploymentPage").then((m) => ({ default: m.DeploymentPage }))
44+
import('@/pages/docs/DeploymentPage').then((m) => ({ default: m.DeploymentPage }))
4545
);
4646
const PersonalDataPage = lazy(() =>
47-
import("@/pages/docs/PersonalDataPage").then((m) => ({ default: m.PersonalDataPage }))
47+
import('@/pages/docs/PersonalDataPage').then((m) => ({ default: m.PersonalDataPage }))
4848
);
4949
const ChannelsPage = lazy(() =>
50-
import("@/pages/docs/ChannelsPage").then((m) => ({ default: m.ChannelsPage }))
51-
);
52-
const McpPage = lazy(() =>
53-
import("@/pages/docs/McpPage").then((m) => ({ default: m.McpPage }))
50+
import('@/pages/docs/ChannelsPage').then((m) => ({ default: m.ChannelsPage }))
5451
);
52+
const McpPage = lazy(() => import('@/pages/docs/McpPage').then((m) => ({ default: m.McpPage })));
5553
const CodingAgentsPage = lazy(() =>
56-
import("@/pages/docs/CodingAgentsPage").then((m) => ({ default: m.CodingAgentsPage }))
54+
import('@/pages/docs/CodingAgentsPage').then((m) => ({ default: m.CodingAgentsPage }))
5755
);
5856
const EdgeDevicesPage = lazy(() =>
59-
import("@/pages/docs/EdgeDevicesPage").then((m) => ({ default: m.EdgeDevicesPage }))
57+
import('@/pages/docs/EdgeDevicesPage').then((m) => ({ default: m.EdgeDevicesPage }))
6058
);
6159
const ConfigurationPage = lazy(() =>
62-
import("@/pages/docs/ConfigurationPage").then((m) => ({ default: m.ConfigurationPage }))
60+
import('@/pages/docs/ConfigurationPage').then((m) => ({ default: m.ConfigurationPage }))
6361
);
6462

6563
function PageLoader() {
@@ -81,14 +79,14 @@ function ThemeInitializer() {
8179
setTheme(theme);
8280

8381
// Listen for system theme changes
84-
const mq = window.matchMedia("(prefers-color-scheme: dark)");
82+
const mq = window.matchMedia('(prefers-color-scheme: dark)');
8583
const handler = () => {
86-
if (theme === "system") {
87-
setTheme("system");
84+
if (theme === 'system') {
85+
setTheme('system');
8886
}
8987
};
90-
mq.addEventListener("change", handler);
91-
return () => mq.removeEventListener("change", handler);
88+
mq.addEventListener('change', handler);
89+
return () => mq.removeEventListener('change', handler);
9290
}, [theme, setTheme]);
9391

9492
return null;

website/src/components/home/Architecture.tsx

Lines changed: 82 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,81 @@
1-
import { useRef } from "react";
2-
import { motion, useInView } from "framer-motion";
3-
import { Badge } from "@/components/ui/Badge";
1+
import { useRef } from 'react';
2+
import { motion, useInView } from 'framer-motion';
3+
import { Badge } from '@/components/ui/Badge';
44

55
const packages = [
66
{
7-
name: "@ownpilot/core",
8-
size: "~62K LOC",
9-
files: "160+ files",
10-
color: "border-purple-500/30 bg-purple-500/5",
11-
badge: "bg-purple-500/10 text-purple-500",
12-
description: "AI engine, tool framework, plugin architecture, security primitives, sandboxed code execution, AES-256-GCM encryption, tamper-evident audit, PII detection. Minimal dependencies.",
13-
modules: ["agent/ — Multi-provider AI engine", "agent/orchestra/ — Fan-out, race, pipeline", "agent/tools/ — 190+ tool definitions", "plugins/ — Isolation + marketplace", "sandbox/ — VM, Docker, Worker threads", "crypto/ — Zero-dep AES-256-GCM", "privacy/ — PII detection (15+ types)"],
7+
name: '@ownpilot/core',
8+
size: '~62K LOC',
9+
files: '160+ files',
10+
color: 'border-purple-500/30 bg-purple-500/5',
11+
badge: 'bg-purple-500/10 text-purple-500',
12+
description:
13+
'AI engine, tool framework, plugin architecture, security primitives, sandboxed code execution, AES-256-GCM encryption, tamper-evident audit, PII detection. Minimal dependencies.',
14+
modules: [
15+
'agent/ — Multi-provider AI engine',
16+
'agent/orchestra/ — Fan-out, race, pipeline',
17+
'agent/tools/ — 190+ tool definitions',
18+
'plugins/ — Isolation + marketplace',
19+
'sandbox/ — VM, Docker, Worker threads',
20+
'crypto/ — Zero-dep AES-256-GCM',
21+
'privacy/ — PII detection (15+ types)',
22+
],
1423
},
1524
{
16-
name: "@ownpilot/gateway",
17-
size: "~76K LOC",
18-
files: "389 test files",
19-
color: "border-blue-500/30 bg-blue-500/5",
20-
badge: "bg-blue-500/10 text-blue-500",
21-
description: "Hono HTTP API server. Routes, services, DB repositories, agent runners, WebSocket, channels (Telegram + WhatsApp), MCP client/server, plugin init, triggers.",
22-
modules: ["routes/ — 55+ route modules", "services/ — 60+ business services", "db/repositories/ — 45+ repos", "channels/ — Telegram + WhatsApp", "services/workflow/ — 23 node executors", "services/soul-heartbeat-service.ts", "tools/ — CLI, edge, browser, coding"],
25+
name: '@ownpilot/gateway',
26+
size: '~76K LOC',
27+
files: '389 test files',
28+
color: 'border-blue-500/30 bg-blue-500/5',
29+
badge: 'bg-blue-500/10 text-blue-500',
30+
description:
31+
'Hono HTTP API server. Routes, services, DB repositories, agent runners, WebSocket, channels (Telegram + WhatsApp), MCP client/server, plugin init, triggers.',
32+
modules: [
33+
'routes/ — 55+ route modules',
34+
'services/ — 60+ business services',
35+
'db/repositories/ — 45+ repos',
36+
'channels/ — Telegram + WhatsApp',
37+
'services/workflow/ — 23 node executors',
38+
'services/soul-heartbeat-service.ts',
39+
'tools/ — CLI, edge, browser, coding',
40+
],
2341
},
2442
{
25-
name: "@ownpilot/ui",
26-
size: "~40K LOC",
27-
files: "57+ pages",
28-
color: "border-emerald-500/30 bg-emerald-500/5",
29-
badge: "bg-emerald-500/10 text-emerald-500",
30-
description: "React 19 + Vite 7 + Tailwind CSS 4 frontend. Code-split with lazy loading, dark mode, 120+ components, real-time WebSocket updates.",
31-
modules: ["pages/ — 57+ page components", "components/ — 120+ reusable UI", "hooks/ — WebSocket, chat store, theme", "api/ — Typed fetch wrapper + endpoints", "App.tsx — Route definitions"],
43+
name: '@ownpilot/ui',
44+
size: '~40K LOC',
45+
files: '57+ pages',
46+
color: 'border-emerald-500/30 bg-emerald-500/5',
47+
badge: 'bg-emerald-500/10 text-emerald-500',
48+
description:
49+
'React 19 + Vite 7 + Tailwind CSS 4 frontend. Code-split with lazy loading, dark mode, 120+ components, real-time WebSocket updates.',
50+
modules: [
51+
'pages/ — 57+ page components',
52+
'components/ — 120+ reusable UI',
53+
'hooks/ — WebSocket, chat store, theme',
54+
'api/ — Typed fetch wrapper + endpoints',
55+
'App.tsx — Route definitions',
56+
],
3257
},
3358
{
34-
name: "@ownpilot/cli",
35-
size: "CLI tools",
36-
files: "293 tests",
37-
color: "border-orange-500/30 bg-orange-500/5",
38-
badge: "bg-orange-500/10 text-orange-500",
39-
description: "Commander.js CLI for server management, bot control, workspace operations, configuration, and channel management.",
40-
modules: ["commands/start — Start server", "commands/config — Manage settings", "commands/bot — Telegram bot control", "commands/workspace — Isolation", "commands/skill — Install/remove skills"],
59+
name: '@ownpilot/cli',
60+
size: 'CLI tools',
61+
files: '293 tests',
62+
color: 'border-orange-500/30 bg-orange-500/5',
63+
badge: 'bg-orange-500/10 text-orange-500',
64+
description:
65+
'Commander.js CLI for server management, bot control, workspace operations, configuration, and channel management.',
66+
modules: [
67+
'commands/start — Start server',
68+
'commands/config — Manage settings',
69+
'commands/bot — Telegram bot control',
70+
'commands/workspace — Isolation',
71+
'commands/skill — Install/remove skills',
72+
],
4173
},
4274
];
4375

4476
export function Architecture() {
4577
const ref = useRef<HTMLDivElement>(null);
46-
const isInView = useInView(ref, { once: true, margin: "-100px" });
78+
const isInView = useInView(ref, { once: true, margin: '-100px' });
4779

4880
return (
4981
<section className="py-24 bg-[var(--color-bg)]">
@@ -57,11 +89,11 @@ export function Architecture() {
5789
Architecture
5890
</Badge>
5991
<h2 className="text-3xl sm:text-4xl font-bold tracking-tight text-[var(--color-text)] mb-4">
60-
TypeScript monorepo,{" "}
61-
<span className="text-gradient">built to scale</span>
92+
TypeScript monorepo, <span className="text-gradient">built to scale</span>
6293
</h2>
6394
<p className="text-[var(--color-text-muted)]">
64-
4 packages, single port in production. Gateway serves the bundled UI, REST API, WebSocket, and SSE — all on port 8080.
95+
4 packages, single port in production. Gateway serves the bundled UI, REST API,
96+
WebSocket, and SSE — all on port 8080.
6597
</p>
6698
</motion.div>
6799
</div>
@@ -110,7 +142,10 @@ export function Architecture() {
110142
</p>
111143
<ul className="space-y-1">
112144
{pkg.modules.map((mod) => (
113-
<li key={mod} className="flex items-start gap-2 text-xs text-[var(--color-text-muted)]">
145+
<li
146+
key={mod}
147+
className="flex items-start gap-2 text-xs text-[var(--color-text-muted)]"
148+
>
114149
<span className="text-[var(--color-text-subtle)] mt-0.5 shrink-0"></span>
115150
<code className="font-mono">{mod}</code>
116151
</li>
@@ -131,7 +166,15 @@ export function Architecture() {
131166
Message Pipeline
132167
</h3>
133168
<div className="flex flex-wrap items-center gap-2">
134-
{["Request", "Audit", "Persistence", "Post-Processing", "Context-Injection", "Agent-Execution", "Response"].map((stage, i, arr) => (
169+
{[
170+
'Request',
171+
'Audit',
172+
'Persistence',
173+
'Post-Processing',
174+
'Context-Injection',
175+
'Agent-Execution',
176+
'Response',
177+
].map((stage, i, arr) => (
135178
<div key={stage} className="flex items-center gap-2">
136179
<div className="px-3 py-1.5 rounded-lg bg-[var(--color-surface)] border border-[var(--color-border)] text-sm text-[var(--color-text-muted)] font-medium">
137180
{stage}
@@ -143,7 +186,8 @@ export function Architecture() {
143186
))}
144187
</div>
145188
<p className="mt-3 text-xs text-[var(--color-text-subtle)]">
146-
All messages (web UI, Telegram, WhatsApp, triggers) flow through the same MessageBus pipeline.
189+
All messages (web UI, Telegram, WhatsApp, triggers) flow through the same MessageBus
190+
pipeline.
147191
</p>
148192
</motion.div>
149193
</div>

0 commit comments

Comments
 (0)