From 9cb2afc787fa91dcdb4ed9eca71d303ab3bf65db Mon Sep 17 00:00:00 2001 From: Alan Wizemann Date: Thu, 23 Apr 2026 15:52:32 +0200 Subject: [PATCH] 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) --- scarf/scarfTests/ProjectTemplateTests.swift | 17 ++++++++++++++++- .../site-status-checker.scarftemplate | Bin 7197 -> 7583 bytes .../site-status-checker/staging/AGENTS.md | 1 + .../staging/cron/jobs.json | 2 +- .../staging/dashboard.json | 16 ++++++++++++++-- templates/catalog.json | 4 ++-- 6 files changed, 34 insertions(+), 6 deletions(-) diff --git a/scarf/scarfTests/ProjectTemplateTests.swift b/scarf/scarfTests/ProjectTemplateTests.swift index 2c871e9..6b14205 100644 --- a/scarf/scarfTests/ProjectTemplateTests.swift +++ b/scarf/scarfTests/ProjectTemplateTests.swift @@ -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 diff --git a/templates/awizemann/site-status-checker/site-status-checker.scarftemplate b/templates/awizemann/site-status-checker/site-status-checker.scarftemplate index 42431a19dab9febb4653b0006ccd12b3117149b3..80da575a7e66c2ecde2b76d8148c66ee98dd86bb 100644 GIT binary patch delta 4699 zcmZvgXEfa1_Qyx>C8B2Zl8G+rDA7AZ^b(zr5#1;; zqW4iENW$Oq{O^mq?!7P0IqR%-_SyT*cdzef=R))4lO^$cxG~b)1UE;WH9-k6wRc#$ z&3u0ewH+Y{6ib1kBxeEexOd<^H!C2R0)$8S0}liuqz8dO@62rtS2gLwHZ5!}(6kW* zdll}_)RgDn%y{ZC{&2M7cShz6IgMIMIOouF{m?pPI!ixYV1aZC!Q%%A?wzds@;zvA zJNQFwPMf}gz{l@?+)l?1+P3xk3y-oE>!gN0`vVX4<}QttDfpy*laYJ z-qF*;TJJ>l8mLTLq>G?m`Rh=}yfyivAJSx)7v!*Hgw9!l6vo#wg@&Yrt-i$^8}ui^ zlHUqI1qi7%c45LF1~5$}ULpbKVojP@CRB>2l!Ad=G^j5-!pu&d-}wdl{YVYLx&!TC zuD)~id6g?YaKL}-nMlKCf}6Q+?pL+u6_*ihC~IhE)|TS$C3Rd?17p5dB(um`srxQ& zJ^P0p&G6h@>6a$~vxLQzYjYD{mv}it7AapHs!tvttvFb$W8w;Z8fu&1)gE^J^`>T0 zlHopyVMBn=#+=9gH{EGwThQ?87pLE@80{$;j&FaJ_pnqUmRkx@>B9R<+GrJslgA9pk-J5yh%##g1TY@DLB zG7YaV-TB4bJxx${7>DiKnHskbf!boXrO`oo3pP?2jOx3}Ix(tX-f}lbx&m{gSu}5s zWvWD2us8IBNf3C2682oRIJ-f>BkC(47$t2Rf=a*_SA&tmI_Q!nJ?if7pP~k@uz0Z~ zV5SXvW)-$ZeLi0(U5Qa>6g=J3vCGIF-!y$!ZojZaAk4y{7{k5XxWGro`4>dRu8U{pl*UeOG z&g1$o;u8BLC4&48mwF_F@j5W7rjg=L1qqA=9_;<5dZ-5w{L^koK|wdI$q2Mo*+&KfB{P6PWFS_Mik60fsfmcE ziWDY@xy)B!0@kqqu$kNIJ)zxhebluOn zv9hJ-Wo0t0S#lZ1COvIm$K@98 zCD6E}pKctZ%WB6bg7@-g-Qiw$%KQhwZWZ88X%z+y)#>0K!96Ep2&&>Ku-9P+_gH!I zH2aqUmSSIbe-mN;_U<&o)jv@*@nmXvecsi;5LSJZ=vm(A^0fETM+nf$n zuD#FN@1g0POQvE`KQqn%cn2;8d2#&2E0ozZeDXLxr#S0dMbVhzk#>q99F9oAs*f33 z)QD)ymNj}lAuCj+|3h!L@mF*XH56Al4dvwUGLl-4BtY$=-Q$!YG^PEYhKgfTL!uaf(lI!!n~##jtCHi(_(LIOm1nhwh=#qoU#%RYII@L zNxPF9R6@=(Pbw|6fXlPbWWLEhc2=l3T3bB&7p|&q;acGqmUkQPOtU+ux!|vxBO4!i zgN_|f{njlgDs2Eo()_6Cz#veL#U8mgD|XVgmm+TFI;KK+$%vE4vZmxrpS7?{eS7QIir<&uzF)@&FsdE$S8TBYeAGIJ#QiVb*N% zwKVp)9by(>M(~SJsc#-B9KnyqL7CYOwYTfdR!*0|#JZ0d3~>cNvYg%(OyLc%A_2@) zbVlR7NYeE`Xno<%&?e3P?Ydd^%Uin|xA9f6+~x7gG$fyM0$*(LDYACgi5&(cEJO(c zBE4d5Tfigr^i}_E1>%YM$d(lI9dkoNtzt=-7R&NUi&8Q2bUXjLh(!hZwcA{4-^a&DXqSVf24#*3A-ulM1wX zJNl|{ozHBAZp+yp%n={&!K?fX?#|0?cswTU&H*At;$DCrCJ>qQRfJK`jeahmhZw?V zNxPlj$k{%LK1~a6{Wg&UXDAkgCC==p zXvT@?T=1Fjqd77hk}@0^r-}7DhhX`Pv$Rp{n!H$kh1b4}@ll`b(Gu~PwPtqVs4wuLk?y!0I{b;^X zYa=Zisjt7`vm@W;&^{^rs!vM2xk@d+7!0k+_11g-NwE2lk}_j>qI13|0^2|?NYf2F z4^LC14O3Oaa z@5DAxDGGWpVn3>#fR)Q@7Q%K*KJ)h`do?+_T|mY1rJLk{&akpc#UYH53>z!C`&5!q zKqXqTo9L4Rdp-)q*b0IRdJvQdKBIq5`LZ7m==-Xp+Novl+P#_m3Boq;y8mHjJ&?Lq z8R{m>(v14Z{BFx?k<_s@=}XZ!U`NY#SsZ z@h12aLP)b{OO{T}YxzziRnVl%saPS0L-NLVhv6@|+;VB0~*^n#jLAGz~H~e2X z8>Z&__sz^Dh3s0@oDPwJz8ZSkh=b4A=A3n`M_K|q-)We0+ziKq63z^mFnQR3;s`%+ z_FY)mkYMS_mJ@LR>~>O&|2frDJhFv7*z3R-q;E=<1(RkCG?#djr?LWAlPZDJ5Qx&A zqn)AF6NtX#IYH6+$)?}FC{KG3q@{WH$-Y69($xp`6tmg1gSA4QtCt-?9G8b$M_izF zrSn9@!dMpx4er-kcC2a0T$^y~Np*aU&D8_N&r^z;iSeD6S z&Zv21o}Yz#d;{@??^Fp?Oxx%B+@PA&LY)(bMl4LMzCOxNn!Od8SKw4X_%*L=ab;W@ z{zR2LyynOEDUj0`<;GQ-V6SKcT%c6MJX2Vi8h7ppzi4fxVOn9Fr z+25HFIprj@@0*z{>00P+^xH7u7SYh*e#-(b4g}e{7%f$M#0!FAX_U{HOKG7MB6u0a90C7&?xP>72R!%tzn*PGY%ud&!*3Lj<(FoFpWi1T;pd z5KN<`HtQ<$3P&FTb%$LA7i_mT$Y3d{nyW(P)?12lds?4`uM-8kJKhRBc(V|m!Gii$ zQL}47&Di14+=1NoT?)E&pTdM0(d1=4LqeQna?39A3emL%6WX5W6=4YZakw~>`y;HDJLY* zB{PWbr=;Baiq!@B7VAGD_^8GuGJ3p&Wa0AQP?07hiQfT2zKM0F;8bdZGk*q=F3d#S zMQpg!Z-iJTEB4$tJu>$!&Y=iwVgQ#`6a-yg0|xNP(23giWu`|i;jOZA+jkMX4fPr# zA#sT*Q$m_JVb^z@+q75}$WcJH5L3l6YtRC2MlsGdsyER zJp>81B|TSLs$27Hh+`rBgVr_@5jT1}DN=H*U#2ssBKlHi!S4*%sJ-G|Lu9l>a$Rp> zy|14OvBkzlK>6O*qP+6mZjX1j-fQE0U0D1@w$wYz#irRIssaE&SF{-0fkz*eU&&-& z3hl z2jt^M*jbU{5^Y#*T_jd9ZargK3`o}f?9q~W-Ho(-@ za9-?hzGYqKL%3r-6{xyzbAWHpJ>;M3k~6x!BuU)+(xVI(oqWb~M)6ZGaG$V8*~E-L z>F|N#X5MP(5`cGbLBp$Q`g)H?R)D|bFO$6G54d-FJz)`pda3V{G`x@SygLtl>o5V6 z=e1H#sX}!|ZzXFD6*c;9iZeBWf)z##UX8la(6G4jt_?O}hoalz zcG;@$-aoQ9k(DxE!`M(PrVe(dc)eWo>6_eRwU$+i6a$XSJ1gUMrtIaNm@h2nlXIgk z4NoqJVp5H!M3wS}RJcWXmNhR@`NY->-G_?mt7QhNzDh@ovJ2@vw#t+bZ|ZJ1Z1ZZJ z4xkm8Ae8I$2xAG+mhY?M|8OO6&OP>|qs zGp5-IuAfOA^_lGZdd<;P;!Kc~ye6Bx9~JJG`wW;ZyU zT#0+UV}DIFedGCO_x#v18A6-v9)H-l(`LlV0drb3bPRv|Vat#bJxQB2ndIcdYE_Mv z!YJTgh~<=1UIoOhN*jqRbZdIsKkjTW<6~B>ls9kg#jvm1Cb%Wg2jpnMtVTYlDe^(F z@HAZ6cgM}%5e^j3o$CJ_#w^`|5Znx7P-I|M@&AS)=6_UhGo1mIL}XEe{vC~o{zfB| z1(;3rZ%O>~?q3@b=>Nk&AX?DA3i{^qk3h^!Z$fT#@pmfD|CZ6er&?o1ErA*EdAU(% MU@l@b`0tPZ59+PC761SM delta 4302 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 diff --git a/templates/awizemann/site-status-checker/staging/AGENTS.md b/templates/awizemann/site-status-checker/staging/AGENTS.md index 693e72f..0e0597f 100644 --- a/templates/awizemann/site-status-checker/staging/AGENTS.md +++ b/templates/awizemann/site-status-checker/staging/AGENTS.md @@ -56,6 +56,7 @@ The cron prompt Scarf registers for this project carries **absolute paths** (the - `Sites Down` stat widget: `value` = count of down results. - `Last Checked` stat widget: `value` = the ISO-8601 timestamp you just wrote. - `Watched Sites` list widget `items`: one entry per URL with `text` = URL and `status` = `"up"` or `"down"` (lowercase). + - `First Watched Site` **webview widget** (in the "Live Site Preview" section): set its `url` field to the **first** URL from `values.sites`. This is what the user sees rendered in the Scarf **Site** tab. If `values.sites` is empty, leave the webview's existing `url` alone. 6. If the cron job has a `deliver` target set, emit a one-line summary (`3 up, 1 down — example.com timed out`) as the agent's final response so the delivery mechanism picks it up. ## What not to do diff --git a/templates/awizemann/site-status-checker/staging/cron/jobs.json b/templates/awizemann/site-status-checker/staging/cron/jobs.json index 9ae3cd2..80c6470 100644 --- a/templates/awizemann/site-status-checker/staging/cron/jobs.json +++ b/templates/awizemann/site-status-checker/staging/cron/jobs.json @@ -2,6 +2,6 @@ { "name": "Check site status", "schedule": "0 9 * * *", - "prompt": "Run the site status check for the Scarf project at {{PROJECT_DIR}}. Read {{PROJECT_DIR}}/.scarf/config.json to get `values.sites` (the URL list) and `values.timeout_seconds` (the per-URL HTTP timeout). HTTP GET each URL with that timeout, following up to 3 redirects; treat 2xx/3xx as up and anything else (including timeouts and DNS failures) as down. Prepend a new timestamped results section to {{PROJECT_DIR}}/status-log.md — create the file with a one-line header if it doesn't exist yet. Update {{PROJECT_DIR}}/.scarf/dashboard.json: set the Sites Up / Sites Down / Last Checked stat widgets' `value` fields, and replace the 'Watched Sites' list widget's `items` array with one entry per URL (text = URL, status = \"up\" or \"down\"). Preserve every other field in dashboard.json as-is. Reply with a one-line summary like '3 up, 1 down — example.com timed out'." + "prompt": "Run the site status check for the Scarf project at {{PROJECT_DIR}}. Read {{PROJECT_DIR}}/.scarf/config.json to get `values.sites` (the URL list) and `values.timeout_seconds` (the per-URL HTTP timeout). HTTP GET each URL with that timeout, following up to 3 redirects; treat 2xx/3xx as up and anything else (including timeouts and DNS failures) as down. Prepend a new timestamped results section to {{PROJECT_DIR}}/status-log.md — create the file with a one-line header if it doesn't exist yet. Update {{PROJECT_DIR}}/.scarf/dashboard.json: set the Sites Up / Sites Down / Last Checked stat widgets' `value` fields; replace the 'Watched Sites' list widget's `items` array with one entry per URL (text = URL, status = \"up\" or \"down\"); and if `values.sites` is non-empty, set the 'First Watched Site' webview widget's `url` field to the FIRST URL from `values.sites` (otherwise leave the webview's existing url alone). Preserve every other field in dashboard.json as-is. Reply with a one-line summary like '3 up, 1 down — example.com timed out'." } ] diff --git a/templates/awizemann/site-status-checker/staging/dashboard.json b/templates/awizemann/site-status-checker/staging/dashboard.json index de2eee0..4670b16 100644 --- a/templates/awizemann/site-status-checker/staging/dashboard.json +++ b/templates/awizemann/site-status-checker/staging/dashboard.json @@ -1,7 +1,7 @@ { "version": 1, "title": "Site Status", - "description": "Daily uptime check for your watched URLs. The stat widgets and the sites list populate after the first cron run; before that, the list mirrors what the agent last wrote.", + "description": "Daily uptime check for your watched URLs. The stat widgets, the sites list, and the Site tab's preview URL all update automatically when the cron job runs. Switch to the Site tab to see your first watched site live.", "theme": { "accent": "green" }, "sections": [ { @@ -47,6 +47,18 @@ } ] }, + { + "title": "Live Site Preview", + "columns": 1, + "widgets": [ + { + "type": "webview", + "title": "First Watched Site", + "url": "https://github.com/awizemann/scarf/tree/main/templates/awizemann/site-status-checker", + "height": 420 + } + ] + }, { "title": "How to Use", "columns": 1, @@ -55,7 +67,7 @@ "type": "text", "title": "Quick Start", "format": "markdown", - "content": "**1.** Review your configuration — click the **slider icon** (top-right of this dashboard) to open Configuration. The sites you enter there are what the cron job will check.\n\n**2.** Enable the `[tmpl:awizemann/site-status-checker] Check site status` cron job in the Cron sidebar. It ships paused — nothing runs until you say so.\n\n**3.** Ask your agent: *\"Run the site status check now.\"* The Watched Sites list populates, the stat widgets update, and a new entry lands at the top of `status-log.md`.\n\n**4.** Daily at 9 AM the cron job fires automatically. Change the schedule in the Cron sidebar if you want a different cadence.\n\nSee `README.md` and `AGENTS.md` in the project root for the full spec." + "content": "**1.** Review your configuration — click the **slider icon** (top-right of this dashboard) to open Configuration. The sites you enter there are what the cron job will check.\n\n**2.** Enable the `[tmpl:awizemann/site-status-checker] Check site status` cron job in the Cron sidebar. It ships paused — nothing runs until you say so.\n\n**3.** Ask your agent: *\"Run the site status check now.\"* The Watched Sites list populates, the stat widgets update, the Site tab's URL switches to your first watched site, and a new entry lands at the top of `status-log.md`.\n\n**4.** Daily at 9 AM the cron job fires automatically. Change the schedule in the Cron sidebar if you want a different cadence.\n\nSwitch to the **Site** tab (next to Dashboard, above) to see your first watched site rendered in a browser. Useful to eyeball a site when the status says up but something still looks off.\n\nSee `README.md` and `AGENTS.md` in the project root for the full spec." } ] } diff --git a/templates/catalog.json b/templates/catalog.json index 7334a81..891aa48 100644 --- a/templates/catalog.json +++ b/templates/catalog.json @@ -7,8 +7,8 @@ "name": "Alan Wizemann", "url": "https://github.com/awizemann/scarf" }, - "bundleSha256": "a3c3a3b1cd1799443fa32ac5f1f643bf28b2e1b30c1b7786a1fa93ef227b0c7e", - "bundleSize": 7197, + "bundleSha256": "2a4e0aba5bd4d86be3153d87c6ce219b9068223daebfad6f9db2b82c3752fac5", + "bundleSize": 7583, "category": "monitoring", "config": { "modelRecommendation": {