diff --git a/.agents/skills/grow-quicksheet/cron-runs.log b/.agents/skills/grow-quicksheet/cron-runs.log
index 45debcd7..354d97d9 100644
--- a/.agents/skills/grow-quicksheet/cron-runs.log
+++ b/.agents/skills/grow-quicksheet/cron-runs.log
@@ -897,3 +897,35 @@ Tokens ↑ 5.0m (4.9m cached) • ↓ 13.7k
2026-05-24T13:05:36-07:00 — Run complete
---
2026-05-24T14:00:00-07:00 — Starting grow-quicksheet run
+2026-05-25T20:05:59-07:00 — Run complete
+---
+2026-05-25T21:00:00-07:00 — Starting grow-quicksheet run
+2026-05-27T01:05:09-07:00 — Run complete
+---
+2026-05-27T02:00:00-07:00 — Starting grow-quicksheet run
+2026-05-27T18:05:46-07:00 — Run complete
+---
+2026-05-27T19:00:00-07:00 — Starting grow-quicksheet run
+● Push log via PR (shell)
+ │ cd /home/akif/Projects/QuickSheet && git checkout -b grow/log-pubmed && git
+ │ push origin grow/log-pubmed 2>&1 | tail -3 && gh pr create --title "chore:
+ │ update grow log — quicksheet-pubmed run 2026-05-27 19:00" --body "Internal
+ │ bookkeeping — logs the pubmed extension run." --head grow/log-pubmed --base
+ │ main 2>&1
+ └ 9 lines...
+
+Done. Let me clean up and report:
+
+● Cleanup (shell)
+ │ cd /home/akif/Projects/QuickSheet && git checkout main 2>&1 | head -2 && rm
+ │ -rf /tmp/quicksheet-pubmed
+ └ 3 lines...
+
+
+
+Changes +308 -0
+AI Credits 169 (5m 37s)
+Tokens ↑ 2.0m (1.9m cached) • ↓ 12.3k
+2026-05-27T19:05:40-07:00 — Run complete
+---
+2026-05-28T19:00:00-07:00 — Starting grow-quicksheet run
diff --git a/.agents/skills/grow-quicksheet/log.md b/.agents/skills/grow-quicksheet/log.md
index 8997e81b..124c25e5 100644
--- a/.agents/skills/grow-quicksheet/log.md
+++ b/.agents/skills/grow-quicksheet/log.md
@@ -1700,9 +1700,323 @@ Persistent memory across runs. Append-only (except the Queued section at bottom)
- Competitor last did: v0.35.0 + Ctrl+K row duplication (previous run May 24 13:00).
- Follow-up: Bucket F — quicksheet-nuget (NuGet package lookup) or quicksheet-pypi2. Bucket D — v0.37.0 release after PR #181 merge.
+## 2026-05-25 21:00
+
+- Stars: 0 (gh API still returning 0, likely 1 actual)
+- Action: Bucket C — created /for-homelab/ landing page on gh-pages. SEO-optimized for homelab/selfhosted community (r/homelab, r/selfhosted audiences). 9 monitoring cards (Docker, Plex/Jellyfin, Pi-hole, disk, sysmon, network, *arr stack, Home Assistant, Proxmox). Example CSV layout. 3-min getting started. 6 value props. Keywords: homelab dashboard terminal, self-hosted monitoring desktop, plex status wallpaper, pihole stats terminal, docker monitoring wallpaper. Updated sitemap + homepage nav.
+- Bucket: C
+- Outcome: Pushed to gh-pages (commit 91c4227). Page live at https://cemheren.github.io/QuickSheet/for-homelab/
+- Competitor last did: Alternatives page on gh-pages (2026-05-25 20:00), quicksheet-ollama extension, quicksheet-git extension.
+- Follow-up: Bucket C — add /for-traders/ page next (finance vertical, another engaged community). Bucket D — v0.37.0 release when PRs merge.
+
## Queued
-- Bucket D: v0.37.0 release after PR #181 (maven docs) merge
-- Bucket F: quicksheet-nuget (NuGet package lookup for C#/.NET devs) — natural follow-on
+- Bucket C: /for-traders/ page (finance vertical — P/L, watchlist, FX, crypto)
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket F: quicksheet-nuget (NuGet package lookup for C#/.NET devs)
- Bucket E: safe additive feature (row height / column formatting)
+
+## 2026-05-26 18:00
+
+- Stars: 0 (gh API returning 0, likely 1 actual)
+- Action: Bucket E — added selection aggregate stats to status bar. When multiple cells are selected, shows Count, Sum (Σ), and Average in the status bar (like Excel/Google Sheets bottom-right). Works on both Linux (X11) and Windows (WinForms).
+- Bucket: E
+- Outcome: PR #189 opened (commit d2d4367 on grow/selection-stats). Build green.
+- Competitor last did: Saturated, doing no-ops. Last substantive: quicksheet-ollama extension + quicksheet-git extension (May 25).
+- Follow-up: Bucket C — /for-traders/ page for finance vertical SEO. Bucket D — v0.37.0 release after PRs merge.
+
+## 2026-05-26 19:00
+
+- Stars: 0 (gh API returning 0, likely 1 actual)
+- Action: Bucket C — created /for-traders/ landing page on gh-pages. SEO-optimized for finance/trading community. 6 extension cards (stocks, crypto, FX, sparklines, web fetch, world clock). Example watchlist CSV table. Comparison vs Bloomberg/Ticker/browser tabs. 6 value props. 3-min getting started. Keywords: stock ticker terminal, crypto price terminal, portfolio tracker terminal, trading dashboard desktop, bloomberg alternative free. Updated sitemap + homepage nav.
+- Bucket: C
+- Outcome: Pushed to gh-pages (commit d87e173). Page live at https://cemheren.github.io/QuickSheet/for-traders/
+- Competitor last did: No-ops (saturated). Last substantive: quicksheet-ollama + quicksheet-git extensions (May 25).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket E — cell timestamp hotkey. Bucket C — /for-gamemasters/ page (TTRPG niche).
+
+## 2026-05-26 21:00
+
+- Stars: 0 (gh API returning 0, likely 1 actual)
+- Action: Bucket C — created /for-developers/ landing page on gh-pages. SEO-optimized for software engineers (the core GitHub-starring audience). 12 extension cards (GitHub PRs, Actions, git log, JWT, base64, cron, urlenc, Docker, npm, ghstreak, regex, sysmon). Example dev-dashboard CSV layout. Comparison table vs GitHub/Waybar/Notion. 6 value props. 4-step getting started. Keywords: developer dashboard terminal, github status wallpaper, ci cd dashboard terminal, dev tools desktop wallpaper. Updated sitemap + homepage nav.
+- Bucket: C
+- Outcome: Pushed to gh-pages (commit 3e2a71a). Page live at https://cemheren.github.io/QuickSheet/for-developers/
+- Competitor last did: No-ops (saturated). Last substantive: for-gamemasters page, quicksheet-ollama/git extensions (May 25-26).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket E — cell timestamp hotkey.
+
+## Queued
+
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket E: cell timestamp hotkey (Ctrl+;) or freeze header row
+- Bucket C: /for-writers/ page (writers/bloggers vertical — word count, markdown export, notes)
+
+## 2026-05-26 23:00
+
+- Stars: 0 (gh API returning 0, likely 1 actual)
+- Action: Bucket C — created /for-writers/ landing page on gh-pages. SEO-optimized for writers, bloggers, and content creators. 9 capability cards (scratchpad, word count, deadlines, research links, markdown export, search, pomodoro, RSS, undo). Example writer's desktop CSV layout. Comparison table vs Sticky Notes/Notion/Obsidian. 6 writing workflow cards (NaNoWriMo tracker, content calendar, chapter outline, freelance tracker, brainstorm board, reading log). 6 value props (always visible, zero distraction, auto-save, plain CSV, cross-platform, themes). Keywords: writing tool desktop wallpaper, distraction free writing, NaNoWriMo tracker desktop, content calendar wallpaper, writer scratchpad. Updated sitemap + homepage nav.
+- Bucket: C
+- Outcome: Pushed to gh-pages (commit f129f21). Page live at https://cemheren.github.io/QuickSheet/for-writers/
+- Competitor last did: Ctrl+; timestamp hotkey (PR #194, Bucket E, 2026-05-26 22:00).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket E — safe additive feature. Bucket F — new extension.
+
+## Queued
+
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket E: safe additive feature (freeze header row, row height)
+- Bucket C: /for-musicians/ or /for-researchers/ page (academic/music niche)
+- Bucket F: quicksheet-words (word count, reading time, character count extension for writers)
+
+## 2026-05-27 00:00
+
+- Stars: 0 (gh API returning 0, likely 1 actual)
+- Action: Bucket F — created quicksheet-sysmon extension (live system monitoring). Reads /proc/stat, /proc/meminfo, /proc/net/dev, /proc/loadavg, /proc/uptime on Linux. 8 subcommands: summary, cpu (per-core bars), ram (breakdown + swap), disk (DriveInfo), net (interface I/O), load, uptime, procs (top 10 by memory). Windows basic support via .NET APIs. Zero NuGet deps. Build green, smoke-tested all commands live. Topics: quicksheet, system-monitor, terminal, htop.
+- Bucket: F
+- Outcome: Repo live at https://github.com/cemheren/quicksheet-sysmon (commit 32751dd). PR #197 on main for README docs.
+- Competitor last did: No-ops (saturated). Last substantive: timestamp hotkey PR #194 (May 26).
+- Follow-up: Bucket C — add sys: to gh-pages extensions page + /for-homelab/ page. Bucket D — v0.37.0 release when PRs merge.
+
+## Queued
+
+- Bucket C: add quicksheet-sysmon to gh-pages extensions page + /for-homelab/ cards
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket E: safe additive feature (freeze header row)
+- Bucket F: quicksheet-nuget (NuGet package lookup for C#/.NET devs)
+
+## 2026-05-27 01:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket E — added `--export-sql` headless export. Converts CSV to SQL CREATE TABLE + INSERT statements. Numeric values unquoted, empty cells as NULL, identifiers safely double-quoted, strings escaped. Supports stdout via `-` for Unix piping. Table name from filename.
+- Bucket: E
+- Outcome: PR #199 opened (commit 1791ca3 on grow/export-sql). Build green.
+- Competitor last did: No-ops (saturated). Last substantive: timestamp hotkey PR #194 (May 26).
+- Follow-up: Bucket C — update gh-pages /features/ page with export-sql. Bucket D — v0.37.0 release when PRs merge.
+
+## Queued
+
+- Bucket C: update gh-pages features page with --export-sql
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket E: safe additive feature (freeze header row, cell comments)
+- Bucket F: quicksheet-nuget (NuGet package lookup for .NET devs)
+
+## 2026-05-27 02:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket C — updated gh-pages site with --export-sql feature. Added SQL export to features page export list, homepage "CSV Everywhere" card, comparison table (now "Multi-format export: MD, HTML, JSON, SQL"), and SEO keywords ("export sql csv, csv to sql cli"). Updated sitemap dates.
+- Bucket: C
+- Outcome: Pushed to gh-pages (commit 15a9243). Site rebuilding at cemheren.github.io/QuickSheet/.
+- Competitor last did: No-ops (saturated). Last substantive: quicksheet-sysmon extension + timestamp hotkey (May 26-27).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket E — safe additive feature (freeze header row).
+
+## Queued
+
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket E: safe additive feature (freeze header row, cell comments)
+- Bucket C: /for-homelab/ or /for-researchers/ page (niche SEO)
+- Bucket F: quicksheet-nuget (NuGet package lookup for .NET devs)
+
+## 2026-05-27 03:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket C — created /for-homelab/ landing page on gh-pages. SEO-optimized for homelab/self-hosted community. 6 monitoring extension cards (sysmon, Docker, network, inline commands, uptime checker, SMART). Example homelab dashboard CSV layout. Comparison table vs Grafana+Prometheus/htop/Conky. 6 value props (zero setup, always visible, minimal resources, offline & self-hosted, extensible via shell, CSV config). 6 homelab recipes (NAS health, Pi-hole stats, Docker fleet, media server, VPN, UPS battery). Updated sitemap + homepage nav.
+- Bucket: C
+- Outcome: Pushed to gh-pages (commit d0fdccf). Page live at https://cemheren.github.io/QuickSheet/for-homelab/
+- Competitor last did: No-ops (saturated). Last substantive: quicksheet-sysmon extension + timestamp hotkey (May 26-27).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket E — safe additive feature. Bucket C — /for-students/ or /for-sysadmins/ page.
+
+## Queued
+
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket E: safe additive feature (freeze header row, cell comments)
+- Bucket C: /for-students/ page (academic/productivity niche) or /for-sysadmins/ (enterprise IT)
+- Bucket F: quicksheet-nuget (NuGet package lookup for .NET devs)
+
+## 2026-05-27 04:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket F — created quicksheet-words extension (text analysis for writers). Word count, character count, reading time (238 wpm), Flesch-Kincaid readability grade, sentence/paragraph count, longest sentence finder, word frequency. Zero NuGet deps. .NET 9. Build green, smoke-tested all 9 subcommands.
+- Bucket: F
+- Outcome: Repo live at https://github.com/cemheren/quicksheet-words (commit pushed). PR #201 on main for docs/extensions.md update.
+- Competitor last did: No-ops (saturated). Last substantive: for-homelab page (May 27 03:00).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket C — add words: to gh-pages /for-writers/ page.
+
+## Queued
+
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket C: add quicksheet-words to gh-pages /for-writers/ page
+- Bucket E: safe additive feature (freeze header row, cell comments)
+- Bucket C: /for-students/ page (academic/productivity niche)
+
+## 2026-05-27 05:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket C — created /for-ai-engineers/ landing page on gh-pages. SEO-optimized for AI engineers — LLM cost tracking (Anthropic, OpenAI, DeepSeek), agent run monitoring (Claude Code, DeepSeek-TUI), model comparison grid, prompt A/B testing, cost alert watchdog, fine-tuning job monitor. Comparison table vs LangSmith/Helicone/Grafana/browser tabs. 6 workflow recipes. Targets hottest niche (AI agents/coding tools trending #1 on HN/GitHub May 2026). Updated sitemap + homepage nav.
+- Bucket: C
+- Outcome: Pushed to gh-pages (commit 9170e7c). Page live at https://cemheren.github.io/QuickSheet/for-ai-engineers/
+- Competitor last did: No-ops (saturated). Last substantive: for-homelab page (May 27 03:00).
+- Follow-up: Bucket F — quicksheet-ai-costs extension (token cost tracker). Bucket D — v0.37.0 release when PRs merge. Bucket E — safe additive feature.
+
+## 2026-05-27 06:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket F — created quicksheet-ai-costs extension (AI API cost tracker). Live OpenAI usage via /v1/usage, built-in pricing for 15 models (GPT-4o, Claude, Gemini, DeepSeek), cost calculator with token shorthand (10k/1M), monthly budget tracker with progress bar, provider comparison table, local CSV spend log. 9 subcommands. Zero NuGet deps. Build green, smoke-tested models/calc/compare commands.
+- Bucket: F
+- Outcome: Repo live at https://github.com/cemheren/quicksheet-ai-costs (commit 1715d15). PR #204 on main for docs/extensions.md update.
+- Competitor last did: No-ops (saturated). Last substantive: for-ai-engineers page (May 27 05:00).
+- Follow-up: Bucket C — update gh-pages /for-ai-engineers/ page with quicksheet-ai-costs link. Bucket D — v0.37.0 release when PRs merge.
+
+## 2026-05-27 07:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket E — added cell bookmarks feature. Ctrl+Shift+1-5 sets a bookmark at the current cell, Ctrl+1-5 jumps to it. 5 persistent slots stored via hidden config cell (same pattern as theme). Both Linux and Windows desktop modes supported. Help overlay updated.
+- Bucket: E
+- Outcome: PR #206 opened (commit bfb02fc on grow/cell-bookmarks). Build green. Purely additive — no existing behavior modified.
+- Competitor last did: No-ops (saturated). Last substantive: quicksheet-ai-costs extension (May 27 06:00).
+- Follow-up: Bucket C — update gh-pages /for-ai-engineers/ page with ai-costs link. Bucket D — v0.37.0 release when PRs merge.
+
+## Queued
+
+- Bucket C: update gh-pages /for-ai-engineers/ page with ai: extension link + install command
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket A: document bookmarks in docs/tour.md keyboard shortcuts section
+- Bucket C: /for-students/ page (academic/productivity niche)
+
+## 2026-05-27 08:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket C — updated gh-pages /for-ai-engineers/ page with quicksheet-ai-costs extension. Added new card to extensions grid + dedicated section with 4 feature cards (live usage polling, token calculator, provider comparison, monthly budget tracker) and install command. Backlinks to extension repo for search discoverability.
+- Bucket: C
+- Outcome: Pushed to gh-pages (commit 0d37ada). Page live at https://cemheren.github.io/QuickSheet/for-ai-engineers/
+- Competitor last did: No-ops (saturated). Last substantive: cell bookmarks feature (May 27 07:00).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket A — document bookmarks in docs/tour.md. Bucket C — /for-students/ page.
+
+## 2026-05-27 09:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket E — added progress bar cell prefix (`p: 75`, `p: 3/10 tasks`). Renders unicode block bar [████░░░░] with percentage. Supports plain percent, fractions, and optional trailing label. Green-tinted colors on both Linux X11 and Windows renderers. Help overlay and docs updated.
+- Bucket: E
+- Outcome: PR #208 opened (commit 02b7944 on grow/progress-bar-prefix). Build green. Purely additive — no existing behavior modified.
+- Competitor last did: No-ops (saturated). Last substantive: /for-ai-engineers/ ai-costs update (May 27 08:00).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket C — /for-students/ page.
+
+## Queued
+
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket A: document bookmarks in docs/tour.md keyboard shortcuts section
+- Bucket C: /for-students/ page (academic/productivity niche)
+- Bucket F: quicksheet-nuget (NuGet package lookup for .NET devs)
+
+## 2026-05-27 10:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket C — created /for-researchers/ landing page on gh-pages. SEO-optimized for academic researchers: paper deadline tracking, experiment logging, citation monitoring, grant milestones, GPU cluster status (SLURM). Comparison table vs Notion/Google Sheets/terminal. 6 workflow recipes (deadline countdown, hyperparameter grid, citation monitor, GPU cluster, reading list, grant budget). 4 extension cards (arxiv, words, sysmon, ai-costs). Updated sitemap + homepage nav.
+- Bucket: C
+- Outcome: Pushed to gh-pages (commit 0e93c04). Page live at https://cemheren.github.io/QuickSheet/for-researchers/
+- Competitor last did: No-ops (saturated). Last substantive: progress bar prefix PR #208 (May 27 09:00).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket E — safe additive feature (freeze header row). Bucket C — /for-freelancers/ page.
+
+## 2026-05-27 11:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket F — published quicksheet-health-ext as live repo under cemheren/. HTTP service health grid for homelab dashboards (Plex, Pi-hole, Nextcloud, *arr-stack). Supports inline name=url specs or services.csv file. HEAD-first probing, GET fallback, 8s timeout, latency display. Build verified green. Updated README link via PR #210.
+- Bucket: F
+- Outcome: Repo live at https://github.com/cemheren/quicksheet-health-ext. PR #210 for README link update.
+- Competitor last did: No-ops (saturated). Last substantive: /for-researchers/ page (May 27 10:00).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket F — roll/dice extension next.
+
+## Queued
+
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket F: quicksheet-roll-ext (dice roller for TTRPG GMs)
+- Bucket E: safe additive feature (freeze header row, cell comments)
+- Bucket C: /for-freelancers/ page (time tracking, invoicing niche)
+
+## 2026-05-27 12:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket C — created /for-freelancers/ landing page on gh-pages. SEO-optimized for freelancers: billable hours tracking, project deadline countdown, invoice reminder pipeline, client retainer dashboards, rate calculators, expense logging. Comparison table vs Toggl/Harvest/Notion/Google Sheets. 6 workflow recipes. Targets keywords: freelance dashboard desktop, time tracking wallpaper, freelancer productivity tool, billable hours desktop. Updated sitemap + homepage nav.
+- Bucket: C
+- Outcome: Pushed to gh-pages (commit 34de4c6). Page live at https://cemheren.github.io/QuickSheet/for-freelancers/
+- Competitor last did: No-ops (saturated). Last substantive: quicksheet-health-ext (May 27 11:00).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket F — quicksheet-roll-ext (dice roller). Bucket E — freeze header row.
+
+## Queued
+
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket F: quicksheet-roll-ext (dice roller for TTRPG GMs)
+- Bucket E: safe additive feature (freeze header row, cell comments)
+- Bucket C: /for-musicians/ or /for-content-creators/ page
+
+## 2026-05-27 13:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket F — created quicksheet-unitconv extension (universal unit converter). 9 categories: length, weight, temperature, data (SI+binary), speed, time, volume, area, pressure. Flexible syntax (100 km to mi, 32 f c, 1024 mb gb). Offline, no API. Build verified green, smoke-tested all categories.
+- Bucket: F
+- Outcome: Repo live at https://github.com/cemheren/quicksheet-unitconv (commit on master). PR #213 on main for docs/extensions.md update.
+- Competitor last did: No-ops (saturated). Last substantive: /for-freelancers/ page (May 27 12:00).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket E — safe additive feature (freeze header row). Bucket C — /for-musicians/ page.
+
+## Queued
+
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket E: safe additive feature (freeze header row, cell comments)
+- Bucket C: /for-musicians/ or /for-content-creators/ page
+- Bucket F: quicksheet-hashgen (hash generator: md5, sha1, sha256, crc32)
+
+## 2026-05-27 15:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket F — published quicksheet-hashgen extension (hash/checksum generator). 5 algorithms (MD5, SHA1, SHA256, SHA512, CRC32), hashes raw text or file contents. Build verified green, smoke-tested all algorithms. Added to docs/extensions.md via PR #217.
+- Bucket: F
+- Outcome: Repo live at https://github.com/cemheren/quicksheet-hashgen (commit a779122). PR #217 for docs update.
+- Competitor last did: Bucket E — zebra striping (PR #215, May 27 14:00).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket C — /for-content-creators/ page. Bucket E — freeze header row.
+
+## 2026-05-27 17:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket E — added countdown/date cell prefix (`d: YYYY-MM-DD label`). Renders days remaining (⏳ 5d Release), today marker (★ TODAY), or days elapsed (✓ 3d ago). Amber-tinted colors on both Linux X11 and Windows renderers. Help overlay and docs/tour.md updated.
+- Bucket: E
+- Outcome: PR #220 opened (commit 0eeac41 on grow/countdown-prefix). Build green. Purely additive — no existing behavior modified.
+- Competitor last did: Bucket C — /for-content-creators/ page (May 27 16:00).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket C — /for-musicians/ page.
+
+## 2026-05-27 18:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket C — created /for-musicians/ niche landing page on gh-pages. Targets setlist management, practice tracking, BPM reference, gig countdown, DAW quick-launch workflows. Includes comparison table (vs Google Sheets, Notion, paper), sample CSV layout, 6 feature cards, 5-step workflow. Added to homepage nav and sitemap.xml. Keywords: setlist manager desktop, practice tracker wallpaper, BPM tracker terminal, musician productivity tool.
+- Bucket: C
+- Outcome: Pushed to gh-pages (commit 0b183e4). Page live at https://cemheren.github.io/QuickSheet/for-musicians/
+- Competitor last did: no-ops since May 19 (PR #139 still open).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket F — quicksheet-base64.
+
+## Queued
+
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket F: quicksheet-base64 (base64 encode/decode)
+- Bucket A: document countdown prefix in keyboard-shortcuts.md
+- Bucket C: /for-gamers/ page (distinct from gamemasters — video game devs/modders)
+
+## 2026-05-27 19:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket F — published quicksheet-pubmed extension (PubMed article lookup). Lookup by PMID returns title, authors, journal, year, DOI, abstract snippet. Search mode returns top 5 results. Uses free NCBI E-utilities API, 30-min cache, zero NuGet. Build green, smoke-tested both modes.
+- Bucket: F
+- Outcome: Repo live at https://github.com/cemheren/quicksheet-pubmed (commit 7efc374). PR #223 for docs/extensions.md update.
+- Competitor last did: No-ops since May 19 (PR #139 still open).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket A — document countdown prefix. Bucket C — /for-gamers/ page.
+
+## 2026-05-28 19:00
+
+- Stars: 0 (Δ +0)
+- Action: Bucket C — created /for-gamers/ niche landing page on gh-pages. Targets loot table tracking, quest logs, keybind references, mod load orders, speedrun splits, game backlog management. Includes comparison table (vs Notepad, game overlays, second monitor), sample RPG companion CSV layout, 6 feature cards, pro tips section (Steam launchers, wiki links, themes). Added to homepage nav and sitemap.xml. Keywords: game notes desktop wallpaper, loot table tracker, quest tracker desktop, keybind reference wallpaper, mod list manager desktop, speedrun splits desktop.
+- Bucket: C
+- Outcome: Pushed to gh-pages (commit 87af039). Page live at https://cemheren.github.io/QuickSheet/for-gamers/
+- Competitor last did: no-ops since May 19 (PR #139 still open).
+- Follow-up: Bucket D — v0.37.0 release when PRs merge. Bucket A — document countdown prefix.
+
+## Queued
+
+- Bucket D: v0.37.0 release after pending PRs merge
+- Bucket A: document countdown prefix in keyboard-shortcuts.md
+- Bucket F: quicksheet-pubmed-batch (batch PMID lookup for systematic reviews)
+- Bucket C: /for-speedrunners/ subpage (deeper niche within gaming)
diff --git a/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/.gitignore b/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/.gitignore
new file mode 100644
index 00000000..cd42ee34
--- /dev/null
+++ b/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/.gitignore
@@ -0,0 +1,2 @@
+bin/
+obj/
diff --git a/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/ArxivExtension.csproj b/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/ArxivExtension.csproj
new file mode 100644
index 00000000..fba60300
--- /dev/null
+++ b/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/ArxivExtension.csproj
@@ -0,0 +1,10 @@
+
+
+ Exe
+ net9.0
+ enable
+ enable
+ QuickSheetArxiv
+ ArxivExtension
+
+
diff --git a/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/LICENSE b/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/LICENSE
new file mode 100644
index 00000000..dbaa22be
--- /dev/null
+++ b/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 cemheren
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/Program.cs b/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/Program.cs
new file mode 100644
index 00000000..534a97a2
--- /dev/null
+++ b/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/Program.cs
@@ -0,0 +1,195 @@
+using System.Collections.Concurrent;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using System.Text.RegularExpressions;
+using System.Xml.Linq;
+
+///
+/// QuickSheet arXiv Extension — looks up papers by arXiv ID.
+/// Usage: `arxiv: 2301.07041` or `arxiv: 2301.07041v2`
+/// Returns: title, authors (up to 4), first ~120 chars of abstract, link.
+/// Free API, no auth, no NuGet deps.
+///
+class Program
+{
+ private static readonly JsonSerializerOptions JsonOpts = new()
+ {
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
+ WriteIndented = false
+ };
+
+ private static readonly HttpClient Http = new() { Timeout = TimeSpan.FromSeconds(10) };
+
+ static Program()
+ {
+ Http.DefaultRequestHeaders.UserAgent.ParseAdd(
+ "quicksheet-arxiv-ext/1.0 (https://github.com/cemheren/quicksheet-arxiv-ext)");
+ }
+
+ private static readonly ConcurrentDictionary> Cache = new(StringComparer.OrdinalIgnoreCase);
+
+ static void Main()
+ {
+ Console.OutputEncoding = System.Text.Encoding.UTF8;
+ string? line;
+ while ((line = Console.ReadLine()) != null)
+ {
+ if (string.IsNullOrWhiteSpace(line)) continue;
+ try
+ {
+ using var doc = JsonDocument.Parse(line);
+ string? type = doc.RootElement.TryGetProperty("type", out var tp) ? tp.GetString() : null;
+ switch (type)
+ {
+ case "init": HandleInit(); break;
+ case "activate": HandleActivate(doc.RootElement); break;
+ }
+ }
+ catch (Exception ex)
+ {
+ SendLog($"parse error: {ex.Message}");
+ }
+ }
+ }
+
+ static void HandleInit()
+ {
+ SendJson(new
+ {
+ type = "register",
+ prefix = "arxiv",
+ name = "arXiv Lookup",
+ version = "1.0.0"
+ });
+ SendLog("arXiv extension registered with prefix 'arxiv'");
+ }
+
+ static void HandleActivate(JsonElement root)
+ {
+ string id = root.TryGetProperty("id", out var idProp) ? idProp.GetString() ?? "" : "";
+ int gridRows = root.TryGetProperty("gridRows", out var gr) ? gr.GetInt32() : 4;
+
+ string[] extParams = [];
+ if (root.TryGetProperty("params", out var p) && p.ValueKind == JsonValueKind.Array)
+ extParams = p.EnumerateArray().Select(x => x.GetString() ?? "").ToArray();
+
+ if (extParams.Length == 0 || string.IsNullOrWhiteSpace(extParams[0]))
+ {
+ WriteCells(id, new[] { new[] { "arxiv: (e.g. 2301.07041)" } });
+ return;
+ }
+
+ string arxivId = NormalizeId(extParams[0]);
+ if (string.IsNullOrEmpty(arxivId))
+ {
+ WriteCells(id, new[] { new[] { "err: invalid arXiv ID" } });
+ return;
+ }
+
+ try
+ {
+ var lines = FetchPaper(arxivId);
+ if (lines.Count == 0)
+ {
+ WriteCells(id, new[] { new[] { $"{arxivId}: not found" } });
+ return;
+ }
+ var rows = lines.Select(l => new[] { l }).ToList();
+ while (rows.Count < gridRows) rows.Add(new[] { "" });
+ if (rows.Count > gridRows) rows = rows.Take(gridRows).ToList();
+ WriteCells(id, rows);
+ }
+ catch (Exception ex)
+ {
+ WriteCells(id, new[] { new[] { $"err: {ex.Message}" } });
+ }
+ }
+
+ static string NormalizeId(string s)
+ {
+ s = s.Trim();
+ // Strip common URL prefixes
+ if (s.StartsWith("https://arxiv.org/abs/", StringComparison.OrdinalIgnoreCase))
+ s = s[22..];
+ else if (s.StartsWith("http://arxiv.org/abs/", StringComparison.OrdinalIgnoreCase))
+ s = s[21..];
+ else if (s.StartsWith("arxiv:", StringComparison.OrdinalIgnoreCase))
+ s = s[6..];
+ s = s.Trim();
+ // Validate: new-style (YYMM.NNNNN[vN]) or old-style (category/YYMMNNN)
+ if (Regex.IsMatch(s, @"^\d{4}\.\d{4,5}(v\d+)?$")) return s;
+ if (Regex.IsMatch(s, @"^[a-z\-]+/\d{7}(v\d+)?$")) return s;
+ return "";
+ }
+
+ static List FetchPaper(string arxivId)
+ {
+ if (Cache.TryGetValue(arxivId, out var cached)) return cached;
+
+ string url = $"https://export.arxiv.org/api/query?id_list={Uri.EscapeDataString(arxivId)}";
+ var resp = Http.GetAsync(url).GetAwaiter().GetResult();
+ if (!resp.IsSuccessStatusCode) { Cache[arxivId] = []; return []; }
+ string xml = resp.Content.ReadAsStringAsync().GetAwaiter().GetResult();
+
+ var lines = new List();
+ XNamespace atom = "http://www.w3.org/2005/Atom";
+ var feed = XDocument.Parse(xml);
+ var entry = feed.Root?.Element(atom + "entry");
+ if (entry == null) { Cache[arxivId] = lines; return lines; }
+
+ // Check for error (arXiv returns an entry with id containing "api/errors")
+ string? entryId = entry.Element(atom + "id")?.Value;
+ if (entryId != null && entryId.Contains("api/errors"))
+ {
+ Cache[arxivId] = lines;
+ return lines;
+ }
+
+ // Title
+ string title = entry.Element(atom + "title")?.Value?.Trim() ?? "";
+ title = Regex.Replace(title, @"\s+", " ");
+ if (!string.IsNullOrEmpty(title))
+ lines.Add(title.Length > 100 ? title[..97] + "..." : title);
+
+ // Authors (up to 4)
+ var authors = entry.Elements(atom + "author")
+ .Select(a => a.Element(atom + "name")?.Value ?? "")
+ .Where(n => !string.IsNullOrEmpty(n))
+ .ToList();
+ if (authors.Count > 0)
+ {
+ string authStr = authors.Count <= 4
+ ? string.Join(", ", authors)
+ : string.Join(", ", authors.Take(4)) + ", et al.";
+ lines.Add(authStr);
+ }
+
+ // Abstract snippet
+ string abs = entry.Element(atom + "summary")?.Value?.Trim() ?? "";
+ abs = Regex.Replace(abs, @"\s+", " ");
+ if (!string.IsNullOrEmpty(abs))
+ lines.Add(abs.Length > 120 ? abs[..117] + "..." : abs);
+
+ // Link
+ lines.Add($"https://arxiv.org/abs/{arxivId}");
+
+ Cache[arxivId] = lines;
+ return lines;
+ }
+
+ static void WriteCells(string id, IEnumerable rows)
+ {
+ SendJson(new { type = "write", id, cells = rows });
+ }
+
+ static void SendJson(object obj)
+ {
+ Console.WriteLine(JsonSerializer.Serialize(obj, JsonOpts));
+ }
+
+ static void SendLog(string message)
+ {
+ SendJson(new { type = "log", message });
+ }
+}
diff --git a/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/README.md b/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/README.md
new file mode 100644
index 00000000..46ef063d
--- /dev/null
+++ b/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/README.md
@@ -0,0 +1,66 @@
+# quicksheet-arxiv-ext
+
+> **2026-05-30: DUPLICATE.** `Deskworks/quicksheet-arxiv` already covers the `arxiv:` prefix
+> and is listed in the main README. This repo (`cemheren/quicksheet-arxiv-ext`) was pushed
+> before discovering the existing one. User should delete `cemheren/quicksheet-arxiv-ext`
+> or repurpose it. Do NOT cross-link from main README — prefix collision.
+
+A QuickSheet extension that looks up arXiv papers by ID. Type an arXiv ID in a cell and get the title, authors, abstract snippet, and link — right on your desktop.
+
+**Persona:** Researchers, grad students, and academics who keep a reading list on their desktop and want quick paper metadata without opening a browser.
+
+## Install
+
+```
+ext: github:cemheren/quicksheet-arxiv-ext
+```
+
+## Usage
+
+```
+arxiv: 2301.07041
+arxiv: 2301.07041v2
+arxiv: hep-th/9802150
+arxiv: https://arxiv.org/abs/2301.07041
+```
+
+## Output
+
+The extension fills cells vertically:
+
+| Cell | Content |
+|------|---------|
+| Row 0 | Paper title (truncated to ~100 chars) |
+| Row 1 | Authors (up to 4, then "et al.") |
+| Row 2 | Abstract snippet (~120 chars) |
+| Row 3 | `https://arxiv.org/abs/` (clickable in QuickSheet) |
+
+## Pairs with
+
+- **`cite:`** — use `cite:` for DOI-based citation formatting, `arxiv:` for preprint lookup.
+- Together they cover the full academic workflow: discover on arXiv → cite the published version.
+
+## API
+
+Uses the free [arXiv API](https://info.arxiv.org/help/api/index.html) (Atom feed, no auth, no rate-limit key needed). Requests are cached in-memory for the session.
+
+## Build
+
+```bash
+dotnet build ArxivExtension.csproj
+```
+
+.NET 9, MIT, zero NuGet dependencies.
+
+## Protocol
+
+Standard QuickSheet JSON-lines:
+
+1. On `{"type":"init"}`, emits `{"type":"register","prefix":"arxiv","name":"arXiv Lookup","version":"1.0.0"}`.
+2. On `{"type":"activate","id":"...","params":["2301.07041"]}`, fetches from arXiv API and replies with `{"type":"write","id":"...","cells":[...]}`.
+
+See [docs/extension-protocol.md](https://github.com/cemheren/QuickSheet/blob/main/docs/extension-protocol.md).
+
+## License
+
+MIT.
diff --git a/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/quicksheet-extension.json b/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/quicksheet-extension.json
new file mode 100644
index 00000000..49f9b9f8
--- /dev/null
+++ b/.claude/skills/grow-quicksheet/drafts/extensions/quicksheet-arxiv-ext/quicksheet-extension.json
@@ -0,0 +1,8 @@
+{
+ "name": "arxiv",
+ "version": "1.0.0",
+ "prefix": "arxiv",
+ "description": "arXiv paper lookup — title, authors, abstract for QuickSheet",
+ "entry": "dotnet run --project ArxivExtension.csproj",
+ "minProtocolVersion": 1
+}
diff --git a/.claude/skills/grow-quicksheet/drafts/reddit-selfhosted.md b/.claude/skills/grow-quicksheet/drafts/reddit-selfhosted.md
new file mode 100644
index 00000000..b63b57f2
--- /dev/null
+++ b/.claude/skills/grow-quicksheet/drafts/reddit-selfhosted.md
@@ -0,0 +1,78 @@
+# r/selfhosted post draft
+
+**Subreddit:** r/selfhosted
+**Flair:** Self-Hosted Alternatives (or "Project Share" if available)
+
+---
+
+## Title
+
+**I replaced my Dashy/Homepage dashboard with a spreadsheet wallpaper — it's weirdly practical**
+
+---
+
+## Body
+
+I run a small homelab (Plex, Pi-hole, Nextcloud, couple of Docker stacks). I used Homepage for a while but kept wanting something simpler — no YAML to configure, no browser tab to keep open, and something I could just *type into* when I need to jot a quick note.
+
+So I built [QuickSheet](https://github.com/cemheren/QuickSheet): a spreadsheet that *is* the desktop wallpaper. You click the wallpaper, you're typing in a cell. Autosaves every 5 seconds to a CSV.
+
+The homelab angle: I use it as a service dashboard that lives on the desktop permanently — no tab, no browser, no alt-tab. Here's what my layout looks like:
+
+- **Health column** — each service gets a cell with the [`health:`](https://github.com/cemheren/quicksheet-health-ext) extension prefix. It HTTP-probes the URL and shows a green/yellow/red dot + latency. One cell per service.
+- **TLS expiry column** — `tls: myserver.local` shows days remaining on the cert. Goes yellow under 30d.
+- **Launcher row** — `r: ssh nas` / `r: docker compose up -d` / `r: firefox http://plex.local:32400`. Multi-select cells, hit Enter, they all fire.
+- **Notes area** — just plain text cells for "reboot nas tonight" or pasting a quick IP.
+
+Extensions are just git repos that speak JSON-lines over stdin/stdout. `ext: github:cemheren/quicksheet-health-ext` in any cell, and the `health:` prefix is live. There's also [`docker:`](https://github.com/cemheren/quicksheet-docker), [`ping:`](https://github.com/cemheren/quicksheet-ping-ext), [`tls:`](https://github.com/cemheren/quicksheet-tls-ext), [`sysmon:`](https://github.com/cemheren/quicksheet-sysmon) for CPU/RAM/disk.
+
+**What it is:**
+
+- .NET 9, zero NuGet dependencies (entire supply chain = .NET SDK)
+- Linux (X11) and Windows
+- CSV is the only persistence format — your "dashboard config" is a CSV file
+- Themes (Nord, Gruvbox, Dracula, etc.) — Ctrl+T to cycle
+- Cell prefixes drive everything: `r:` = run command, `i:` = live subprocess output, `s:` = sparkline, `ext:` = install extension
+
+**What it isn't:**
+
+- Not a Homepage/Dashy replacement if you need widget tiles, icons, or a web-accessible dashboard
+- Not Wayland-compatible yet (X11 only on Linux)
+- Not "pretty" in the polished-webapp sense — it's a grid with text
+
+If you're the kind of person who has a terminal open all day anyway and just wants a persistent scratchpad + status board on the wallpaper, it might click.
+
+**Links:**
+- GitHub: https://github.com/cemheren/QuickSheet
+- 60-second tour: https://github.com/cemheren/QuickSheet/blob/main/docs/tour.md
+- Homelab-specific guide: https://github.com/cemheren/QuickSheet/blob/main/docs/for-homelab.md
+- Health extension: https://github.com/cemheren/quicksheet-health-ext
+
+Happy to answer questions. This is a side project — I'm aware it's niche, but for the niche it serves, it's been really useful on my own machine daily.
+
+---
+
+## Posting notes
+
+- **Best time:** weekday morning EST (Tue–Thu, 8–10 AM)
+- **Tone:** practical, not promotional. Lead with the problem (dashboard fatigue, YAML config files, needing a browser tab open). Show the actual use case.
+- **Expectations:** r/selfhosted is friendly to small projects if you're honest about scope. "This isn't a Homepage killer, but here's why it works for me" lands better than "look at my thing."
+- **Avoid:** calling it "production-grade," claiming large user counts, comparing unfavorably to established tools. Acknowledge limitations upfront (X11 only, no Wayland, not web-accessible).
+- **Follow-up comment:** Prepare a top-level reply with the full extension list relevant to homelabbers (docker, health, ping, tls, sysmon, mxck) and a quick "here's my actual CSV" snippet.
+
+---
+
+## Prepared first comment
+
+> For the curious, here's the extensions I use in my homelab layout:
+>
+> | Cell content | What it does |
+> |---|---|
+> | `ext: github:cemheren/quicksheet-health-ext` | Install the health-check extension |
+> | `health: http://plex.local:32400/web` | Green dot if 200, red if down |
+> | `tls: nas.mydomain.com` | Days until cert expires |
+> | `ping: 192.168.1.1` | Latency to router |
+> | `docker: plex` | Container status |
+> | `sysmon: cpu` | Live CPU percentage |
+>
+> Each extension is ~50 lines of code in any language. If you have a weird service you want to monitor, you can write your own in an afternoon. The protocol is just JSON-lines over stdin/stdout — [docs here](https://github.com/cemheren/QuickSheet#extensions--make-your-desktop-do-more).
diff --git a/.claude/skills/grow-quicksheet/log.md b/.claude/skills/grow-quicksheet/log.md
index 7b845528..f004227b 100644
--- a/.claude/skills/grow-quicksheet/log.md
+++ b/.claude/skills/grow-quicksheet/log.md
@@ -1,3 +1,140 @@
+## 2026-05-30 (feat: --get cell value extraction)
+
+- Stars: 0 (Δ 0).
+- Action: Added `--get ` headless flag — extracts a single cell value from CSV by Excel-style reference. Makes QuickSheet composable in shell scripts (`balance=$(QuickSheet budget.csv --get C5)`).
+- Bucket: E (quality-of-life feature).
+- Outcome: PR #245.
+- Follow-up: Next run variety → Bucket C or D. Consider drafting a "shell scripting with QuickSheet" blog snippet showing --get + --export-md pipeline.
+
+## 2026-05-30 (docs: virtual tabs design spec)
+
+- Stars: 0 (Δ 0).
+- Action: Wrote design specification for virtual tabs / weekly aging feature (issue #158). Covers data model, CSV format with backward-compatible `---TAB:name---` separators, aging logic with pinned-cell rules, UX, and four implementation phases.
+- Bucket: A (product polish — addressing owner's feature request).
+- Outcome: PR #244.
+- Follow-up: User reviews design, provides answers to open questions. Implementation can follow in phased PRs once spec is approved.
+
+## 2026-05-30 (duplicate: quicksheet-arxiv-ext)
+
+- Stars: 0 (Δ 0).
+- Action: Attempted Bucket F — scaffolded `quicksheet-arxiv-ext` (arXiv paper lookup). Built successfully, pushed to `cemheren/quicksheet-arxiv-ext`. Then discovered `Deskworks/quicksheet-arxiv` already covers the same `arxiv:` prefix and is listed in README line 208.
+- Bucket: F (vertical extension) — **wasted run**.
+- Outcome: Duplicate repo pushed. Cannot delete (missing `delete_repo` scope). Marked draft README as SUPERSEDED. No cross-link PR opened.
+- Follow-up: User should delete `cemheren/quicksheet-arxiv-ext` (duplicate). Next run should sweep for new issues or no-op if saturation still applies. 15+ PRs still awaiting merge.
+
+## 2026-05-29 (docs: for-artists page)
+
+- Stars: 0 (Δ 0).
+- Action: Created `docs/for-artists.md` audience landing page + `examples/artist-dashboard.csv`. Targets illustrators, writers, musicians, animators. Pairs with `words`, `ollama`, `unitconv` extensions.
+- Bucket: A (product polish).
+- Outcome: PR #242.
+- Follow-up: Next run variety → Bucket D or E. Consider `for-dms.md` PR #231 already open.
+
+## 2026-05-29 (feat: quicksheet-init-ext)
+
+- Stars: 0 (Δ 0).
+- Action: Created `cemheren/quicksheet-init-ext` — combat initiative tracker for TTRPG GMs. Sort combatants by initiative roll, cycle turns, track rounds. Pairs with `quicksheet-dice` for a DM-screen bundle. Zero NuGet deps.
+- Bucket: F (vertical extension).
+- Outcome: Repo pushed → https://github.com/cemheren/quicksheet-init-ext. Cross-link PR #241.
+- Follow-up: Next run variety → Bucket A (audience landing page) or Bucket D (awesome-list draft).
+
+## 2026-05-29 (draft: r/selfhosted post)
+
+- Stars: 0 (Δ 0).
+- Action: Drafted r/selfhosted submission — "Homepage/Dashy alternative" angle featuring `health-ext`, `tls`, `docker`, `ping`, `sysmon` extensions. Includes posting notes, timing strategy, and a prepared first comment with extension table.
+- Bucket: C (content draft).
+- Outcome: Draft saved at `drafts/reddit-selfhosted.md`, commit 0f37a65.
+- Follow-up: Next run variety → Bucket F (push `roll-ext` draft) or Bucket E.
+
+## 2026-05-29 (feat: quicksheet-salestax-ext)
+
+- Stars: 0 (Δ 0).
+- Action: Created `cemheren/quicksheet-salestax-ext` — US state sales tax rate lookup for all 50 states + DC. Supports abbreviations, full names, and dollar amount calc. Tax Foundation 2024 data. Zero NuGet deps.
+- Bucket: F (vertical extension).
+- Outcome: Repo pushed → https://github.com/cemheren/quicksheet-salestax-ext. Cross-link PR #239.
+- Follow-up: Next run variety → Bucket D (awesome-list draft) or Bucket A.
+
+## 2026-05-29 (feat: --stats CSV summary)
+
+- Stars: 0 (Δ 0).
+- Action: Added `--stats` headless flag — prints file size, row/column count, headers, and cell fill percentage. Makes QuickSheet discoverable as a CLI CSV inspection tool.
+- Bucket: E (QoL feature).
+- Outcome: PR #238.
+- Follow-up: Next run variety → Bucket F (roll: dice extension) or Bucket D.
+
+## 2026-05-29 (ci: release workflow for binaries)
+
+- Stars: 0 (Δ 0).
+- Action: Created `.github/workflows/release.yml` — builds self-contained, trimmed, single-file binaries (win-x64 .zip + linux-x64 .tar.gz) on every `v*` tag push. Uses `softprops/action-gh-release` to attach artifacts to GitHub Releases.
+- Bucket: E (QoL feature / infra).
+- Outcome: PR #235.
+- Follow-up: After merge + first tagged release, draft Scoop manifest submission.
+
+## 2026-05-29 (research: package manager distribution)
+
+- Stars: 0 (Δ 0).
+- Action: Researched package manager distribution strategy (winget, Scoop, AUR, Homebrew, Nix). Found zero binary releases exist — no CI, no artifacts on any release tag. Documented requirements, manifest sketches, and a 5-run roadmap from zero to three package managers.
+- Bucket: R (research).
+- Outcome: `research/package-manager-distribution.md` committed.
+- Follow-up: Next action = create `.github/workflows/release.yml` (Bucket E, ~40 lines YAML). This unblocks all package manager submissions.
+
+## 2026-05-29 (feat: --import-json CLI converter)
+
+- Stars: 0 (Δ 0).
+- Action: Added `--import-json ` headless converter. Reads a JSON array of objects, emits CSV with first row as headers. Round-trip compatible with `--export-json`. ~60 lines in GridManager + ~35 in Program.cs.
+- Bucket: E (QoL feature).
+- Outcome: PR #233.
+- Follow-up: none.
+
+## 2026-05-29 (docs: tabletop GM audience page)
+
+- Stars: 0 (Δ 0).
+- Action: Created `docs/for-dms.md` targeting D&D / Pathfinder / TTRPG game masters. Covers dice rolling (quicksheet-dice), initiative tracking, NPC stat blocks, quick-reference rules, session-tool launchers, and theme picks. Added `examples/dm-screen.csv` starter layout and README cross-link.
+- Bucket: A (docs polish — audience landing page).
+- Outcome: PR #231.
+- Follow-up: none — five audience pages now live (homelab, traders, SRE, students, DMs).
+
+## 2026-05-29 (feat: pubmed extension — academic persona)
+
+- Stars: 0 (Δ 0).
+- Action: Created `cemheren/quicksheet-pubmed-ext` — PubMed article lookup via NCBI E-utilities (free, no key). Supports PMID fetch and keyword search. Pairs with `cite:` and `arxiv:` for a full academic research dashboard on the desktop.
+- Bucket: F (vertical extension).
+- Outcome: Repo pushed → https://github.com/cemheren/quicksheet-pubmed-ext. Cross-link PR #230.
+- Follow-up: none — academic trio (arxiv + cite + pubmed) now complete.
+
+## 2026-05-29 (docs: Wayland support investigation)
+
+- Stars: 0 (Δ 0).
+- Action: Researched Wayland layer-shell feasibility for desktop mode. Documented compositor compatibility (wlroots ✅, GNOME ❌), P/Invoke approach, phased implementation plan, and effort estimates. Addresses issue #3.
+- Bucket: R (research) addressing open issue.
+- Outcome: PR #229.
+- Follow-up: Needs a contributor with Sway/Hyprland to implement Phase 2. Issue #3 stays open until code lands.
+
+## 2026-05-28 (docs: add 18 missing extensions to README + directory)
+
+- Stars: 0 (Δ 0).
+- Action: Audited all Deskworks/ and cemheren/ quicksheet-* repos against README and docs/extensions.md. Found 18 published extensions not listed. Added them all: apistatus, b64, dict, gitlog, hntop, news, rate, sys, pomo, stocks, ai, hash, mvn, nuget, ollama, pubmed, unit, words.
+- Bucket: A (docs polish — discoverability).
+- Outcome: PR #228.
+- Follow-up: none — catalog now reflects all known public extension repos.
+
+## 2026-05-28 (feat: --theme and --list-themes CLI flags)
+
+- Stars: 0 (Δ 0).
+- Action: Added `--theme ` flag to start QuickSheet with a specific color theme, and `--list-themes` to enumerate available presets. Also fixed arg parsing so flag values don't get mistaken for the CSV path.
+- Bucket: E (QoL feature).
+- Outcome: PR #227.
+- Follow-up: none.
+
+## 2026-05-28 (docs: ghst + lc in for-students.md)
+
+- Stars: 0 (Δ 0).
+- Action: Added `ghst:` (GitHub streak) and `lc:` (LeetCode daily) extensions to `docs/for-students.md`. Both extensions exist under Deskworks/ but the student audience page didn't mention them. Added a zone-table row + dedicated "GitHub streak + LeetCode daily" section.
+- Bucket: A (docs polish).
+- Outcome: PR #226.
+- Note: Also attempted to create `cemheren/quicksheet-ghstreak-ext` before realizing `Deskworks/quicksheet-ghstreak` already exists. Couldn't delete (no `delete_repo` scope). User should delete the duplicate `cemheren/quicksheet-ghstreak-ext` repo.
+- Follow-up: none — all backlog Bucket F items already exist under Deskworks/.
+
## 2026-05-19 (no-op #31 — #139 still open, hold)
- Stars: 0 (Δ 0). PR #139 still open, no other action items. Hold.
@@ -1036,6 +1173,8 @@
- **Generic-primitive justifications are not enough.** "Hits N/M personas" alone is not a green light — persona-shaped specifics are required.
- **Live backlog (re-ranked after the c?:/timer revert):**
+ Pre-flight: see standing rules above.
+ 0. **Bucket E: `.github/workflows/release.yml`** — publish self-contained win-x64 + linux-x64 binaries on tag push. Unblocks Scoop/winget/AUR submissions. ~40 lines YAML, 1 file. See `research/package-manager-distribution.md`.
Pre-flight rule for any item below: if you can't explain in one sentence *why this specific persona will install QuickSheet because of this* (not "it could be useful for everyone"), skip and pick something else.
1. **Bucket F: `health:` HTTP-probe extension.** Reads `services.csv` (name,url,expected_status); fills a row of green/red dots. Homelab persona; writes its own r/selfhosted screenshot. New extension repo on user's account.
2. **Bucket F: `leetcode:` + `gh:` user-streak combo.** Students persona; "CS-student flex bundle." Free APIs, lowest auth.
diff --git a/.claude/skills/grow-quicksheet/research/package-manager-distribution.md b/.claude/skills/grow-quicksheet/research/package-manager-distribution.md
new file mode 100644
index 00000000..39415920
--- /dev/null
+++ b/.claude/skills/grow-quicksheet/research/package-manager-distribution.md
@@ -0,0 +1,175 @@
+# Package Manager Distribution Strategy
+
+**Summary:**
+- QuickSheet has zero presence on any package manager. Current releases are tag-only (no binaries).
+- Pre-built self-contained binaries on GitHub Releases are the prerequisite for ALL package managers.
+- Highest ROI channels: **Scoop** (easy, dev audience), **winget** (wide Windows reach), **AUR** (Arch/unixporn crowd).
+- A GitHub Actions CI workflow to publish binaries on tag is the single blocking step before any package manager submission.
+- Once binaries exist, Scoop submission is < 1 hour of work; winget ~ 2 hours; AUR ~ 3 hours.
+
+---
+
+## Current State (2026-05-29)
+
+- **Releases:** v0.36.0 is latest. All releases are source-only tags — zero binary assets attached.
+- **CI:** No `.github/workflows/` directory exists. No automated build or release pipeline.
+- **Install method:** Clone → `dotnet build` → run. This is a huge barrier for non-.NET users.
+
+## Target Package Managers (ranked by ROI)
+
+### 1. Scoop (Windows) — HIGH priority
+
+| Attribute | Detail |
+|-----------|--------|
+| Audience | Windows developers, CLI power users |
+| Format | JSON manifest in `ScoopInstaller/Extras` bucket |
+| Requirements | Stable URL to a `.zip` of binaries, SHA256 hash |
+| Effort | Low — one JSON file, test locally, submit PR |
+| Overlap | r/commandline, r/dotnet, terminal-tool communities |
+
+**Manifest sketch:**
+```json
+{
+ "version": "0.36.0",
+ "description": "Interactive spreadsheet as your desktop wallpaper",
+ "homepage": "https://github.com/cemheren/QuickSheet",
+ "license": "MIT",
+ "architecture": {
+ "64bit": {
+ "url": "https://github.com/cemheren/QuickSheet/releases/download/v0.36.0/QuickSheet-win-x64.zip",
+ "hash": ""
+ }
+ },
+ "bin": "QuickSheet.exe",
+ "shortcuts": [["QuickSheet.exe", "QuickSheet"]]
+}
+```
+
+### 2. winget (Windows) — HIGH priority
+
+| Attribute | Detail |
+|-----------|--------|
+| Audience | All Windows 10/11 users (ships with OS) |
+| Format | YAML manifest in `microsoft/winget-pkgs` |
+| Requirements | Public installer URL (zip/exe/msi), SHA256, silent-install capability |
+| Effort | Moderate — use `winget-create` tool, fill metadata, submit PR |
+| Notes | Self-contained .NET publish zip works; "portable" installer type |
+
+**Identifier:** `cemheren.QuickSheet`
+
+### 3. AUR (Arch Linux) — MEDIUM-HIGH priority
+
+| Attribute | Detail |
+|-----------|--------|
+| Audience | Arch Linux users, r/unixporn, tiling WM enthusiasts |
+| Format | PKGBUILD script |
+| Requirements | Source tarball or binary release URL |
+| Effort | Moderate — write PKGBUILD, test in clean chroot |
+| Notes | Can do `-bin` variant (pre-built) or source build. Binary is simpler for users. |
+
+**PKGBUILD sketch (binary variant, `quicksheet-bin`):**
+```bash
+pkgname=quicksheet-bin
+pkgver=0.36.0
+pkgrel=1
+pkgdesc="Interactive spreadsheet as your desktop wallpaper (X11)"
+arch=('x86_64')
+url="https://github.com/cemheren/QuickSheet"
+license=('MIT')
+depends=('libx11' 'libxft')
+source=("$url/releases/download/v${pkgver}/QuickSheet-linux-x64.tar.gz")
+sha256sums=('...')
+
+package() {
+ install -Dm755 QuickSheet "$pkgdir/usr/bin/quicksheet"
+}
+```
+
+### 4. Homebrew (macOS/Linux) — MEDIUM priority
+
+| Attribute | Detail |
+|-----------|--------|
+| Audience | macOS developers, some Linux users |
+| Format | Ruby formula in a tap (`cemheren/homebrew-quicksheet`) |
+| Requirements | Tarball URL, depends on .NET runtime or self-contained binary |
+| Notes | QuickSheet doesn't support macOS desktop mode — console/headless only. Lower priority. |
+
+### 5. Nix/nixpkgs — LOW priority (high effort)
+
+| Attribute | Detail |
+|-----------|--------|
+| Audience | NixOS enthusiasts, declarative-config fans |
+| Format | Nix derivation |
+| Requirements | Complex — needs buildDotnetModule or fetchNuGet deps |
+| Notes | Zero NuGet deps actually makes this EASIER than most .NET apps. Still high initial effort. |
+
+### 6. Chocolatey (Windows) — LOW priority
+
+| Attribute | Detail |
+|-----------|--------|
+| Audience | Enterprise/sysadmin |
+| Format | NuGet-style .nuspec + install script |
+| Notes | More overhead than Scoop/winget for similar audience. Skip unless asked. |
+
+## Blocking Prerequisite: Release Binaries CI
+
+**Without binary artifacts on GitHub Releases, NONE of the above are possible.**
+
+Required GitHub Actions workflow (`release.yml`):
+```yaml
+on:
+ push:
+ tags: ['v*']
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ include:
+ - os: windows-latest
+ rid: win-x64
+ artifact: QuickSheet-win-x64.zip
+ - os: ubuntu-latest
+ rid: linux-x64
+ artifact: QuickSheet-linux-x64.tar.gz
+ runs-on: ${{ matrix.os }}
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-dotnet@v4
+ with: { dotnet-version: '9.0.x' }
+ - run: dotnet publish ExcelConsole.csproj -c Release -r ${{ matrix.rid }} --self-contained -p:PublishSingleFile=true -p:PublishTrimmed=true -o publish/
+ - # zip/tar the publish/ directory
+ - uses: softprops/action-gh-release@v2
+ with:
+ files: ${{ matrix.artifact }}
+```
+
+**Key publish flags:**
+- `--self-contained` — no .NET runtime needed on target machine
+- `-p:PublishSingleFile=true` — one executable
+- `-p:PublishTrimmed=true` — smaller binary (~30-50MB → ~15-25MB)
+- `-r win-x64` / `-r linux-x64` — platform-specific
+
+## Implications for QuickSheet
+
+1. **Immediate next action (Bucket E/B):** Create `.github/workflows/release.yml` that publishes self-contained binaries on tag push. This unblocks ALL package manager submissions. ~40 lines of YAML, touches 1 file, well within the "small change" boundary.
+
+2. **After CI lands:** Submit Scoop manifest to `ScoopInstaller/Extras`. Draft the JSON manifest + PR body now, ship when binaries exist. Scoop's audience (Windows CLI devs) is ideal for QuickSheet.
+
+3. **After Scoop:** Submit winget manifest to `microsoft/winget-pkgs`. Broader reach, same binary.
+
+4. **After winget:** Create `quicksheet-bin` AUR package. Captures the Arch/unixporn audience that the existing `docs/for-students.md` and Reddit drafts target.
+
+5. **README badge:** Once on any package manager, add install badges to README hero section. `scoop install quicksheet` one-liner is far more compelling than "clone and build."
+
+## Effort Estimate
+
+| Step | Effort | Blocked on |
+|------|--------|-----------|
+| Release CI workflow | 1 run | nothing |
+| Scoop manifest draft | 1 run | CI merged + one tagged release |
+| winget manifest draft | 1 run | CI merged + one tagged release |
+| AUR PKGBUILD draft | 1 run | CI merged + one tagged release |
+| README install section | 1 run | at least one package manager accepted |
+
+Total: ~5 runs from "no distribution" to "on 3 package managers with install badges."
diff --git a/CellPrefix.cs b/CellPrefix.cs
index 9189681f..637ac407 100644
--- a/CellPrefix.cs
+++ b/CellPrefix.cs
@@ -118,6 +118,36 @@ public static bool IsSparkline(string value) =>
return sb.ToString();
}
+ // ── Progress bar prefix ─────────────────────────────────────────
+
+ private static readonly char ProgressFilled = '█';
+ private static readonly char ProgressEmpty = '░';
+ private const int ProgressBarWidth = 10;
+
+ ///
+ /// Returns true when a cell starts with "p: " (progress bar).
+ ///
+ public static bool IsProgressBar(string value) =>
+ value.StartsWith("p: ", StringComparison.OrdinalIgnoreCase);
+
+ ///
+ /// Renders a "p: 75" cell as "███████░░░ 75%".
+ /// Accepts values 0–100. Returns null if not a progress cell or value is invalid.
+ ///
+ public static string? RenderProgressBar(string value)
+ {
+ if (!IsProgressBar(value)) return null;
+ string rest = value[3..].Trim();
+ if (!double.TryParse(rest, System.Globalization.NumberStyles.Float,
+ System.Globalization.CultureInfo.InvariantCulture, out double pct))
+ return null;
+ pct = Math.Clamp(pct, 0, 100);
+ int filled = (int)Math.Round(pct / 100.0 * ProgressBarWidth);
+ return new string(ProgressFilled, filled)
+ + new string(ProgressEmpty, ProgressBarWidth - filled)
+ + $" {pct:0}%";
+ }
+
// ── Color prefix ───────────────────────────────────────────────
private static readonly Dictionary ColorMap = new(StringComparer.OrdinalIgnoreCase)
diff --git a/Platform/Linux/DesktopWindow.cs b/Platform/Linux/DesktopWindow.cs
index cf33a281..b4c50d77 100644
--- a/Platform/Linux/DesktopWindow.cs
+++ b/Platform/Linux/DesktopWindow.cs
@@ -717,6 +717,14 @@ private void Render()
if (spark != null) displayVal = spark;
}
+ // Render progress bar cells (p: 75 → ███████░░░ 75%)
+ bool isProgressBar = !isEditingThisCell && !isSparkline && CellPrefix.IsProgressBar(cellVal);
+ if (isProgressBar)
+ {
+ string? bar = CellPrefix.RenderProgressBar(cellVal);
+ if (bar != null) displayVal = bar;
+ }
+
// Render color-prefixed cells: strip prefix from display
var colorParsed = (!isEditingThisCell && !isSparkline) ? CellPrefix.ParseColor(cellVal) : null;
if (colorParsed != null)
diff --git a/Platform/Windows/DesktopForm.cs b/Platform/Windows/DesktopForm.cs
index 7b528f7d..a27f04fa 100644
--- a/Platform/Windows/DesktopForm.cs
+++ b/Platform/Windows/DesktopForm.cs
@@ -595,6 +595,14 @@ private void RenderGrid(Graphics g, int formWidth, int formHeight)
if (spark != null) displayVal = spark;
}
+ // Render progress bar cells (p: 75 → ███████░░░ 75%)
+ bool isProgressBar = !isSparkline && CellPrefix.IsProgressBar(cellVal);
+ if (isProgressBar)
+ {
+ string? bar = CellPrefix.RenderProgressBar(cellVal);
+ if (bar != null) displayVal = bar;
+ }
+
var colorParsed = !isSparkline ? CellPrefix.ParseColor(cellVal) : null;
if (colorParsed != null)
displayVal = colorParsed.Value.text;