promptlean / contribute.html
kishormorol's picture
Sync from GitHub b5e4ac2
8a31f89 verified
Raw History Blame Contribute Delete
19.6 kB
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="favicon.svg">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Contribute — PromptLean</title>
<meta name="description" content="Add your prompts to PromptLean. Guidelines, schema, and review process.">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/main.css">
</head>
<body>
<nav>
<div class="nav-inner">
<a href="index.html" class="nav-logo">
<img src="assets/img/logo.svg" alt="PromptLean" class="nav-logo-icon" style="border-radius:7px;">
PromptLean
</a>
<div class="nav-links">
<a href="browse.html" class="nav-link">Browse</a>
<a href="compare.html" class="nav-link">Compare</a>
<a href="about.html" class="nav-link">About</a>
<a href="contribute.html" class="nav-link active">Contribute</a>
</div>
<div class="nav-actions">
<a href="https://github.com/kishormorol/promptlean" target="_blank" rel="noopener" class="github-star-btn">
<svg viewBox="0 0 16 16" fill="currentColor"><path d="M8 .25a7.75 7.75 0 1 0 0 15.5A7.75 7.75 0 0 0 8 .25Zm0 1.5a6.25 6.25 0 1 1 0 12.5A6.25 6.25 0 0 1 8 1.75Zm-.25 3.25a.75.75 0 0 1 .5 0l.963 2.97 3.124.022a.75.75 0 0 1 .44 1.354l-2.527 1.82.972 2.95a.75.75 0 0 1-1.154.838L8 12.845l-2.068 1.414a.75.75 0 0 1-1.154-.838l.972-2.95-2.527-1.82a.75.75 0 0 1 .44-1.354l3.124-.022L7.75 5Z"/></svg>
<span>Star</span><span class="gh-star-sep">|</span><span id="gh-stars"></span>
</a>
<button class="theme-toggle" id="theme-toggle" title="Toggle theme">☀</button>
</div>
</div>
</nav>
<main class="page-content">
<div class="container" style="max-width: 760px;">
<div class="mb-8">
<h1 style="font-size: 2rem; margin-bottom: 10px;">Contribute a Prompt</h1>
<p style="font-size: 1.0625rem;">Every prompt in the library came from someone who needed it. Open a PR with yours.</p>
</div>
<div class="divider"></div>
<!-- Steps -->
<div class="mb-8">
<h2 style="font-size: 1.25rem; margin-bottom: 16px;">How to contribute</h2>
<div style="display: flex; flex-direction: column; gap: 12px;">
<div class="card" style="display: flex; gap: 16px; align-items: flex-start;">
<div style="min-width: 32px; height: 32px; background: var(--accent-bg); border: 1px solid var(--accent-border); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--accent-light); font-size: 0.875rem;">1</div>
<div>
<div style="font-weight: 600; margin-bottom: 4px;">Fork the repo</div>
<p style="font-size: 0.875rem;"><a href="https://github.com/kishormorol/promptlean" target="_blank">github.com/kishormorol/promptlean</a> — fork, then clone to your machine.</p>
</div>
</div>
<div class="card" style="display: flex; gap: 16px; align-items: flex-start;">
<div style="min-width: 32px; height: 32px; background: var(--accent-bg); border: 1px solid var(--accent-border); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--accent-light); font-size: 0.875rem;">2</div>
<div>
<div style="font-weight: 600; margin-bottom: 4px;">Add your prompt to <code class="mono">data/prompts.json</code></div>
<p style="font-size: 0.875rem;">Follow the schema below. All three variants are required. Use <code class="mono">[PLACEHOLDER]</code> syntax for user-filled values.</p>
</div>
</div>
<div class="card" style="display: flex; gap: 16px; align-items: flex-start;">
<div style="min-width: 32px; height: 32px; background: var(--accent-bg); border: 1px solid var(--accent-border); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--accent-light); font-size: 0.875rem;">3</div>
<div>
<div style="font-weight: 600; margin-bottom: 4px;">Open a pull request</div>
<p style="font-size: 0.875rem;">Title: <code class="mono">feat: add "[Your Prompt Title]" to [Category]</code>. Include the output from at least one model in the PR description.</p>
</div>
</div>
</div>
</div>
<div class="divider"></div>
<!-- Prompt Builder -->
<div class="mb-8">
<h2 style="font-size: 1.25rem; margin-bottom: 6px;">Prompt Builder</h2>
<p style="margin-bottom: 20px;">Fill in the form — the correct JSON is generated automatically. Copy it into <code class="mono">data/prompts.json</code>.</p>
<div class="card" style="display: flex; flex-direction: column; gap: 16px;">
<!-- Row 1: title + category -->
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px;">
<div class="builder-field">
<label class="builder-label">Title</label>
<input class="builder-input" id="bf-title" placeholder="e.g. Write a SQL Migration" />
</div>
<div class="builder-field">
<label class="builder-label">Category</label>
<select class="builder-input" id="bf-category">
<option>Code</option>
<option>Data</option>
<option>Research</option>
<option>Writing</option>
<option>AI / ML</option>
<option>Productivity</option>
<option>Engineering</option>
<option>General Purpose</option>
<option>Well-being &amp; Mental Health</option>
<option>Safety &amp; Crisis Support</option>
<option>Supportive Conversation</option>
<option>Entertainment &amp; Creative</option>
<option>Education &amp; Tutoring</option>
<option>Career &amp; Professional Growth</option>
</select>
</div>
</div>
<!-- Row 2: tags + description -->
<div class="builder-field">
<label class="builder-label">Tags <span style="font-weight:400;color:var(--text-3);">(comma-separated, lowercase)</span></label>
<input class="builder-input" id="bf-tags" placeholder="e.g. sql, migration, database" />
</div>
<div class="builder-field">
<label class="builder-label">Description <span style="font-weight:400;color:var(--text-3);">(one sentence)</span></label>
<input class="builder-input" id="bf-desc" placeholder="What does this prompt do and when should someone use it?" />
</div>
<!-- Row 3: variants -->
<div style="display: grid; grid-template-columns: 1fr; gap: 12px;">
<div class="builder-field">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;">
<label class="builder-label" style="margin:0;">⚡ Lean prompt</label>
<span class="builder-token-count" id="bf-lean-count">0t</span>
</div>
<textarea class="builder-input builder-textarea" id="bf-lean" placeholder="Shortest effective prompt. Use [PLACEHOLDER] for user content." rows="3"></textarea>
</div>
<div class="builder-field">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;">
<label class="builder-label" style="margin:0;">⚖ Balanced prompt</label>
<span class="builder-token-count" id="bf-balanced-count">0t</span>
</div>
<textarea class="builder-input builder-textarea" id="bf-balanced" placeholder="Structured prompt with consistent format." rows="4"></textarea>
</div>
<div class="builder-field">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;">
<label class="builder-label" style="margin:0;">★ Max Quality prompt</label>
<span class="builder-token-count" id="bf-quality-count">0t</span>
</div>
<textarea class="builder-input builder-textarea" id="bf-quality" placeholder="Full rubric for external deliverables or expert review." rows="6"></textarea>
</div>
</div>
</div>
<!-- Generated JSON output -->
<div class="prompt-block" style="margin-top: 16px;">
<div class="prompt-block-header">
<div class="prompt-block-meta">
<span class="badge badge-cat">Generated JSON</span>
<span style="font-size:0.75rem;color:var(--text-3);">model_notes &amp; benchmarks need manual completion</span>
</div>
<button class="copy-btn" id="copy-builder-btn" onclick="copyBuilderJson()">⧉ Copy</button>
</div>
<pre class="prompt-text" id="builder-output" style="max-height:360px;overflow-y:auto;">{
"id": "your-prompt-id",
...
}</pre>
</div>
</div>
<div class="divider"></div>
<!-- Schema -->
<div class="mb-8">
<h2 style="font-size: 1.25rem; margin-bottom: 16px;">JSON Schema</h2>
<div class="prompt-block">
<div class="prompt-block-header">
<div class="prompt-block-meta">
<span class="badge badge-cat">data/prompts.json</span>
</div>
<button class="copy-btn" onclick="copySchema()">⧉ Copy</button>
</div>
<pre class="prompt-text" id="schema-block">{
"id": "your-prompt-id", // kebab-case, unique
"title": "Your Prompt Title",
"category": "Code", // Code | Data | Research | Writing | AI/ML | Productivity | Engineering
"tags": ["tag1", "tag2"], // 3–6 lowercase tags
"featured": false, // leave false; maintainers set this
"description": "One sentence describing what this prompt does and when to use it.",
"model_notes": {
"gpt-5.4": "...",
"claude-sonnet-4-6": "...",
"claude-opus-4-6": "...",
"gemini-3.1-pro": "...",
"grok-4": "...",
"llama-4-scout": "...",
"mistral-large-3": "...",
"o1": "..."
},
"variants": {
"lean": {
"prompt": "Your lean prompt here. Use [PLACEHOLDER] for user content.",
"token_estimate": 28 // count with tiktoken or similar
},
"balanced": {
"prompt": "Your balanced prompt here.",
"token_estimate": 72
},
"max_quality": {
"prompt": "Your max quality prompt here.",
"token_estimate": 165
}
}
}</pre>
</div>
</div>
<div class="divider"></div>
<!-- Guidelines -->
<div class="mb-8">
<h2 style="font-size: 1.25rem; margin-bottom: 16px;">Contribution guidelines</h2>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">
<div>
<div style="color: var(--lean); font-weight: 600; margin-bottom: 10px; font-size: 0.875rem;">✓ We accept</div>
<ul style="font-size: 0.875rem; color: var(--text-2); line-height: 2.1; padding-left: 18px;">
<li>Task-focused prompts with real-world use cases</li>
<li>Prompts you've actually used in production or research</li>
<li>Variants that meaningfully differ in token cost and quality</li>
<li>New categories not yet represented</li>
<li>Improvements to existing prompts (open an issue first)</li>
</ul>
</div>
<div>
<div style="color: var(--quality); font-weight: 600; margin-bottom: 10px; font-size: 0.875rem;">✗ We decline</div>
<ul style="font-size: 0.875rem; color: var(--text-2); line-height: 2.1; padding-left: 18px;">
<li>Prompts that generate harmful or deceptive content</li>
<li>Jailbreaks or prompt injection exploits</li>
<li>Vanity prompts with no clear use case</li>
<li>Duplicates of existing prompts</li>
<li>Lean variants that are just truncated max-quality prompts</li>
</ul>
</div>
</div>
</div>
<div class="divider"></div>
<!-- Quality bar -->
<div class="mb-8">
<h2 style="font-size: 1.25rem; margin-bottom: 12px;">Quality bar for variants</h2>
<p style="margin-bottom: 12px;">The three variants should feel genuinely different — not just shorter versions of the same prompt. The quality difference should be real and measurable.</p>
<div class="card">
<div class="flex-center gap-2 mb-3">
<span class="badge badge-lean">⚡ Lean</span>
</div>
<p style="font-size: 0.875rem;">Should produce a usable output with no wasted tokens. If the lean prompt gets 80%+ of the max-quality output, that's a good lean variant.</p>
</div>
<div class="card" style="margin-top: 12px;">
<div class="flex-center gap-2 mb-3">
<span class="badge badge-quality">★ Max Quality</span>
</div>
<p style="font-size: 0.875rem;">Should produce output that a human expert would rate noticeably higher than the lean variant. If the output is indistinguishable, the max-quality variant is not doing its job.</p>
</div>
</div>
<div class="divider"></div>
<!-- Community variants -->
<div class="mb-8" id="community">
<h2 style="font-size: 1.25rem; margin-bottom: 6px;">Community Variants</h2>
<p style="margin-bottom: 16px;">Have a specialized take on an existing prompt? Add it as a community variant — it shows up as an extra tab on the prompt page without replacing the standard ones.</p>
<div class="card mb-4">
<div style="font-weight: 600; margin-bottom: 10px; font-size: 0.9rem;">How it works</div>
<ol style="font-size: 0.875rem; color: var(--text-2); padding-left: 20px; line-height: 2.2;">
<li>Fork the repo and create <code class="mono">community/{prompt-id}.json</code></li>
<li>Add your variant(s) as a JSON array (schema below)</li>
<li>Open a PR — include example output from at least one model</li>
</ol>
<p style="font-size: 0.8125rem; color: var(--text-3); margin-top: 10px;">
Example: to add a variant for the <em>Code Review</em> prompt, create <code class="mono">community/code-review.json</code>.
</p>
</div>
<div class="prompt-block">
<div class="prompt-block-header">
<span class="badge badge-cat">community/{prompt-id}.json</span>
<button class="copy-btn" onclick="copyCommunitySchema()">⧉ Copy</button>
</div>
<pre class="prompt-text" id="community-schema">[
{
"id": "your-variant-id", // kebab-case, unique within this prompt
"label": "🔒 Your Variant Name", // shown in the tab — keep it short
"author": "your-github-username",
"description": "One sentence: what does this variant optimize for?",
"prompt": "Your specialized prompt text. Use [PLACEHOLDER] for user content.",
"token_estimate": 95 // rough count; use chars/4 as approximation
}
]</pre>
</div>
</div>
<div style="text-align: center; padding: 20px 0;">
<a href="https://github.com/kishormorol/promptlean" class="btn btn-primary btn-lg" target="_blank">Open GitHub →</a>
</div>
</div>
</main>
<footer>
<div class="footer-inner">
<div class="footer-left">
<span>⚡ PromptLean</span>
<span>·</span>
<span>Open source, MIT license</span>
</div>
<div class="footer-links">
<a href="about.html" class="footer-link">About</a>
<a href="contribute.html" class="footer-link">Contribute</a>
<a href="https://github.com/kishormorol/promptlean/blob/main/ATTRIBUTION.md" class="footer-link" target="_blank">Attribution</a>
<a href="https://github.com/kishormorol/promptlean" class="footer-link" target="_blank">GitHub</a>
</div>
</div>
</footer>
<div id="toast"></div>
<script src="assets/js/main.js"></script>
<script>
window.copySchema = () => {
const text = document.getElementById('schema-block').textContent;
PL.copy(text);
};
window.copyCommunitySchema = () => {
const text = document.getElementById('community-schema').textContent;
PL.copy(text);
};
window.copyBuilderJson = () => {
const text = document.getElementById('builder-output').textContent;
PL.copy(text, document.getElementById('copy-builder-btn'));
};
(function initBuilder() {
const MODELS = ['gpt-5.4','claude-sonnet-4-6','claude-opus-4-6','gemini-3.1-pro','grok-4','llama-4-scout','mistral-large-3','o1'];
const toSlug = (s) => s.toLowerCase().replace(/[^a-z0-9\s-]/g,'').trim().replace(/\s+/g,'-');
const estimateTokens = (s) => Math.max(1, Math.ceil((s.trim().length || 0) / 4));
const updateCount = (textareaId, countId) => {
const text = document.getElementById(textareaId)?.value || '';
const el = document.getElementById(countId);
if (el) el.textContent = estimateTokens(text) + 't';
};
const generateJson = () => {
const title = (document.getElementById('bf-title')?.value || '').trim();
const category = document.getElementById('bf-category')?.value || 'Code';
const tagsRaw = document.getElementById('bf-tags')?.value || '';
const desc = (document.getElementById('bf-desc')?.value || '').trim();
const leanP = document.getElementById('bf-lean')?.value || '';
const balP = document.getElementById('bf-balanced')?.value || '';
const qualP = document.getElementById('bf-quality')?.value || '';
const id = toSlug(title) || 'your-prompt-id';
const tags = tagsRaw.split(',').map(t => t.trim().toLowerCase()).filter(Boolean);
const modelNotes = {};
MODELS.forEach(m => { modelNotes[m] = 'Add notes about how this model handles this prompt type.'; });
const benchmarks = {};
MODELS.forEach(m => { benchmarks[m] = { lean: 4, balanced: 4, max_quality: 5, best: 'balanced' }; });
const obj = {
id,
title: title || 'Your Prompt Title',
category,
tags: tags.length ? tags : ['tag1', 'tag2'],
featured: false,
description: desc || 'One sentence describing what this prompt does and when to use it.',
model_notes: modelNotes,
benchmarks,
variants: {
lean: { prompt: leanP || 'Your lean prompt here. Use [PLACEHOLDER] for user content.', token_estimate: estimateTokens(leanP || 'placeholder') },
balanced: { prompt: balP || 'Your balanced prompt here.', token_estimate: estimateTokens(balP || 'placeholder') },
max_quality: { prompt: qualP || 'Your max quality prompt here.', token_estimate: estimateTokens(qualP || 'placeholder') }
}
};
return JSON.stringify(obj, null, 2);
};
const refresh = () => {
updateCount('bf-lean', 'bf-lean-count');
updateCount('bf-balanced', 'bf-balanced-count');
updateCount('bf-quality', 'bf-quality-count');
const out = document.getElementById('builder-output');
if (out) out.textContent = generateJson();
};
document.addEventListener('DOMContentLoaded', () => {
['bf-title','bf-category','bf-tags','bf-desc','bf-lean','bf-balanced','bf-quality']
.forEach(id => document.getElementById(id)?.addEventListener('input', refresh));
refresh();
});
})();
</script>
</body>
</html>