Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 4 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@
# GOOGLE_CLIENT_SECRET=replace-with-your-google-oauth-client-secret
# POSTHOG_PUBLIC_KEY=replace-with-your-posthog-project-api-key
# POSTHOG_HOST=https://us.i.posthog.com
# LOOPS_API_KEY=replace-with-your-loops-api-key
# LOOPS_TRANSACTIONAL_VERIFY_EMAIL_ID=replace-with-your-loops-verify-template-id
# LOOPS_TRANSACTIONAL_RESET_PASSWORD_ID=replace-with-your-loops-reset-template-id
# LOOPS_TRANSACTIONAL_INVITATION_ID=replace-with-your-loops-invitation-template-id
# Note: this fork has no hosted transactional email provider wired up, so
# hosted mode also requires BYPASS_EMAIL_VERIFICATION=true — password reset
# and invitation emails are not sent in hosted mode.
# BYPASS_EMAIL_VERIFICATION=true

# Optional in self-hosted modes. Required if you want AI features like SAM,
# the in-app SEO agent. Create a key at https://openrouter.ai/settings/keys.
Expand Down
14 changes: 4 additions & 10 deletions .env.production.example
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,18 @@ DATABASE_PROVIDER=postgres
# HYPERDRIVE_ORIGIN_USER=
# HYPERDRIVE_ORIGIN_PASSWORD=

# Hosted auth.
# Hosted auth. Note: this fork has no hosted transactional email provider
# wired up, so hosted mode also requires BYPASS_EMAIL_VERIFICATION=true —
# password reset and invitation emails are not sent in hosted mode.
# GOOGLE_CLIENT_ID=
# GOOGLE_CLIENT_SECRET=
# LOOPS_API_KEY=
# LOOPS_TRANSACTIONAL_VERIFY_EMAIL_ID=
# LOOPS_TRANSACTIONAL_RESET_PASSWORD_ID=
# LOOPS_TRANSACTIONAL_INVITATION_ID=
# BYPASS_EMAIL_VERIFICATION=true
# TURNSTILE_SECRET_KEY=
# TURNSTILE_SITE_KEY=

