feat(ui): declutter dashboard done-recently + MCP-access, add per-project stats
CI & Build / Python lint (push) Successful in 2s
CI & Build / TypeScript typecheck (push) Successful in 31s
CI & Build / Python tests (push) Successful in 49s
CI & Build / Build & push image (push) Successful in 58s

Dashboard:
- 'Done recently' chip-cloud -> compact uniform list (Active-now row style),
  showing 5 with inline expand to the rest (backend already returns up to 8).
- New 'Projects' rail card: each active project with 'N open · M done'.
  Backend already computed done_count (dashboard.py) — now surfaced in the
  /api/dashboard payload per active project.

MCP Access (Connect Claude / Claude Code):
- Progressive disclosure: lead with the pre-filled plugin-install snippet;
  fold server name, scope, marketplace URL, and the MCP-only path into a
  single 'Customize' expander. Desktop tab keeps its own server-name field.
- Marketplace URL now defaults to this instance's own repo via
  config.PLUGIN_MARKETPLACE_URL (env-overridable); /api/plugin/marketplace-url
  falls back to it, so the field + install snippet are pre-filled out of the
  box instead of showing a generic placeholder.

Refs #761

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-10 11:04:23 -04:00
parent 79aec4f9c1
commit da511fcc9f
5 changed files with 134 additions and 87 deletions
+10
View File
@@ -38,6 +38,16 @@ class Config:
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")
# Git URL of the repo that ships this Scribe plugin. There is one correct
# value per deployment (the repo serving the plugin), so it's a config
# default — not something each user types. Surfaced in Settings → MCP Access
# as the default install-command marketplace; an admin can still override it
# per-instance via the Plugin marketplace setting.
PLUGIN_MARKETPLACE_URL: str = os.environ.get(
"PLUGIN_MARKETPLACE_URL",
"https://git.fabledsword.com/bvandeusen/FabledScribe.git",
)
# OIDC / OAuth2 SSO (e.g. Authentik)
OIDC_ISSUER: str = os.environ.get("OIDC_ISSUER", "")
OIDC_CLIENT_ID: str = os.environ.get("OIDC_CLIENT_ID", "")
+5 -2
View File
@@ -11,6 +11,7 @@ from __future__ import annotations
from quart import Blueprint, g, jsonify, request
from scribe.auth import admin_required, get_current_user_id, login_required
from scribe.config import Config
from scribe.services import plugin_context as plugin_ctx_svc
from scribe.services import repo_bindings as repo_bindings_svc
from scribe.services.settings import get_admin_setting, set_setting
@@ -60,8 +61,10 @@ async def session_context():
@login_required
async def get_marketplace_url():
"""The plugin marketplace git URL, readable by any logged-in user so their
Settings page can show a copyable install command."""
return jsonify({"marketplace_url": await get_admin_setting(_MARKETPLACE_KEY)})
Settings page can show a copyable install command. Falls back to the
config default (this deployment's own repo) when no admin override is set."""
url = await get_admin_setting(_MARKETPLACE_KEY, default=Config.PLUGIN_MARKETPLACE_URL)
return jsonify({"marketplace_url": url})
@plugin_bp.put("/marketplace-url")
+2 -1
View File
@@ -122,7 +122,8 @@ async def _active_projects(user_id: int) -> list[dict]:
out.append({
"id": project.id, "title": project.title, "color": project.color,
"last_activity": (last or project.updated_at).isoformat(),
"open_count": open_count, "progress_pct": progress_pct,
"open_count": open_count, "done_count": done_count,
"progress_pct": progress_pct,
"milestones": milestones,
"no_milestone": [_task_row(t) for t in no_ms],
})