refactor: rename Fabled Assistant to Fabled Scribe
Updates user-visible branding across frontend (PWA manifest, page title, Settings, push fallback), backend (email templates and subjects, LLM system prompt, CalDAV displayname, SMTP from-name default), README, quickstart compose, and MCP server description. Also updates the CI image path and quickstart image reference to git.fabledsword.com/bvandeusen/fabledscribe in preparation for the Forgejo repo rename. Internal Python package, env vars, and database schema unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -57,7 +57,7 @@ permissions:
|
||||
|
||||
env:
|
||||
REGISTRY: git.fabledsword.com
|
||||
IMAGE: git.fabledsword.com/bvandeusen/fabledassistant
|
||||
IMAGE: git.fabledsword.com/bvandeusen/fabledscribe
|
||||
|
||||
jobs:
|
||||
typecheck:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Fabled Assistant
|
||||
# Fabled Scribe
|
||||
|
||||
A self-hosted second brain and project management application with integrated LLM capabilities. Write, organise, and act on your notes and tasks with the help of a local AI assistant — all running on your own hardware.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Fabled Assistant — Quick Start
|
||||
# Fabled Scribe — Quick Start
|
||||
#
|
||||
# No build required. Pulls the latest pre-built image from the registry.
|
||||
#
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
services:
|
||||
app:
|
||||
image: git.fabledsword.com/bvandeusen/fabledassistant:latest
|
||||
image: git.fabledsword.com/bvandeusen/fabledscribe:latest
|
||||
ports:
|
||||
- "5000:5000"
|
||||
environment:
|
||||
|
||||
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
|
||||
[project]
|
||||
name = "fable-mcp"
|
||||
version = "0.2.6"
|
||||
description = "MCP server for Fabled Assistant"
|
||||
description = "MCP server for Fabled Scribe"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"mcp[cli]>=1.0",
|
||||
|
||||
+2
-2
@@ -9,8 +9,8 @@
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-title" content="Fabled">
|
||||
<title>Fabled Assistant</title>
|
||||
<meta name="apple-mobile-web-app-title" content="Scribe">
|
||||
<title>Fabled Scribe</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Fabled Assistant",
|
||||
"short_name": "Fabled",
|
||||
"name": "Fabled Scribe",
|
||||
"short_name": "Scribe",
|
||||
"description": "Your self-hosted second brain with AI assistance",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
|
||||
@@ -12,7 +12,7 @@ self.addEventListener('push', event => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
return self.registration.showNotification(data.title || 'Fabled Assistant', {
|
||||
return self.registration.showNotification(data.title || 'Scribe', {
|
||||
body: data.body || '',
|
||||
icon: '/favicon.ico',
|
||||
badge: '/favicon.ico',
|
||||
|
||||
@@ -501,7 +501,7 @@ const smtp = ref({
|
||||
smtp_username: "",
|
||||
smtp_password: "",
|
||||
smtp_from_address: "",
|
||||
smtp_from_name: "Fabled Assistant",
|
||||
smtp_from_name: "Fabled Scribe",
|
||||
smtp_use_tls: "true",
|
||||
});
|
||||
const savingSmtp = ref(false);
|
||||
@@ -1981,7 +1981,7 @@ function formatUserDate(iso: string): string {
|
||||
|
||||
<section class="settings-section full-width">
|
||||
<h2>About</h2>
|
||||
<p class="version-line">Fabled Assistant <span class="version-badge">{{ appVersion }}</span></p>
|
||||
<p class="version-line">Fabled Scribe <span class="version-badge">{{ appVersion }}</span></p>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
@@ -2741,7 +2741,7 @@ FABLE_API_KEY={{ effectiveApiKey }}</pre>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="smtp-from-name">From Name</label>
|
||||
<input id="smtp-from-name" v-model="smtp.smtp_from_name" type="text" placeholder="Fabled Assistant" class="input" />
|
||||
<input id="smtp-from-name" v-model="smtp.smtp_from_name" type="text" placeholder="Fabled Scribe" class="input" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="checkbox-field">
|
||||
|
||||
@@ -52,7 +52,7 @@ class Config:
|
||||
SMTP_USERNAME: str = os.environ.get("SMTP_USERNAME", "")
|
||||
SMTP_PASSWORD: str = _read_secret("SMTP_PASSWORD", "SMTP_PASSWORD_FILE", "")
|
||||
SMTP_FROM_ADDRESS: str = os.environ.get("SMTP_FROM_ADDRESS", "")
|
||||
SMTP_FROM_NAME: str = os.environ.get("SMTP_FROM_NAME", "Fabled Assistant")
|
||||
SMTP_FROM_NAME: str = os.environ.get("SMTP_FROM_NAME", "Fabled Scribe")
|
||||
SMTP_USE_TLS: bool = os.environ.get("SMTP_USE_TLS", "true").lower() in ("1", "true", "yes")
|
||||
BASE_URL: str = os.environ.get("BASE_URL", "http://localhost:5000").rstrip("/")
|
||||
TRUST_PROXY_HEADERS: bool = os.environ.get("TRUST_PROXY_HEADERS", "").lower() in ("1", "true", "yes")
|
||||
|
||||
@@ -66,7 +66,7 @@ async def setup_user_calendar(user_id: int) -> bool:
|
||||
<set>
|
||||
<prop>
|
||||
<resourcetype><collection/><C:calendar/></resourcetype>
|
||||
<displayname>Fabled Assistant</displayname>
|
||||
<displayname>Fabled Scribe</displayname>
|
||||
</prop>
|
||||
</set>
|
||||
</mkcol>""",
|
||||
|
||||
@@ -38,7 +38,7 @@ _EMAIL_LOGO_SVG = (
|
||||
|
||||
|
||||
def _email_html(title: str, body: str) -> str:
|
||||
"""Wrap email body content in the standard Fabled Assistant template."""
|
||||
"""Wrap email body content in the standard Fabled Scribe template."""
|
||||
return f"""<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
@@ -56,7 +56,7 @@ def _email_html(title: str, body: str) -> str:
|
||||
<!-- Header -->
|
||||
<div style="background:linear-gradient(135deg,#7c3aed 0%,#6d28d9 100%);padding:24px 28px;text-align:center;">
|
||||
<div style="margin-bottom:8px;">
|
||||
{_EMAIL_LOGO_SVG}<span style="display:inline-block;vertical-align:middle;color:#ffffff;font-size:18px;font-weight:700;letter-spacing:0.01em;">Fabled Assistant</span>
|
||||
{_EMAIL_LOGO_SVG}<span style="display:inline-block;vertical-align:middle;color:#ffffff;font-size:18px;font-weight:700;letter-spacing:0.01em;">Fabled Scribe</span>
|
||||
</div>
|
||||
<p style="margin:0;color:#ede9fe;font-size:13px;letter-spacing:0.03em;">{title}</p>
|
||||
</div>
|
||||
@@ -68,7 +68,7 @@ def _email_html(title: str, body: str) -> str:
|
||||
|
||||
<!-- Footer -->
|
||||
<div style="border-top:1px solid #ede9fe;padding:16px 28px;text-align:center;background:#faf5ff;">
|
||||
<p style="margin:0;color:#a78bfa;font-size:12px;">Sent by your Fabled Assistant instance.</p>
|
||||
<p style="margin:0;color:#a78bfa;font-size:12px;">Sent by your Fabled Scribe instance.</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -146,7 +146,7 @@ async def send_email(to: str, subject: str, html_body: str) -> None:
|
||||
username = config.get("smtp_username", "")
|
||||
password = config.get("smtp_password", "")
|
||||
from_address = config.get("smtp_from_address", "")
|
||||
from_name = config.get("smtp_from_name", "Fabled Assistant")
|
||||
from_name = config.get("smtp_from_name", "Fabled Scribe")
|
||||
use_tls = config.get("smtp_use_tls", "true") == "true"
|
||||
|
||||
msg = EmailMessage()
|
||||
@@ -176,6 +176,6 @@ async def send_test_email(to: str) -> None:
|
||||
"""Send a branded test email."""
|
||||
body = """
|
||||
<p style="margin:0 0 12px;color:#1e1b4b;font-size:15px;font-weight:600;">SMTP is configured correctly</p>
|
||||
<p style="margin:0;color:#6b7280;font-size:14px;">Your Fabled Assistant instance can send email notifications.</p>
|
||||
<p style="margin:0;color:#6b7280;font-size:14px;">Your Fabled Scribe instance can send email notifications.</p>
|
||||
"""
|
||||
await send_email(to, "Fabled Assistant - Test Email", _email_html("Test Email", body))
|
||||
await send_email(to, "Fabled Scribe - Test Email", _email_html("Test Email", body))
|
||||
|
||||
@@ -632,7 +632,7 @@ async def build_context(
|
||||
tool_guidance = "\n".join(tool_lines)
|
||||
|
||||
static_block = (
|
||||
f"You are a helpful assistant named {assistant_name}, integrated into a note-taking and task-tracking app called Fabled Assistant. "
|
||||
f"You are a helpful assistant named {assistant_name}, integrated into a note-taking and task-tracking app called Fabled Scribe. "
|
||||
"Help users with their notes, tasks, and general questions. "
|
||||
"When note context is provided, use it to give relevant answers.\n\n"
|
||||
f"{tool_guidance}"
|
||||
|
||||
@@ -91,7 +91,7 @@ async def notify_security_event(
|
||||
</table>
|
||||
<p style="margin:16px 0 0;color:#9ca3af;font-size:12px;">If this wasn't you, change your password immediately.</p>
|
||||
"""
|
||||
await send_email(email, f"Fabled Assistant - {label}", _email_html("Security Alert", body))
|
||||
await send_email(email, f"Fabled Scribe - {label}", _email_html("Security Alert", body))
|
||||
except Exception:
|
||||
logger.exception("Failed to send security notification for user %d", user_id)
|
||||
|
||||
@@ -113,7 +113,7 @@ async def send_password_reset_email(email: str, reset_url: str) -> None:
|
||||
<p style="margin:0;color:#9ca3af;font-size:12px;">If the button doesn't work, copy and paste this link:</p>
|
||||
<p style="margin:4px 0 0;color:#9ca3af;font-size:12px;word-break:break-all;">{reset_url}</p>
|
||||
"""
|
||||
await send_email(email, "Fabled Assistant - Password Reset", _email_html("Password Reset", body))
|
||||
await send_email(email, "Fabled Scribe - Password Reset", _email_html("Password Reset", body))
|
||||
|
||||
|
||||
async def send_password_reset_success_email(email: str) -> None:
|
||||
@@ -125,14 +125,14 @@ async def send_password_reset_success_email(email: str) -> None:
|
||||
</p>
|
||||
<p style="margin:0;color:#6b7280;font-size:13px;">If you didn't make this change, please contact your administrator immediately.</p>
|
||||
"""
|
||||
await send_email(email, "Fabled Assistant - Password Changed", _email_html("Password Changed", body))
|
||||
await send_email(email, "Fabled Scribe - Password Changed", _email_html("Password Changed", body))
|
||||
|
||||
|
||||
async def send_invitation_email(email: str, invite_url: str, invited_by_username: str) -> None:
|
||||
"""Send a branded invitation email with a registration link."""
|
||||
body = f"""
|
||||
<p style="margin:0 0 16px;color:#374151;font-size:15px;">
|
||||
<strong>{invited_by_username}</strong> has invited you to join Fabled Assistant.
|
||||
<strong>{invited_by_username}</strong> has invited you to join Fabled Scribe.
|
||||
Click the button below to create your account.
|
||||
</p>
|
||||
<div style="text-align:center;margin:24px 0;">
|
||||
@@ -146,7 +146,7 @@ async def send_invitation_email(email: str, invite_url: str, invited_by_username
|
||||
<p style="margin:0;color:#9ca3af;font-size:12px;">If the button doesn't work, copy and paste this link:</p>
|
||||
<p style="margin:4px 0 0;color:#9ca3af;font-size:12px;word-break:break-all;">{invite_url}</p>
|
||||
"""
|
||||
await send_email(email, "Fabled Assistant - You're Invited!", _email_html("You're Invited!", body))
|
||||
await send_email(email, "Fabled Scribe - You're Invited!", _email_html("You're Invited!", body))
|
||||
|
||||
|
||||
async def check_due_tasks() -> None:
|
||||
@@ -225,7 +225,7 @@ async def check_due_tasks() -> None:
|
||||
{task_rows}
|
||||
</table>
|
||||
"""
|
||||
await send_email(email, f"Fabled Assistant - {len(user_tasks)} Task(s) Due", _email_html("Task Reminders", body))
|
||||
await send_email(email, f"Fabled Scribe - {len(user_tasks)} Task(s) Due", _email_html("Task Reminders", body))
|
||||
await log_audit(
|
||||
"task_reminder",
|
||||
user_id=user_id,
|
||||
|
||||
Reference in New Issue
Block a user