Add 5 new Gemma skills: regex-builder, meeting-notes, cover-letter, standup-summary, pricing-advisor

This commit is contained in:
Mustafa Ergisi
2026-04-07 19:06:15 +03:00
parent 536d2374b1
commit f3f07f9861
15 changed files with 795 additions and 0 deletions
+27
View File
@@ -0,0 +1,27 @@
---
name: cover-letter
description: Describe the role and your background, get a concise, compelling cover letter paragraph.
---
# Cover Letter
Give Gemma the job title, company, and a few words about yourself. Get a sharp cover letter opening paragraph — ready to send.
## Examples
* "Software engineer at Stripe, 4 years React experience, previously at a fintech startup"
* "Product manager at a healthcare startup, background in data analytics and user research"
* "Marketing manager at Nike, 3 years in growth marketing, strong in paid social"
* "Data scientist at Google, PhD in statistics, built ML models for e-commerce"
## Instructions
You MUST use the `run_js` tool with the following exact parameters:
- data: A JSON string with the following fields:
- role: String - the job title they are applying for
- company: String - the company name
- hook: String - one compelling opening sentence that grabs attention
- value: String - one sentence about their most relevant experience or skill
- fit: String - one sentence about why this role or company specifically
- close: String - one sentence closing with a call to action
@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cover Letter</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #f8f6f1;
font-family: Georgia, 'Times New Roman', serif;
color: #2c2416;
min-height: 100vh;
display: flex;
align-items: flex-start;
justify-content: center;
padding: 6%;
}
.card {
width: 100%;
background: #fff;
border-radius: 4px;
padding: 24px 20px;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}
.to-line {
font-size: clamp(11px, 3vw, 13px);
color: #999;
font-family: -apple-system, sans-serif;
margin-bottom: 18px;
letter-spacing: 0.3px;
}
.to-line strong { color: #444; }
.rule { height: 1px; background: #e5e0d5; margin-bottom: 18px; }
.letter-body {
font-size: clamp(14px, 4vw, 17px);
line-height: 1.9;
color: #2c2416;
}
.sentence { display: block; margin-bottom: 14px; }
.sentence:last-child { margin-bottom: 0; }
.footer {
margin-top: 20px;
font-size: 11px;
color: #c5bba8;
font-family: -apple-system, sans-serif;
text-align: right;
}
</style>
</head>
<body>
<div class="card">
<div class="to-line">Applying for: <strong id="role-company"></strong></div>
<div class="rule"></div>
<div class="letter-body">
<span class="sentence" id="hook"></span>
<span class="sentence" id="value"></span>
<span class="sentence" id="fit"></span>
<span class="sentence" id="close"></span>
</div>
<div class="footer">made on device with gemma</div>
</div>
<script>
const p = new URLSearchParams(window.location.search);
const role = p.get('role') || '';
const company = p.get('company') || '';
document.getElementById('role-company').textContent = role + (company ? ' at ' + company : '');
document.getElementById('hook').textContent = p.get('hook') || '';
document.getElementById('value').textContent = p.get('value') || '';
document.getElementById('fit').textContent = p.get('fit') || '';
document.getElementById('close').textContent = p.get('close') || '';
</script>
</body>
</html>
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Cover Letter</title></head>
<body>
<script>
window['ai_edge_gallery_get_result'] = async (data) => {
const d = JSON.parse(data);
return JSON.stringify({
webview: {
url: `../assets/webview.html?role=${encodeURIComponent(d.role)}&company=${encodeURIComponent(d.company)}&hook=${encodeURIComponent(d.hook)}&value=${encodeURIComponent(d.value)}&fit=${encodeURIComponent(d.fit)}&close=${encodeURIComponent(d.close)}`
}
});
};
</script>
</body>
</html>
+31
View File
@@ -0,0 +1,31 @@
---
name: meeting-notes
description: Paste raw meeting notes and get a clean summary with key decisions and action items.
---
# Meeting Notes
Turn messy meeting notes into a structured summary. Decisions, action items, and next steps — all extracted automatically.
## Examples
* "john said we should push the launch to next friday. sarah will handle the email campaign. budget approved at 5k. need to check with legal about the contract."
* "discussed q2 roadmap. feature x gets priority. mike owns backend. lisa does design by end of month. still unclear on pricing."
* "standup: blocked on api keys. will unblock tomorrow. demo moved to thursday."
## Instructions
You MUST use the `run_js` tool with the following exact parameters:
- data: A JSON string with the following fields:
- title: String - a short title for this meeting (3-5 words)
- summary: String - one sentence describing what the meeting was about
- decision1: String - first key decision made, or empty string
- decision2: String - second key decision made, or empty string
- action1_who: String - name or role of person responsible for first action item
- action1_what: String - what they need to do
- action2_who: String - name or role for second action item, or empty string
- action2_what: String - what they need to do, or empty string
- action3_who: String - name or role for third action item, or empty string
- action3_what: String - what they need to do, or empty string
- next_step: String - the single most important next step overall
@@ -0,0 +1,135 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Meeting Notes</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #fafafa;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
color: #1a1a1a;
min-height: 100vh;
display: flex;
align-items: flex-start;
justify-content: center;
padding: 6%;
}
.card { width: 100%; }
.meeting-title {
font-size: clamp(18px, 5vw, 26px);
font-weight: 700;
margin-bottom: 4px;
}
.summary {
font-size: clamp(12px, 3.5vw, 15px);
color: #666;
margin-bottom: 18px;
line-height: 1.5;
}
.section { margin-bottom: 16px; }
.section-label {
font-size: 10px;
font-weight: 800;
letter-spacing: 1.5px;
text-transform: uppercase;
color: #999;
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 6px;
}
.section-label::after {
content: '';
flex: 1;
height: 1px;
background: #e5e5e5;
}
.decision {
background: #fff8e6;
border-left: 3px solid #f59e0b;
border-radius: 0 6px 6px 0;
padding: 8px 12px;
font-size: clamp(12px, 3.5vw, 14px);
color: #1a1a1a;
margin-bottom: 6px;
line-height: 1.5;
}
.action {
display: flex;
align-items: flex-start;
gap: 8px;
margin-bottom: 8px;
}
.who {
flex-shrink: 0;
background: #e8f4fd;
color: #1a7fc1;
font-size: 11px;
font-weight: 700;
padding: 2px 8px;
border-radius: 20px;
white-space: nowrap;
}
.what {
font-size: clamp(12px, 3.5vw, 14px);
color: #333;
line-height: 1.5;
}
.next {
background: #f0fdf4;
border: 1px solid #86efac;
border-radius: 8px;
padding: 12px;
font-size: clamp(13px, 3.5vw, 15px);
font-weight: 600;
color: #166534;
line-height: 1.5;
}
.footer { font-size: 11px; color: #ccc; text-align: right; margin-top: 14px; }
</style>
</head>
<body>
<div class="card">
<div class="meeting-title" id="title"></div>
<div class="summary" id="summary"></div>
<div class="section" id="decisions-section">
<div class="section-label">Decisions</div>
<div id="decisions"></div>
</div>
<div class="section" id="actions-section">
<div class="section-label">Action Items</div>
<div id="actions"></div>
</div>
<div class="section">
<div class="section-label">Next Step</div>
<div class="next" id="next"></div>
</div>
<div class="footer">made on device with gemma</div>
</div>
<script>
const p = new URLSearchParams(window.location.search);
document.getElementById('title').textContent = p.get('title') || 'Meeting Summary';
document.getElementById('summary').textContent = p.get('summary') || '';
document.getElementById('next').textContent = p.get('next') || '';
const decisionsEl = document.getElementById('decisions');
[p.get('d1'), p.get('d2')].filter(Boolean).forEach(d => {
decisionsEl.innerHTML += `<div class="decision">${d}</div>`;
});
if (!decisionsEl.innerHTML) document.getElementById('decisions-section').style.display = 'none';
const actionsEl = document.getElementById('actions');
[[p.get('a1w'), p.get('a1t')], [p.get('a2w'), p.get('a2t')], [p.get('a3w'), p.get('a3t')]]
.filter(([w, t]) => w && t)
.forEach(([who, what]) => {
actionsEl.innerHTML += `<div class="action"><span class="who">${who}</span><span class="what">${what}</span></div>`;
});
</script>
</body>
</html>
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Meeting Notes</title></head>
<body>
<script>
window['ai_edge_gallery_get_result'] = async (data) => {
const d = JSON.parse(data);
return JSON.stringify({
webview: {
url: `../assets/webview.html?title=${encodeURIComponent(d.title)}&summary=${encodeURIComponent(d.summary)}&d1=${encodeURIComponent(d.decision1||'')}&d2=${encodeURIComponent(d.decision2||'')}&a1w=${encodeURIComponent(d.action1_who)}&a1t=${encodeURIComponent(d.action1_what)}&a2w=${encodeURIComponent(d.action2_who||'')}&a2t=${encodeURIComponent(d.action2_what||'')}&a3w=${encodeURIComponent(d.action3_who||'')}&a3t=${encodeURIComponent(d.action3_what||'')}&next=${encodeURIComponent(d.next_step)}`
}
});
};
</script>
</body>
</html>
+34
View File
@@ -0,0 +1,34 @@
---
name: pricing-advisor
description: Describe your product and target customer, get a pricing strategy with three tiers and rationale.
---
# Pricing Advisor
Stop guessing your price. Describe what you built and who it's for — get a concrete pricing structure with the reasoning behind it.
## Examples
* "SaaS tool for freelancers that automates invoicing, early stage"
* "Mobile app for fitness tracking, subscription model, targeting gym-goers"
* "API service for developers that does image compression, usage-based"
* "Online course about marketing for small business owners"
* "B2B software for restaurant inventory management"
## Instructions
You MUST use the `run_js` tool with the following exact parameters:
- data: A JSON string with the following fields:
- product: String - short description of the product
- model: String - recommended pricing model (e.g. subscription, one-time, usage-based, freemium)
- tier1_name: String - name for the entry tier (e.g. Starter, Free, Basic)
- tier1_price: String - price for tier 1 with period (e.g. $9/mo, Free, $49 one-time)
- tier1_for: String - who this tier is for in 5 words or less
- tier2_name: String - name for the mid tier (e.g. Pro, Growth, Standard)
- tier2_price: String - price for tier 2
- tier2_for: String - who this tier is for in 5 words or less
- tier3_name: String - name for the top tier (e.g. Team, Business, Enterprise)
- tier3_price: String - price for tier 3
- tier3_for: String - who this tier is for in 5 words or less
- rationale: String - one sentence explaining the key pricing logic or anchor strategy
@@ -0,0 +1,126 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pricing Advisor</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #09090b;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
color: #fafafa;
min-height: 100vh;
display: flex;
align-items: flex-start;
justify-content: center;
padding: 6%;
}
.card { width: 100%; }
.product {
font-size: clamp(16px, 4.5vw, 22px);
font-weight: 700;
margin-bottom: 4px;
}
.model-badge {
display: inline-block;
padding: 3px 10px;
border-radius: 20px;
font-size: 11px;
font-weight: 600;
background: #18181b;
color: #a1a1aa;
border: 1px solid #27272a;
margin-bottom: 18px;
}
.tiers { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; }
.tier {
background: #18181b;
border: 1px solid #27272a;
border-radius: 12px;
padding: 14px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
}
.tier.highlight {
border-color: #3f3f46;
background: #1c1c1f;
}
.tier-left { flex: 1; min-width: 0; }
.tier-name {
font-size: clamp(14px, 4vw, 17px);
font-weight: 700;
color: #fafafa;
margin-bottom: 3px;
}
.tier-for {
font-size: clamp(11px, 3vw, 13px);
color: #71717a;
}
.tier-price {
font-size: clamp(16px, 4.5vw, 22px);
font-weight: 800;
color: #fafafa;
white-space: nowrap;
text-align: right;
}
.rationale {
background: #18181b;
border-radius: 8px;
padding: 12px;
font-size: clamp(12px, 3vw, 14px);
color: #71717a;
line-height: 1.6;
font-style: italic;
}
.rationale-label {
font-size: 10px;
font-weight: 700;
letter-spacing: 1px;
text-transform: uppercase;
color: #52525b;
margin-bottom: 4px;
font-style: normal;
}
.footer { font-size: 11px; color: #27272a; text-align: right; margin-top: 12px; }
</style>
</head>
<body>
<div class="card">
<div class="product" id="product"></div>
<div class="model-badge" id="model"></div>
<div class="tiers" id="tiers"></div>
<div class="rationale">
<div class="rationale-label">Strategy</div>
<span id="rationale"></span>
</div>
<div class="footer">made on device with gemma</div>
</div>
<script>
const p = new URLSearchParams(window.location.search);
document.getElementById('product').textContent = p.get('product') || '';
document.getElementById('model').textContent = p.get('model') || '';
document.getElementById('rationale').textContent = p.get('rationale') || '';
const tiers = [
{ name: p.get('t1n'), price: p.get('t1p'), for: p.get('t1f') },
{ name: p.get('t2n'), price: p.get('t2p'), for: p.get('t2f'), highlight: true },
{ name: p.get('t3n'), price: p.get('t3p'), for: p.get('t3f') },
];
const tiersEl = document.getElementById('tiers');
tiers.forEach(t => {
if (!t.name) return;
tiersEl.innerHTML += `
<div class="tier${t.highlight ? ' highlight' : ''}">
<div class="tier-left">
<div class="tier-name">${t.name}</div>
<div class="tier-for">${t.for}</div>
</div>
<div class="tier-price">${t.price}</div>
</div>`;
});
</script>
</body>
</html>
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Pricing Advisor</title></head>
<body>
<script>
window['ai_edge_gallery_get_result'] = async (data) => {
const d = JSON.parse(data);
return JSON.stringify({
webview: {
url: `../assets/webview.html?product=${encodeURIComponent(d.product)}&model=${encodeURIComponent(d.model)}&t1n=${encodeURIComponent(d.tier1_name)}&t1p=${encodeURIComponent(d.tier1_price)}&t1f=${encodeURIComponent(d.tier1_for)}&t2n=${encodeURIComponent(d.tier2_name)}&t2p=${encodeURIComponent(d.tier2_price)}&t2f=${encodeURIComponent(d.tier2_for)}&t3n=${encodeURIComponent(d.tier3_name)}&t3p=${encodeURIComponent(d.tier3_price)}&t3f=${encodeURIComponent(d.tier3_for)}&rationale=${encodeURIComponent(d.rationale)}`
}
});
};
</script>
</body>
</html>
+28
View File
@@ -0,0 +1,28 @@
---
name: regex-builder
description: Describe a text pattern in plain English and get a working regular expression with an explanation.
---
# Regex Builder
Turn plain English into a working regex. No regex knowledge required.
## Examples
* "Match email addresses"
* "Find all phone numbers in format 555-123-4567"
* "Match URLs that start with https"
* "Find words that start with capital letters"
* "Match dates in MM/DD/YYYY format"
## Instructions
You MUST use the `run_js` tool with the following exact parameters:
- data: A JSON string with the following fields:
- description: String - the plain English description of the pattern
- regex: String - the regular expression pattern (without surrounding slashes)
- flags: String - regex flags like g, i, m (or empty string)
- explanation: String - plain English explanation of how the regex works
- example_match: String - one example string that this regex would match
- example_no_match: String - one example string that this regex would NOT match
@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Regex Builder</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #0d1117;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
color: #e6edf3;
min-height: 100vh;
display: flex;
align-items: flex-start;
justify-content: center;
padding: 6%;
}
.card { width: 100%; }
.label {
font-size: 10px;
font-weight: 700;
letter-spacing: 1px;
text-transform: uppercase;
color: #484f58;
margin-bottom: 6px;
}
.description {
font-size: clamp(15px, 4vw, 18px);
font-weight: 600;
color: #e6edf3;
margin-bottom: 18px;
line-height: 1.4;
}
.regex-box {
background: #161b22;
border: 1px solid #f78166;
border-radius: 10px;
padding: 16px;
margin-bottom: 16px;
display: flex;
align-items: center;
gap: 8px;
}
.slash { color: #f78166; font-size: 22px; font-family: monospace; }
.regex-text {
font-family: 'Courier New', monospace;
font-size: clamp(14px, 4vw, 20px);
color: #7ee787;
word-break: break-all;
flex: 1;
}
.flags { color: #f78166; font-family: monospace; font-size: 18px; }
.explanation {
background: #161b22;
border-radius: 10px;
padding: 14px;
font-size: clamp(13px, 3.5vw, 15px);
color: #8b949e;
line-height: 1.6;
margin-bottom: 14px;
}
.examples { display: flex; gap: 10px; margin-bottom: 14px; }
.ex-card {
flex: 1;
background: #161b22;
border-radius: 8px;
padding: 10px;
}
.ex-card .label { margin-bottom: 4px; }
.ex-match { border-top: 2px solid #3fb950; }
.ex-nomatch { border-top: 2px solid #f85149; }
.ex-text {
font-family: monospace;
font-size: clamp(11px, 3vw, 13px);
word-break: break-all;
}
.ex-match .ex-text { color: #3fb950; }
.ex-nomatch .ex-text { color: #f85149; }
.footer { font-size: 11px; color: #484f58; text-align: right; margin-top: 4px; }
</style>
</head>
<body>
<div class="card">
<div class="label">Pattern for</div>
<div class="description" id="description"></div>
<div class="regex-box">
<span class="slash">/</span>
<span class="regex-text" id="regex"></span>
<span class="slash">/</span>
<span class="flags" id="flags"></span>
</div>
<div class="explanation" id="explanation"></div>
<div class="examples">
<div class="ex-card ex-match">
<div class="label">Matches</div>
<div class="ex-text" id="match"></div>
</div>
<div class="ex-card ex-nomatch">
<div class="label">No match</div>
<div class="ex-text" id="nomatch"></div>
</div>
</div>
<div class="footer">made on device with gemma</div>
</div>
<script>
const p = new URLSearchParams(window.location.search);
document.getElementById('description').textContent = p.get('description') || '';
document.getElementById('regex').textContent = p.get('regex') || '';
document.getElementById('flags').textContent = p.get('flags') || '';
document.getElementById('explanation').textContent = p.get('explanation') || '';
document.getElementById('match').textContent = p.get('match') || '';
document.getElementById('nomatch').textContent = p.get('nomatch') || '';
</script>
</body>
</html>
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Regex Builder</title></head>
<body>
<script>
window['ai_edge_gallery_get_result'] = async (data) => {
const d = JSON.parse(data);
return JSON.stringify({
webview: {
url: `../assets/webview.html?description=${encodeURIComponent(d.description)}&regex=${encodeURIComponent(d.regex)}&flags=${encodeURIComponent(d.flags||'')}&explanation=${encodeURIComponent(d.explanation)}&match=${encodeURIComponent(d.example_match)}&nomatch=${encodeURIComponent(d.example_no_match)}`
}
});
};
</script>
</body>
</html>
+26
View File
@@ -0,0 +1,26 @@
---
name: standup-summary
description: Tell Gemma what you did, what you're working on, and any blockers. Get a clean standup update.
---
# Standup Summary
Format your daily standup in seconds. Works for async standups, Slack updates, and team check-ins.
## Examples
* "finished the auth flow, working on dashboard today, no blockers"
* "reviewed 3 PRs yesterday, today finishing the API integration, blocked on credentials from devops"
* "wrote blog post draft, need to edit and publish today, waiting on design assets"
* "fixed 2 bugs, implementing search feature today, no blockers but might need help with indexing"
## Instructions
You MUST use the `run_js` tool with the following exact parameters:
- data: A JSON string with the following fields:
- yesterday: String - what was completed yesterday (one clear sentence)
- today: String - what will be worked on today (one clear sentence)
- blocker: String - any blockers or dependencies, or "No blockers" if none
- eta: String - estimated completion or milestone if relevant, or empty string
- mood: String - one word energy level: focused, energized, tired, steady, or blocked
@@ -0,0 +1,118 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Standup Summary</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #111827;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
color: #f9fafb;
min-height: 100vh;
display: flex;
align-items: flex-start;
justify-content: center;
padding: 6%;
}
.card { width: 100%; }
.top-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20px;
}
.title { font-size: clamp(16px, 4.5vw, 22px); font-weight: 700; }
.mood {
padding: 4px 12px;
border-radius: 20px;
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.focused { background: #1e3a5f; color: #60a5fa; }
.energized { background: #1a3326; color: #34d399; }
.tired { background: #3b2a1a; color: #fb923c; }
.steady { background: #1f2937; color: #9ca3af; }
.blocked { background: #3b1a1a; color: #f87171; }
.row {
background: #1f2937;
border-radius: 10px;
padding: 14px;
margin-bottom: 10px;
}
.row-label {
font-size: 10px;
font-weight: 700;
letter-spacing: 1px;
text-transform: uppercase;
margin-bottom: 6px;
display: flex;
align-items: center;
gap: 6px;
}
.row-label .icon { font-size: 14px; }
.yesterday .row-label { color: #9ca3af; }
.today .row-label { color: #60a5fa; }
.blocker-row .row-label { color: #f87171; }
.eta-row .row-label { color: #a78bfa; }
.row-text {
font-size: clamp(13px, 3.5vw, 16px);
line-height: 1.6;
color: #e5e7eb;
}
.footer { font-size: 11px; color: #374151; text-align: right; margin-top: 10px; }
</style>
</head>
<body>
<div class="card">
<div class="top-row">
<div class="title">Daily Standup</div>
<div class="mood" id="mood"></div>
</div>
<div class="row yesterday">
<div class="row-label"><span class="icon"></span> Yesterday</div>
<div class="row-text" id="yesterday"></div>
</div>
<div class="row today">
<div class="row-label"><span class="icon"></span> Today</div>
<div class="row-text" id="today"></div>
</div>
<div class="row blocker-row" id="blocker-row">
<div class="row-label"><span class="icon"></span> Blocker</div>
<div class="row-text" id="blocker"></div>
</div>
<div class="row eta-row" id="eta-row">
<div class="row-label"><span class="icon"></span> ETA</div>
<div class="row-text" id="eta"></div>
</div>
<div class="footer">made on device with gemma</div>
</div>
<script>
const p = new URLSearchParams(window.location.search);
const mood = p.get('mood') || 'steady';
const moodEl = document.getElementById('mood');
moodEl.textContent = mood;
moodEl.className = 'mood ' + mood.toLowerCase();
document.getElementById('yesterday').textContent = p.get('yesterday') || '';
document.getElementById('today').textContent = p.get('today') || '';
const blocker = p.get('blocker') || '';
if (blocker && blocker.toLowerCase() !== 'no blockers') {
document.getElementById('blocker').textContent = blocker;
} else {
document.getElementById('blocker-row').style.display = 'none';
}
const eta = p.get('eta') || '';
if (eta) {
document.getElementById('eta').textContent = eta;
} else {
document.getElementById('eta-row').style.display = 'none';
}
</script>
</body>
</html>
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Standup Summary</title></head>
<body>
<script>
window['ai_edge_gallery_get_result'] = async (data) => {
const d = JSON.parse(data);
return JSON.stringify({
webview: {
url: `../assets/webview.html?yesterday=${encodeURIComponent(d.yesterday)}&today=${encodeURIComponent(d.today)}&blocker=${encodeURIComponent(d.blocker)}&eta=${encodeURIComponent(d.eta||'')}&mood=${encodeURIComponent(d.mood)}`
}
});
};
</script>
</body>
</html>