quick-view

安装量: 67
排名: #11364

安装

npx skills add https://github.com/shipshitdev/library --skill quick-view

Quick View

Generate minimal HTML to review structured data in a browser. Minimal styling, maximum readability.

When to Use User wants to review output that's hard to read in terminal Lists, tables, drafts, summaries that benefit from visual layout User says: "show me", "view this", "make reviewable", "open as webpage" Output Rules

DO:

Semantic HTML:

,
    ,
    ,
    , 
    Use the base template with CSS variables
    Write to _private/views/
    Open with open _private/views/{filename}

    DO NOT:

    Add decorative styling beyond the base template Use CSS frameworks Over-engineer or "make it nice" File Naming

    Views have a lifecycle: temporary → keeper → archived.

    Stage Filename When Temporary name-temp.html Default for new views Keeper name.html User says "keep this", "this is good" Archived name.2025-01-01.html Previous keeper when promoting new one

    Rules:

    Always create with -temp suffix — Every new view starts as name-temp.html Promote on approval — When user approves, rename to name.html Archive before replacing — If name.html exists, rename to name.DATE.html before promoting Never regenerate keepers — Only regenerate -temp files

    Workflow:

    First iteration

    drafts-temp.html ← created

    User: "keep this"

    drafts.html ← promoted (temp deleted)

    Later iteration

    drafts-temp.html ← new temp created drafts.html ← keeper untouched

    User: "this is better, keep it"

    drafts.2025-01-01.html ← old keeper archived drafts.html ← new keeper promoted

    Trigger phrases for promotion:

    "keep this", "this is good", "save this" "make this the default", "lock this in" "I like this one" Base Template

    Every quick-view HTML file:

    <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>{title}</title> <style> :root { --bg: #fff; --text: #222; --muted: #666; --border: #ddd; --accent: #1976d2; } @media (prefers-color-scheme: dark) { :root { --bg: #1a1a1a; --text: #e0e0e0; --muted: #999; --border: #333; --accent: #64b5f6; } } body { max-width: 800px; margin: 40px auto; padding: 0 20px; font-family: system-ui; background: var(--bg); color: var(--text); } table { border-collapse: collapse; width: 100%; } td, th { border: 1px solid var(--border); padding: 8px; text-align: left; } .meta { color: var(--muted); font-size: 0.875rem; margin-bottom: 1rem; } details { margin: 0.5rem 0; } summary { cursor: pointer; } pre { background: var(--border); padding: 1rem; overflow-x: auto; border-radius: 4px; } /* Long content truncation */ .truncate { max-height: 200px; overflow: hidden; position: relative; } .truncate.expanded { max-height: none; } .truncate:not(.expanded)::after { content: ''; position: absolute; bottom: 0; left: 0; right: 0; height: 60px; background: linear-gradient(transparent, var(--bg)); } .expand-btn { color: var(--accent); background: none; border: none; cursor: pointer; padding: 0.5rem 0; font-size: 0.875rem; } /* Type borders */ .type-user { border-left: 3px solid var(--accent); padding-left: 1rem; } .type-draft { border-left: 3px solid #ff9800; padding-left: 1rem; } .type-done { border-left: 3px solid #4caf50; padding-left: 1rem; } /* Source attribution */ .source { color: var(--muted); font-size: 0.75rem; } .source a { color: var(--muted); } .source a:hover { color: var(--accent); } </style> </head> <body>

    Generated: {timestamp} · {count} items

    {content} <script> // Truncation toggle document.querySelectorAll('.truncate').forEach(el => { if (el.scrollHeight > 220) { const btn = document.createElement('button'); btn.className = 'expand-btn'; btn.textContent = 'Show more'; btn.onclick = () => { el.classList.toggle('expanded'); btn.textContent = el.classList.contains('expanded') ? 'Show less' : 'Show more'; }; el.after(btn); } else { el.classList.add('expanded'); // No truncation needed } }); </script> </body> </html>

    Patterns List of items

    Title

    • @username — action item

    Table

ContactActionDraft
@nameFollow upHey...

Expandable sections (for long content)

@username — action
Long content here that may need truncation...

Type-differentiated items

User message or input
Draft content
Completed item

With actions

Open Telegram ·

Sourced data (citations & drill-down)

When displaying data gathered from external sources, always include attribution links for drill-down.

Add to base template CSS:

.source { color: var(--muted); font-size: 0.75rem; } .source a { color: var(--muted); } .source a:hover { color: var(--accent); }

Inline attribution (preferred for lists):

Tip title — Description of the tip. @username

Table with source column:

TipSource
Description here @user

Expandable with source in summary:

Tip title @source

Full content...

Meta header with main source:

Generated: {timestamp} · {count} items · Source: Original thread

Principles:

Always link to original when data comes from external sources Use @username for social media, domain for articles Source links should be muted/subtle, not prominent Include main source in meta header for collections from single source Editable drafts (with diff tracking)

For drafts that user may edit before sending. Tracks original vs edited for later analysis.

@username — action
Original draft text here

Include this script block at end of <body> (before closing </body> tag):

function saveDraft(el) { const key = 'draft_' + el.dataset.username; const edited = el.textContent.trim(); const original = el.dataset.original; if (edited !== original) { localStorage.setItem(key, edited); el.closest('details').querySelector('.status').textContent = '(edited)'; } }

function copyDraft(btn) { const pre = btn.closest('details').querySelector('pre'); navigator.clipboard.writeText(pre.textContent.trim()); btn.textContent = 'Copied!'; setTimeout(() => btn.textContent = 'Copy', 1500); }

function restoreEdits() { document.querySelectorAll('pre[data-username]').forEach(el => { const saved = localStorage.getItem('draft_' + el.dataset.username); if (saved) { el.textContent = saved; el.closest('details').querySelector('.status').textContent = '(edited)'; } }); }

function exportEdits() { const edits = []; document.querySelectorAll('pre[data-username]').forEach(el => { const original = el.dataset.original; const current = el.textContent.trim(); if (original !== current) { edits.push({ username: el.dataset.username, original, edited: current }); } }); if (edits.length === 0) { alert('No edits to export'); return; } const blob = new Blob([JSON.stringify({exported_at: new Date().toISOString(), edits}, null, 2)], {type: 'application/json'}); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'draft_edits.json'; a.click(); }

restoreEdits();

Add export button in header when using editable drafts:

Generated: {timestamp} · {count} drafts ·

Workflow Identify the data to display (file, variable, recent output) Choose pattern: list, table, or expandable sections Generate HTML using template above Write to _private/views/{name}-temp.html Run open _private/views/{name}-temp.html If user approves, promote to {name}.html Example

User: "show me the drafts"

Claude:

Reads _private/drafts/outreach_drafts.md Parses each draft (heading = contact, body = draft) Generates HTML with

for each draft Writes to _private/views/drafts-temp.html Runs open _private/views/drafts-temp.html

Result: Browser opens, user sees expandable list of drafts with auto dark/light mode, long content truncated with "Show more", can copy each one.

User: "this looks good, keep it"

Claude:

Renames drafts-temp.html → drafts.html Confirms: "Saved as drafts.html" Styling Handoff

This skill produces functional HTML with minimal styling. For full visual styling, invoke the html-style skill after generating.

Classes used by quick-view (compatible with html-style):

Class Purpose .type-user User input/message .type-draft Draft content .type-done Completed item .source Attribution links .meta Metadata header .truncate Long content container .actions Action button container

Data attributes for JS hooks:

data-username — Identifier for drafts data-original — Original text for diff tracking Attribution

Truncation pattern and CSS variables approach inspired by simon willison's claude-code-transcripts.

返回排行榜