# Billing, analytics, agents.
# AUTUMN_SECRET_KEY=
# AUTUMN_WEBHOOK_SECRET=
# Dub referral conversion tracking (leads + sales). Also requires, in the Dub
# dashboard: openseo.so allowlisted under workspace Tracking settings, partner
# link destinations kept on openseo.so, and the native Stripe integration
# disconnected (sales are reported by the app; both would double count).
# DUB_API_KEY=
# Long random secret shared only with scripts/erase-user-data.ts.
# GDPR_ERASURE_SECRET=
# POSTHOG_PUBLIC_KEY=
Expand Down
11 changes: 0 additions & 11 deletions alchemy.run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,18 +274,7 @@ const dataEnv = {
OPENROUTER_MODEL: optionalVar("OPENROUTER_MODEL"),
AUTUMN_SECRET_KEY: optionalSecret("AUTUMN_SECRET_KEY"),
AUTUMN_WEBHOOK_SECRET: optionalSecret("AUTUMN_WEBHOOK_SECRET"),
DUB_API_KEY: optionalSecret("DUB_API_KEY"),
GDPR_ERASURE_SECRET: optionalSecret("GDPR_ERASURE_SECRET"),
LOOPS_API_KEY: optionalSecret("LOOPS_API_KEY"),
LOOPS_TRANSACTIONAL_VERIFY_EMAIL_ID: optionalVar(
"LOOPS_TRANSACTIONAL_VERIFY_EMAIL_ID",
),
LOOPS_TRANSACTIONAL_RESET_PASSWORD_ID: optionalVar(
"LOOPS_TRANSACTIONAL_RESET_PASSWORD_ID",
),
LOOPS_TRANSACTIONAL_INVITATION_ID: optionalVar(
"LOOPS_TRANSACTIONAL_INVITATION_ID",
),
POSTHOG_PUBLIC_KEY: optionalVar("POSTHOG_PUBLIC_KEY"),
POSTHOG_HOST: optionalVar("POSTHOG_HOST"),
TURNSTILE_SECRET_KEY: optionalSecret("TURNSTILE_SECRET_KEY"),
Expand Down
4 changes: 2 additions & 2 deletions public/site.webmanifest
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "OpenSEO",
"short_name": "OpenSEO",
"name": "Sightline",
"short_name": "Sightline",
"icons": [
{
"src": "/android-chrome-192x192.png",
Expand Down
2 changes: 1 addition & 1 deletion src/client/components/Markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type Props = {
/**
* Shared Markdown renderer with explicit per-element Tailwind classes.
*
* OpenSEO doesn't ship `@tailwindcss/typography`, so `prose` classes are
* Sightline doesn't ship `@tailwindcss/typography`, so `prose` classes are
* no-ops — every block element is styled here instead. Tables use daisyUI's
* `table table-sm` so model- and strategy-generated tables stay readable.
*
Expand Down
2 changes: 1 addition & 1 deletion src/client/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export function Sidebar({ projectId, onNavigate, onClose }: SidebarProps) {
onClick={onNavigate}
className="text-base font-semibold text-base-content"
>
OpenSEO
Sightline
</Link>
{onClose ? (
<button
Expand Down
4 changes: 1 addition & 3 deletions src/client/features/ai-mcp/AgentSetup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ export function AgentSetup({
}) {
const [intent, setIntent] = useState(initialIntent ?? "");
const prompt = getAgentSetupPrompt(
typeof window === "undefined"
? "https://app.openseo.so"
: window.location.origin,
typeof window === "undefined" ? "" : window.location.origin,
);
const Heading = onComplete ? "h1" : "h2";
const chooseIntent = (answer: "yes" | "no") => {
Expand Down
4 changes: 2 additions & 2 deletions src/client/features/ai-mcp/AgentSetupPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Package } from "lucide-react";
import { CopyButton } from "./SetupControls";

export const AGENT_SETUP_DESCRIPTION =
"Paste this prompt into your agent to automatically configure OpenSEO for you.";
"Paste this prompt into your agent to automatically configure Sightline for you.";

export function AgentSetupPanel({
prompt,
Expand All @@ -19,7 +19,7 @@ export function AgentSetupPanel({
<Package className="size-5 text-base-content/70" />
</span>
<div>
<p className="text-sm font-medium">OpenSEO plugin</p>
<p className="text-sm font-medium">Sightline plugin</p>
<p className="mt-1 text-xs text-base-content/55">
MCP connection + SEO skills
</p>
Expand Down
4 changes: 2 additions & 2 deletions src/client/features/ai-mcp/agentUpdatePrompt.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Update my installed OpenSEO skills using https://openseo.so/docs/agent-setup#update-your-skills.
Update my installed Sightline skills using https://openseo.so/docs/agent-setup#update-your-skills.

Identify this agent and how OpenSEO was installed. Use the matching plugin or skills installer, checking the installed client's help before running commands. Update only OpenSEO in its existing scope. Preserve my MCP endpoint, sign-in, and personal skill edits; ask before replacing conflicting edits. Avoid duplicate skills and do not install internal repository skills.
Identify this agent and how Sightline was installed. Use the matching plugin or skills installer, checking the installed client's help before running commands. Update only Sightline in its existing scope. Preserve my MCP endpoint, sign-in, and personal skill edits; ask before replacing conflicting edits. Avoid duplicate skills and do not install internal repository skills.

If the skills were copied manually, compare them with https://github.com/every-app/open-seo/tree/main/plugins/openseo/skills and update the installed public skill folders, including their supporting files. For Grok Bot or another agent without a verified update command, use its supported skill management flow or give me the exact manual steps available in this version.

Expand Down
2 changes: 1 addition & 1 deletion src/client/features/audit/results/ResultsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export function ResultsView({
? "The requested cooldown exceeded the audit time limit, so some URLs were left unvisited. This report is incomplete. "
: "Pages that returned 429 Too Many Requests could not be audited. "}
Re-run the audit after the rate limit resets, or ask the site owner to
allow the "OpenSEO-Audit" crawler.
allow the "Sightline-Audit" crawler.
</CrawlWarning>
)}

Expand Down
2 changes: 0 additions & 2 deletions src/client/features/audit/shared.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { AlertCircle, CheckCircle, Loader2 } from "lucide-react";

export const SUPPORT_EMAIL = "ben@openseo.so";

export function extractPathname(url: string): string {
try {
return new URL(url).pathname;
Expand Down
2 changes: 1 addition & 1 deletion src/client/features/auth/AuthPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export function AuthPageCard({
<div className="text-center space-y-3">
<img
src="/transparent-logo.png"
alt="OpenSEO"
alt="Sightline"
className="mx-auto size-10 rounded-lg"
/>
<div>
Expand Down
6 changes: 3 additions & 3 deletions src/client/features/billing/FreePlanBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function FreePlanBanner() {
return (
<BannerShell variant="error">
You&rsquo;ve used all your credits. {creditsActionLink} to continue
using OpenSEO.
using Sightline.
</BannerShell>
);
}
Expand All @@ -67,15 +67,15 @@ export function FreePlanBanner() {
return (
<BannerShell variant="warning">
You&rsquo;re running low on credits. {creditsActionLink} to keep using
OpenSEO.
Sightline.
</BannerShell>
);
}

if (isFreePlan) {
return (
<BannerShell variant="info">
We hope you&rsquo;re enjoying OpenSEO!{" "}
We hope you&rsquo;re enjoying Sightline!{" "}
<Link
to={SUBSCRIBE_ROUTE}
search={{ upgrade: true }}
Expand Down
10 changes: 4 additions & 6 deletions src/client/features/dashboard/DashboardSetupAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { markDashboardCompetitorClicked } from "@/serverFunctions/dashboard";
import type { DashboardSetupStep } from "@/types/schemas/dashboard";
import { parseResearchTarget } from "@/shared/researchScope";

const projectPrompt = `Use OpenSEO to set up a separate project for each website below. List my existing projects first and reuse matches so you don’t create duplicates. Set the country and language for each site, and ask me about anything missing.
const projectPrompt = `Use Sightline to set up a separate project for each website below. List my existing projects first and reuse matches so you don’t create duplicates. Set the country and language for each site, and ask me about anything missing.

Replace this list with my websites:
- Project name — website — country — language`;
Expand Down Expand Up @@ -68,12 +68,12 @@ export function DashboardSetupAction({
return (
<div className="max-w-2xl space-y-4">
<p className="text-sm leading-relaxed text-base-content/65">
Paste this prompt into your agent to automatically configure OpenSEO
Paste this prompt into your agent to automatically configure Sightline
for you.
</p>
<div className="flex flex-col gap-4 rounded-lg border border-base-300 bg-base-200/25 p-4 sm:flex-row sm:items-center sm:justify-between">
<div>
<p className="text-sm font-medium">OpenSEO plugin</p>
<p className="text-sm font-medium">Sightline plugin</p>
<p className="mt-1 text-xs text-base-content/60">
MCP connection + SEO skills
</p>
Expand All @@ -82,9 +82,7 @@ export function DashboardSetupAction({
<CopyButton
primary
value={getAgentSetupPrompt(
typeof window === "undefined"
? "https://app.openseo.so"
: window.location.origin,
typeof window === "undefined" ? "" : window.location.origin,
)}
label="Copy setup prompt"
successMessage="Setup prompt copied"
Expand Down
2 changes: 1 addition & 1 deletion src/client/features/dashboard/dashboardSteps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const setupSteps: {
{
id: "mcp",
label: "Connect your AI agent",
detail: "Use OpenSEO inside Claude or your favorite agent.",
detail: "Use Sightline inside Claude or your favorite agent.",
icon: Bot,
},
{
Expand Down
2 changes: 1 addition & 1 deletion src/client/features/gsc/GscReEngagementModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export function GscReEngagementModal({
New: Connect Google Search Console
</h2>
<p className="text-sm text-base-content/70">
Bring your real clicks, impressions, and rankings into OpenSEO and
Bring your real clicks, impressions, and rankings into Sightline and
query them from Claude or Codex over MCP. It never uses credits.
</p>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export function GoogleAccountRemovalDialog({
</h3>
<p className="break-all text-sm font-medium">{label}</p>
<p className="text-sm text-base-content/70">
This removes the account’s {name} connection from OpenSEO. You can
This removes the account’s {name} connection from Sightline. You can
reconnect it anytime.
</p>
{impact.isPending ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function GoogleOAuthSetupWarning({
<div className="space-y-1">
<p className="font-medium">Google OAuth client not configured</p>
<p className="text-base-content/70">
Add your Google client ID and secret to this OpenSEO deployment before
Add your Google client ID and secret to this Sightline deployment before
connecting {integrationName}.
</p>
<SafeExternalLink
Expand Down
4 changes: 2 additions & 2 deletions src/client/features/integrations/googleAuthErrorCopy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export function googleAuthErrorCopy(
return {
title: "Google account already connected",
description: providerLabel
? `Sign in to the OpenSEO user that linked it, open the ${providerLabel} property picker, and choose Remove account beside the Google account. Then link it here.`
: "That Google account is already linked to a different OpenSEO user. Sign in with that user, or contact support for help.",
? `Sign in to the Sightline user that linked it, open the ${providerLabel} property picker, and choose Remove account beside the Google account. Then link it here.`
: "That Google account is already linked to a different Sightline user. Sign in with that user, or contact support for help.",
};
default:
return {
Expand Down
10 changes: 6 additions & 4 deletions src/client/features/onboarding/CompactAgentPrompt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ export function CompactAgentPrompt({
onBack: () => void;
onFinish: () => void;
}) {
const prompt = getAgentSetupPrompt("https://app.openseo.so");
const prompt = getAgentSetupPrompt(
typeof window === "undefined" ? "" : window.location.origin,
);
const copy = (
<div className="[&>button]:h-11 [&>button]:w-full [&>button]:gap-2 [&>button]:text-sm">
<CopyButton
Expand Down Expand Up @@ -42,7 +44,7 @@ export function CompactAgentPrompt({
{treatment === "simple" && (
<>
<div className="mb-5 flex items-center justify-between gap-3">
<span className="text-sm font-medium">OpenSEO plugin</span>
<span className="text-sm font-medium">Sightline plugin</span>
<span className="rounded-md border border-base-300 px-2 py-1 text-xs text-base-content/60">
MCP + skills
</span>
Expand All @@ -59,11 +61,11 @@ export function CompactAgentPrompt({
<FileText className="size-3.5 text-base-content/60" /> Setup
prompt
</span>
<span className="text-xs text-base-content/45">OpenSEO</span>
<span className="text-xs text-base-content/45">Sightline</span>
</div>
<div className="p-5">
<p className="text-sm font-medium">
Set up OpenSEO in this agent.
Set up Sightline in this agent.
</p>
<p className="mt-2 text-xs leading-relaxed text-base-content/60">
Detect the agent. Install the plugin (MCP + skills).
Expand Down
2 changes: 1 addition & 1 deletion src/client/features/onboarding/OnboardingCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function OnboardingCard({
<div className="w-full max-w-xl py-8">
<div className="flex items-center justify-center gap-2 text-sm font-semibold">
<img src="/transparent-logo.png" alt="" className="size-7" />
OpenSEO
Sightline
</div>
<main className="mt-8 rounded-2xl border border-base-300 bg-base-100 p-6 shadow-sm md:mt-12 md:p-10">
<div
Expand Down
2 changes: 1 addition & 1 deletion src/client/features/onboarding/PostSignupOnboarding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export function PostSignupOnboarding({
/>
) : step === 2 ? (
<OnboardingChoiceGroup
title="How did you find OpenSEO?"
title="How did you find Sightline?"
options={[...SOURCE_OPTIONS]}
selectedValues={answers.source ? [answers.source] : []}
onToggle={(source) => updateAnswers({ source })}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function SearchConsoleOnboardingStep() {
Connect Google Search Console now?
</h1>
<p className="mt-3 text-sm leading-relaxed text-base-content/60">
Bring your real clicks and queries into OpenSEO and your AI agent. You
Bring your real clicks and queries into Sightline and your AI agent. You
can also do this later from the dashboard.
</p>
</div>
Expand Down
6 changes: 4 additions & 2 deletions src/client/features/onboarding/SignupPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,15 @@ export function SignupPreview({
}
>
<div className="mb-4 flex items-center gap-2 text-xs font-medium text-base-content/55">
<span>OpenSEO plugin</span>
<span>Sightline plugin</span>
<span aria-hidden="true">·</span>
<span>MCP + skills</span>
</div>
<CopyButton
primary
value={getAgentSetupPrompt("https://app.openseo.so")}
value={getAgentSetupPrompt(
typeof window === "undefined" ? "" : window.location.origin,
)}
label="Copy setup prompt"
successMessage="Setup prompt copied"
/>
Expand Down
2 changes: 1 addition & 1 deletion src/client/features/onboarding/SignupPreviewLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function SignupPreviewLayout({
const brand = (
<div className="flex items-center gap-2 text-sm font-semibold">
<img src="/transparent-logo.png" alt="" className="size-7" />
OpenSEO
Sightline
</div>
);
const milestones = (
Expand Down
2 changes: 1 addition & 1 deletion src/client/features/reports/ReportsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function ReportsList({
if (reports.length === 0) {
return (
<p className="rounded-lg border border-dashed border-base-300 px-4 py-6 text-sm text-base-content/60">
No reports yet. Run an OpenSEO skill such as seo-audit from Claude Code
No reports yet. Run an Sightline skill such as seo-audit from Claude Code
or Codex and the report will appear here.
</p>
);
Expand Down
4 changes: 2 additions & 2 deletions src/client/features/reports/shared.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ export function DeleteReportModal({

/**
* The share toggle. The link is built from the browser's own origin, so the
* same report shares correctly from app.openseo.so and from a self-hosted
* hostname without the server knowing either.
* same report shares correctly from any hosted or self-hosted hostname
* without the server knowing which one it is.
*/
export function ShareReportModal({
report,
Expand Down
2 changes: 1 addition & 1 deletion src/client/features/sam/ChatComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export function ChatComposer({
busy,
onSend,
onStop,
placeholder = "Ask Sam about your strategy or OpenSEO…",
placeholder = "Ask Sam about your strategy or Sightline…",
}: {
busy: boolean;
onSend: (text: string) => void;
Expand Down
2 changes: 1 addition & 1 deletion src/client/features/sam/SamChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export function SamChat({
<div className="space-y-1">
<p className="text-lg font-medium">What should we work on?</p>
<p className="max-w-sm text-sm text-base-content/60">
SAM is your in-app SEO agent with access to every OpenSEO research
SAM is your in-app SEO agent with access to every Sightline research
tool. Start a chat to get going.
</p>
</div>
Expand Down
Loading