feat(admin): rename /admin/welcome to /admin/agent-prompt (Agent Setup Prompt)
Rename the welcome prompt editor from /admin/welcome to /admin/agent-prompt and update all UI labels to "Agent Setup Prompt". API endpoint URLs are unchanged (PUT/GET/DELETE /api/admin/welcome-template, GET /api/welcome). - Nav menu: "Welcome prompt" → "Agent Setup Prompt", href updated - Page title and h2 updated in admin_welcome.html - Error message hint in app/api/welcome.py updated to /admin/agent-prompt - Dashboard: replace inline <details> preview of _claude_setup_instructions with a simple link to /setup (Task C) - docs/welcome-template.md renamed to docs/agent-setup-prompt.md; internal references to /admin/welcome updated - OpenAPI snapshot path updated - Tests updated to reflect new route and removed inline preview
This commit is contained in:
parent
c7b14fb120
commit
ecb6c35ad5
8 changed files with 21 additions and 33 deletions
|
|
@ -81,7 +81,7 @@ async def get_welcome(
|
|||
logger.warning("Welcome render failed: %s", e, exc_info=True)
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail="Welcome template render failed. An admin can fix it at /admin/welcome.",
|
||||
detail="Welcome template render failed. An admin can fix it at /admin/agent-prompt.",
|
||||
)
|
||||
return WelcomeResponse(content=rendered)
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
<a class="app-nav-link {% if _path.startswith('/setup') or _path.startswith('/install') %}is-active{% endif %}" href="/setup">Setup local agent</a>
|
||||
{% if session.user.is_admin %}
|
||||
<a class="app-nav-link {% if _path.startswith('/admin/marketplaces') %}is-active{% endif %}" href="/admin/marketplaces">Marketplaces</a>
|
||||
{% set _admin_active = _path.startswith('/admin/tables') or _path.startswith('/admin/tokens') or _path.startswith('/admin/users') or _path.startswith('/admin/groups') or _path.startswith('/admin/access') or _path.startswith('/admin/server-config') or _path.startswith('/admin/welcome') or _path.startswith('/admin/setup-banner') %}
|
||||
{% set _admin_active = _path.startswith('/admin/tables') or _path.startswith('/admin/tokens') or _path.startswith('/admin/users') or _path.startswith('/admin/groups') or _path.startswith('/admin/access') or _path.startswith('/admin/server-config') or _path.startswith('/admin/agent-prompt') %}
|
||||
<div class="app-nav-menu" id="adminNavMenu">
|
||||
<button type="button"
|
||||
class="app-nav-link app-nav-menu-trigger {% if _admin_active %}is-active{% endif %}"
|
||||
|
|
@ -32,8 +32,7 @@
|
|||
<a class="app-nav-menu-item {% if _path.startswith('/admin/groups') %}is-active{% endif %}" role="menuitem" href="/admin/groups">Groups</a>
|
||||
<a class="app-nav-menu-item {% if _path.startswith('/admin/access') %}is-active{% endif %}" role="menuitem" href="/admin/access">Resource access</a>
|
||||
<a class="app-nav-menu-item {% if _path.startswith('/admin/server-config') %}is-active{% endif %}" role="menuitem" href="/admin/server-config">Server config</a>
|
||||
<a class="app-nav-menu-item {% if _path.startswith('/admin/welcome') %}is-active{% endif %}" role="menuitem" href="/admin/welcome">Welcome prompt</a>
|
||||
<a class="app-nav-menu-item {% if _path.startswith('/admin/setup-banner') %}is-active{% endif %}" role="menuitem" href="/admin/setup-banner">Setup banner</a>
|
||||
<a class="app-nav-menu-item {% if _path.startswith('/admin/agent-prompt') %}is-active{% endif %}" role="menuitem" href="/admin/agent-prompt">Agent Setup Prompt</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}Welcome Prompt — {{ config.INSTANCE_NAME }}{% endblock %}
|
||||
{% block title %}Agent Setup Prompt — {{ config.INSTANCE_NAME }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.css"
|
||||
|
|
@ -202,8 +202,8 @@
|
|||
<div class="welcome-page">
|
||||
<div class="welcome-toolbar">
|
||||
<div>
|
||||
<h2 class="welcome-title">Analyst Welcome Prompt</h2>
|
||||
<p class="welcome-sub">Customise the CLAUDE.md generated for analysts on <code>da analyst setup</code>.</p>
|
||||
<h2 class="welcome-title">Agent Setup Prompt</h2>
|
||||
<p class="welcome-sub">Customise the <code>CLAUDE.md</code> generated for analysts on <code>da analyst setup</code>.</p>
|
||||
</div>
|
||||
<div id="status-chip">
|
||||
{% if is_override %}
|
||||
|
|
|
|||
|
|
@ -2046,20 +2046,7 @@
|
|||
<a href="/setup" class="env-setup-link">Or open the full setup page →</a>
|
||||
</div>
|
||||
<div id="setupClaudeError" class="setup-error" role="alert" style="display:none;"></div>
|
||||
<details class="setup-preview-card" aria-label="Preview of the clipboard payload">
|
||||
<summary class="setup-preview-summary">
|
||||
<span class="setup-preview-chevron" aria-hidden="true">▸</span>
|
||||
<span class="setup-preview-title">What Claude Code will receive</span>
|
||||
</summary>
|
||||
<p class="setup-preview-sub">
|
||||
Read-only preview. The real token is generated the moment
|
||||
you click the button above and is placed directly in your
|
||||
clipboard — never shown on this page.
|
||||
</p>
|
||||
{% with preview_mode=True %}
|
||||
{% include "_claude_setup_instructions.jinja" %}
|
||||
{% endwith %}
|
||||
</details>
|
||||
<a href="/setup" class="env-setup-link" style="display: block; margin-top: 8px;">View what Claude Code will receive on /setup →</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Welcome prompt customization
|
||||
# Agent Setup Prompt
|
||||
|
||||
The welcome prompt is the `CLAUDE.md` file generated in an analyst's local
|
||||
The agent setup prompt is the `CLAUDE.md` file generated in an analyst's local
|
||||
workspace by `da analyst setup`. It instructs Claude Code on how to behave in
|
||||
that workspace — which commands to use, where to read schema metadata, what
|
||||
metrics exist, what plugins are available.
|
||||
|
|
@ -15,7 +15,7 @@ no admin action is required.
|
|||
|
||||
Admins can override the template via:
|
||||
|
||||
- **Admin UI:** `/admin/welcome` — textarea editor with placeholder cheatsheet
|
||||
- **Admin UI:** `/admin/agent-prompt` — textarea editor with placeholder cheatsheet
|
||||
and live preview button. Save sends a `PUT` to `/api/admin/welcome-template`.
|
||||
- **REST API:**
|
||||
- `GET /api/admin/welcome-template` — returns `{content, default, updated_at, updated_by}`. `content` is `null` when no override is set.
|
||||
|
|
@ -32,7 +32,7 @@ audit trail (`updated_at`, `updated_by`) is preserved.
|
|||
[Jinja2](https://jinja.palletsprojects.com/) with `StrictUndefined`. Any
|
||||
typo in a placeholder name raises an error at render time rather than
|
||||
silently emitting an empty string. Server returns HTTP 500 with a hint
|
||||
pointing at `/admin/welcome`; the admin UI rejects syntax errors AND
|
||||
pointing at `/admin/agent-prompt`; the admin UI rejects syntax errors AND
|
||||
undefined-placeholder errors with HTTP 400 on save (validated by rendering
|
||||
the template against a stub context before persisting).
|
||||
|
||||
|
|
@ -3358,9 +3358,9 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"/admin/welcome": {
|
||||
"/admin/agent-prompt": {
|
||||
"get": {
|
||||
"operationId": "admin_welcome_page_admin_welcome_get",
|
||||
"operationId": "admin_agent_prompt_page_admin_agent_prompt_get",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "header",
|
||||
|
|
|
|||
|
|
@ -233,14 +233,16 @@ class TestClaudeSetupPreview:
|
|||
assert "da diagnose" in body
|
||||
assert "da auth whoami" in body
|
||||
|
||||
def test_dashboard_preview_visible(self, web_client, admin_cookie):
|
||||
def test_dashboard_setup_cta_links_to_setup(self, web_client, admin_cookie):
|
||||
"""Dashboard setup CTA shows env-setup-cta and a link to /setup instead
|
||||
of an inline collapsed preview."""
|
||||
resp = web_client.get("/dashboard", cookies=admin_cookie)
|
||||
assert resp.status_code == 200
|
||||
body = resp.text
|
||||
assert "env-setup-cta" in body
|
||||
assert "setup-preview-pre" in body
|
||||
assert "What Claude Code will receive" in body
|
||||
assert "<will be generated on click>" in body
|
||||
assert "View what Claude Code will receive on /setup" in body
|
||||
# inline <details> preview block must no longer appear
|
||||
assert 'aria-label="Preview of the clipboard payload"' not in body
|
||||
|
||||
def test_install_mcp_card_removed(self, web_client):
|
||||
"""The stale 'Use with Claude Code / MCP' card on /setup has been
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ def test_put_rejects_undefined_placeholder(seeded_app):
|
|||
|
||||
def test_get_welcome_500_includes_reset_hint_on_render_failure(seeded_app, monkeypatch):
|
||||
"""If an override slips through validation and fails at render time, the
|
||||
user-visible 500 must point at /admin/welcome rather than leaking a
|
||||
user-visible 500 must point at /admin/agent-prompt rather than leaking a
|
||||
Jinja stack trace."""
|
||||
# Stub render_welcome to raise a TemplateError so we exercise the
|
||||
# exception path without needing a malformed override (PUT validation
|
||||
|
|
@ -123,7 +123,7 @@ def test_get_welcome_500_includes_reset_hint_on_render_failure(seeded_app, monke
|
|||
headers=admin,
|
||||
)
|
||||
assert r.status_code == 500
|
||||
assert "/admin/welcome" in r.json()["detail"]
|
||||
assert "/admin/agent-prompt" in r.json()["detail"]
|
||||
|
||||
|
||||
def test_admin_preview_renders_arbitrary_content(seeded_app):
|
||||
|
|
|
|||
Loading…
Reference in a new issue