feat(site-status-checker): add Live Site Preview webview for Site tab

A Scarf project dashboard that includes at least one webview widget
automatically exposes a Site tab next to the Dashboard tab. Adding a
"Live Site Preview" section with a webview widget gives this template
that tab out of the box.

The cron job + AGENTS.md now tell the agent to rewrite the webview's
`url` field to the first entry in `values.sites` on each run, so the
Site tab renders whatever the user actually configured instead of the
GitHub placeholder. If `values.sites` is empty, the webview URL is
left untouched.

Swift example test updated to assert 4 sections (was 3) plus the new
webview widget's presence + title; bundle + catalog rebuilt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alan Wizemann
2026-04-23 15:52:32 +02:00
parent 69e9cc6c7b
commit 19750597cd
6 changed files with 34 additions and 6 deletions
+16 -1
View File
@@ -1019,7 +1019,9 @@ final class TestRegistryLock: @unchecked Sendable {
let dashboardData = try Data(contentsOf: URL(fileURLWithPath: dashboardPath))
let dashboard = try JSONDecoder().decode(ProjectDashboard.self, from: dashboardData)
#expect(dashboard.title == "Site Status")
#expect(dashboard.sections.count == 3)
// Four sections: Current Status (stats), Watched Sites (list),
// Live Site Preview (webview drives the Site tab), How to Use (text).
#expect(dashboard.sections.count == 4)
// First section should have three stat widgets that the cron job
// updates by value. Assert titles + types so the AGENTS.md contract
@@ -1031,6 +1033,19 @@ final class TestRegistryLock: @unchecked Sendable {
#expect(statTitles.contains("Sites Down"))
#expect(statTitles.contains("Last Checked"))
// Live Site Preview section must contain exactly one webview
// widget. The presence of any webview widget is what makes Scarf
// expose the Site tab next to Dashboard, so losing this section
// would silently drop a user-visible feature. The cron job
// rewrites this widget's `url` to the first configured site on
// every run AGENTS.md documents the contract.
let previewSection = dashboard.sections[2]
#expect(previewSection.title == "Live Site Preview")
let webviews = previewSection.widgets.filter { $0.type == "webview" }
#expect(webviews.count == 1)
#expect(webviews.first?.title == "First Watched Site")
#expect((webviews.first?.url ?? "").isEmpty == false)
// Cron prompt references .scarf/config.json (where values.sites
// + values.timeout_seconds live), the dashboard/log it writes,
// and the {{PROJECT_DIR}} placeholder the installer resolves