Files
scarf/tools/widget-schema.json
T
Alan Wizemann c7bcfd8655 feat(dashboards): v2.7 widget catalog — file-reading widgets, sparkline, typed status, project-wide watch
Major project-dashboard release. Five new widget types (markdown_file, log_tail,
cron_status, image, status_grid), inline sparkline on stat, typed status enum
shared by list + status_grid, structured WidgetErrorCard, and a project-wide
.scarf/ directory watch that picks up files cron jobs write next to dashboard.json.

- ProjectDashboard: extend DashboardWidget with path/lines/jobId/cells/gridColumns/sparkline; add StatusGridCell + ListItemStatus (lenient parse with synonyms)
- HermesFileWatcher: watch each project's .scarf/ dir alongside dashboard.json (local FSEvents + remote SSH mtime poll); updateProjectWatches signature now takes dashboardPaths + scarfDirs
- New widget views: CronStatus, Image, LogTail, MarkdownFile, StatusGrid, plus WidgetErrorCard for structured failure messaging; legacy "Unknown" placeholder replaced everywhere
- WidgetPathResolver: project-root-anchored path resolution that rejects absolute paths + ".." escapes pre and post canonicalization
- Stat widget gains optional inline sparkline (pure SwiftUI Path, no Charts dep); list widget rows route through typed status with semantic icons + ScarfColor tints
- iOS list widget + unsupported card adopt typed status + warning-toned error card (parity with Mac error styling); new widget types remain Mac-only
- Site mirror: widgets.js renders all five new types (file-reading widgets show annotated catalog placeholders), sparkline SVG, status-grid grid; styles.css adds typed-status palette + error-card + sparkline + grid styles
- Catalog validator: tools/widget-schema.json is the single source of truth; build-catalog.py loads it and enforces per-type required fields. 8 new test cases in test_build_catalog.py covering schema load, v2.7 additions, and missing-required rejection
- Template-author skill (SKILL.md) gains v2.7 Widget Catalog section + canonical status guidance; CONTRIBUTING.md points authors at widget-schema.json; template-author bundle rebuilt
- Localizable.xcstrings picks up auto-extracted strings for the previously-shipped OAuth keepalive feature
- Release notes drafted at releases/v2.7.0/RELEASE_NOTES.md

Backwards compatible — existing dashboard.json renders byte-identically, status synonyms (ok/up/down/active/etc.) keep working.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 21:16:29 +02:00

79 lines
3.4 KiB
JSON

{
"schemaVersion": 1,
"comment": "Canonical project-dashboard widget vocabulary. Single source of truth for the catalog validator (tools/build-catalog.py) and the agent-authoring skill (templates/awizemann/template-author/staging/skills/scarf-template-author/SKILL.md). The Swift renderer (scarf/scarf/Features/Projects/Views/ProjectsView.swift WidgetView) and the JS renderer (site/widgets.js) are hand-written but MUST stay aligned with the type list here. Adding a new widget type: add it here first, then implement the Swift view + JS renderer, then update the SKILL.md Widget Catalog section. Removing or renaming a type breaks every dashboard.json that uses it — don't.",
"widgets": {
"stat": {
"description": "Single big-number metric with optional icon, subtitle, color, and inline sparkline trend.",
"since": "v2.2",
"required": ["title"],
"optional": ["value", "icon", "color", "subtitle", "sparkline"]
},
"progress": {
"description": "0.0..1.0 horizontal progress bar with optional label.",
"since": "v2.2",
"required": ["title", "value"],
"optional": ["label", "color"]
},
"text": {
"description": "Inline text or markdown block. Use 'markdown_file' if the content lives in an external file.",
"since": "v2.2",
"required": ["title", "content"],
"optional": ["format"]
},
"table": {
"description": "Columns x rows of strings.",
"since": "v2.2",
"required": ["title", "columns", "rows"],
"optional": []
},
"chart": {
"description": "Line / bar / area / pie chart over named series.",
"since": "v2.2",
"required": ["title", "series"],
"optional": ["chartType", "xLabel", "yLabel"]
},
"list": {
"description": "Bulleted list with optional typed status badges per item (success / warning / danger / info / pending / done / neutral; unknown values render as plain text).",
"since": "v2.2",
"required": ["title", "items"],
"optional": []
},
"webview": {
"description": "Embedded URL in an iframe / WKWebView. Including a webview also exposes a Site tab in the project view.",
"since": "v2.2",
"required": ["title", "url"],
"optional": ["height"]
},
"markdown_file": {
"description": "Renders a markdown file from disk, relative to the project root. Refreshes when any file under the project's .scarf/ directory changes.",
"since": "v2.7",
"required": ["title", "path"],
"optional": []
},
"log_tail": {
"description": "Tails the last N lines of a file from disk, monospaced. Useful for surfacing the most recent cron-job output. Strips ANSI color codes.",
"since": "v2.7",
"required": ["title", "path"],
"optional": ["lines"]
},
"cron_status": {
"description": "Last run / next run / current state for one Hermes cron job by id, with a tiny inline log tail.",
"since": "v2.7",
"required": ["title", "jobId"],
"optional": ["lines"]
},
"image": {
"description": "Local image file (path relative to project root) or remote URL.",
"since": "v2.7",
"required": ["title"],
"optional": ["path", "url", "height"]
},
"status_grid": {
"description": "Compact grid of colored cells, one per service / item, with hover labels. Reuses the typed status enum.",
"since": "v2.7",
"required": ["title", "cells"],
"optional": ["columns"]
}
}
}