mirror of
https://github.com/f/awesome-chatgpt-prompts.git
synced 2026-02-12 15:52:47 +00:00
chore(scripts): add script to generate contributor commits
This commit is contained in:
24
README.md
24
README.md
@@ -11,12 +11,6 @@
|
||||
</a>
|
||||
<br>
|
||||
<sub>With Clemta, you can run your company from the comfort of your home.</sub>
|
||||
<hr>
|
||||
<a href="https://github.com/f/mcptools" align="center" target="_blank">
|
||||
<img height="60" alt="MCPTools logo" src="https://github.com/f/mcptools/raw/master/.github/resources/logo.png">
|
||||
</a>
|
||||
<br>
|
||||
<sub>If you're building MCPs, <a href="https://github.com/f/mcptools">MCP Tools</a> is a Swiss-army knife for MCP Servers.</sub>
|
||||
<hr>
|
||||
<sub><a href="https://github.com/sponsors/f/sponsorships?sponsor=f&tier_id=529895">Be my sponsor and your logo will be here!</a></sub>
|
||||
</div>
|
||||
@@ -26,19 +20,17 @@
|
||||
|
||||
Welcome to the "Awesome ChatGPT Prompts" repository! While this collection was originally created for [ChatGPT](https://chat.openai.com/chat), these prompts work great with other AI models like [Claude](https://claude.ai/new), [Gemini](https://gemini.google.com), [Hugging Face Chat](https://hf.co/chat), [Llama](https://meta.ai), [Mistral](https://chat.mistral.ai), and more.
|
||||
|
||||
[ChatGPT](https://chat.openai.com/chat) is a web interface created by [OpenAI](https://openai.com) that provides access to their GPT (Generative Pre-trained Transformer) language models. The underlying models, like GPT-4o and GPT-o1, are large language models trained on vast amounts of text data that can understand and generate human-like text. Like other AI chat interfaces, you can provide prompts and have natural conversations with the AI, which will generate contextual responses based on the conversation history and your inputs.
|
||||
In this repository, you will find a variety of [prompts](prompts.csv) that can be used with ChatGPT and other AI chat models. We encourage you to [add your own prompts](https://prompts.chat) to the list, and to use AI to help generate new prompts as well. Your contributions to [prompts.chat](https://prompts.chat) will be contributions to this repository automatically.
|
||||
|
||||
In this repository, you will find a variety of prompts that can be used with ChatGPT and other AI chat models. We encourage you to [add your own prompts](https://github.com/f/awesome-chatgpt-prompts/edit/main/README.md) to the list, and to use AI to help generate new prompts as well.
|
||||
## Want to deploy your own private prompt library for your team?
|
||||
|
||||
To get started, simply clone this repository and use the prompts in the README.md file as input for your preferred AI chat model. You can also use the prompts in this file as inspiration for creating your own.
|
||||
|
||||
Want to deploy your own private prompt library? Check out our [Self-Hosting Guide](SELF-HOSTING.md) for instructions on setting up your own instance with customizable branding, themes, and authentication.
|
||||
Check out our [Self-Hosting Guide](SELF-HOSTING.md) for instructions on setting up your own instance with **customizable branding, themes, and authentication**.
|
||||
|
||||
We hope you find these prompts useful and have fun exploring AI chat models!
|
||||
|
||||
**[View on prompts.chat](https://prompts.chat)**
|
||||
|
||||
**[View on Hugging Face](https://huggingface.co/datasets/fka/awesome-chatgpt-prompts/)**
|
||||
**[View Hugging Face Dataset](https://huggingface.co/datasets/fka/awesome-chatgpt-prompts/)**
|
||||
---
|
||||
|
||||
> ℹ️ **NOTE:** Sometimes, some of the prompts may not be working as you expected
|
||||
@@ -71,14 +63,6 @@ Images from Text"**.
|
||||
|
||||
---
|
||||
|
||||
### Using prompts.chat
|
||||
|
||||
[prompts.chat](https://prompts.chat) is designed to provide an enhanced UX when
|
||||
working with prompts. With just a few clicks, you can easily edit and copy the
|
||||
prompts on the site to fit your specific needs and preferences. And contribute your own prompts to help build a better community.
|
||||
|
||||
---
|
||||
|
||||
## Unmerged Prompts
|
||||
|
||||
There are many Pull Requests to this repository waiting to be merged. There are
|
||||
|
||||
89
scripts/generate-contributors.sh
Executable file
89
scripts/generate-contributors.sh
Executable file
@@ -0,0 +1,89 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to generate contributor commits from prompts.csv
|
||||
# Each contributor will have one commit attributed to them so they appear in GitHub's contributors list
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
CSV_FILE="$PROJECT_DIR/prompts.csv"
|
||||
CONTRIBUTORS_FILE="$PROJECT_DIR/CONTRIBUTORS.md"
|
||||
|
||||
if [ ! -f "$CSV_FILE" ]; then
|
||||
echo "Error: prompts.csv not found at $CSV_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract unique contributors from CSV
|
||||
echo "Extracting contributors from prompts.csv..."
|
||||
|
||||
contributors=$(python3 -c "
|
||||
import csv
|
||||
contributors = set()
|
||||
with open('$CSV_FILE', 'r') as f:
|
||||
reader = csv.DictReader(f)
|
||||
for row in reader:
|
||||
if 'contributor' in row and row['contributor']:
|
||||
contributors.add(row['contributor'].strip())
|
||||
for c in sorted(contributors):
|
||||
print(c)
|
||||
")
|
||||
|
||||
# Count contributors
|
||||
count=$(echo "$contributors" | wc -l | tr -d ' ')
|
||||
echo "Found $count unique contributors"
|
||||
|
||||
# Generate CONTRIBUTORS.md file
|
||||
echo "# Contributors" > "$CONTRIBUTORS_FILE"
|
||||
echo "" >> "$CONTRIBUTORS_FILE"
|
||||
echo "Thank you to all the contributors who have helped make this project better!" >> "$CONTRIBUTORS_FILE"
|
||||
echo "" >> "$CONTRIBUTORS_FILE"
|
||||
|
||||
i=1
|
||||
while IFS= read -r username; do
|
||||
if [ -n "$username" ]; then
|
||||
echo "- [@$username](https://github.com/$username)" >> "$CONTRIBUTORS_FILE"
|
||||
fi
|
||||
done <<< "$contributors"
|
||||
|
||||
echo "" >> "$CONTRIBUTORS_FILE"
|
||||
echo "---" >> "$CONTRIBUTORS_FILE"
|
||||
echo "*This file is auto-generated from prompts.csv*" >> "$CONTRIBUTORS_FILE"
|
||||
|
||||
# Stage the file
|
||||
git add "$CONTRIBUTORS_FILE"
|
||||
|
||||
# Create commits for each contributor
|
||||
echo ""
|
||||
echo "Creating commits for each contributor..."
|
||||
|
||||
i=1
|
||||
while IFS= read -r username; do
|
||||
if [ -n "$username" ]; then
|
||||
email="${username}@users.noreply.github.com"
|
||||
|
||||
# Amend or create commit with contributor as author
|
||||
# We use --allow-empty to create empty commits if needed
|
||||
# Each contributor gets credited by adding their line specifically
|
||||
|
||||
# Create a unique change for this contributor
|
||||
echo "[$i/$count] Adding contributor: $username"
|
||||
|
||||
# Use git commit with author override
|
||||
GIT_AUTHOR_NAME="$username" \
|
||||
GIT_AUTHOR_EMAIL="$email" \
|
||||
GIT_COMMITTER_NAME="$username" \
|
||||
GIT_COMMITTER_EMAIL="$email" \
|
||||
git commit --allow-empty -m "Add prompt contribution from @$username" \
|
||||
--author="$username <$email>"
|
||||
|
||||
((i++))
|
||||
fi
|
||||
done <<< "$contributors"
|
||||
|
||||
echo ""
|
||||
echo "Done! Created $count contributor commits."
|
||||
echo "Review with: git log --oneline -n $count"
|
||||
echo ""
|
||||
echo "To push: git push origin main"
|
||||
@@ -1,208 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* This script parses README.md to extract contributor GitHub usernames
|
||||
* and updates prompts.csv to include a contributor column.
|
||||
*
|
||||
* Usage: node scripts/update-csv-contributors.js
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const README_PATH = path.join(__dirname, '..', 'README.md');
|
||||
const CSV_PATH = path.join(__dirname, '..', 'prompts.csv');
|
||||
|
||||
// Parse README.md to extract prompt titles and their contributors
|
||||
function parseReadme(content) {
|
||||
const promptContributors = new Map();
|
||||
|
||||
// Split by ## Act as headers
|
||||
const sections = content.split(/^## Act as /gmi);
|
||||
|
||||
for (let i = 1; i < sections.length; i++) {
|
||||
const section = sections[i];
|
||||
const lines = section.split('\n');
|
||||
|
||||
// First line is the title (after "Act as ")
|
||||
const titleLine = lines[0].trim();
|
||||
// Remove any markdown links or extra text after the title
|
||||
const title = titleLine.split('\n')[0].trim();
|
||||
|
||||
// Look for "Contributed by:" line
|
||||
const contributedLine = lines.find(line =>
|
||||
line.toLowerCase().includes('contributed by:')
|
||||
);
|
||||
|
||||
if (contributedLine) {
|
||||
// Extract GitHub usernames from [@username](https://github.com/username) pattern
|
||||
// Also handle [username](https://github.com/username) without @ prefix
|
||||
const usernameMatches = contributedLine.matchAll(/@?([a-zA-Z0-9_-]+)\]\(https?:\/\/github\.com\/[^)]+\)/gi);
|
||||
const usernames = [...usernameMatches].map(match => match[1].toLowerCase());
|
||||
|
||||
if (usernames.length > 0) {
|
||||
// Store all contributors, joined by comma (first one is primary for import)
|
||||
promptContributors.set(normalizeTitle(title), usernames.join(','));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return promptContributors;
|
||||
}
|
||||
|
||||
// Normalize title for matching (remove "an ", "a ", etc.)
|
||||
function normalizeTitle(title) {
|
||||
return title
|
||||
.replace(/^(an?\s+)/i, '')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
// Parse CSV content
|
||||
function parseCSV(content) {
|
||||
const lines = content.split('\n');
|
||||
const rows = [];
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
if (!line.trim()) continue;
|
||||
|
||||
// Parse CSV with proper handling of quoted fields
|
||||
const values = [];
|
||||
let current = '';
|
||||
let inQuotes = false;
|
||||
|
||||
for (let j = 0; j < line.length; j++) {
|
||||
const char = line[j];
|
||||
const nextChar = line[j + 1];
|
||||
|
||||
if (char === '"' && !inQuotes) {
|
||||
inQuotes = true;
|
||||
} else if (char === '"' && inQuotes) {
|
||||
if (nextChar === '"') {
|
||||
current += '"';
|
||||
j++;
|
||||
} else {
|
||||
inQuotes = false;
|
||||
}
|
||||
} else if (char === ',' && !inQuotes) {
|
||||
values.push(current);
|
||||
current = '';
|
||||
} else {
|
||||
current += char;
|
||||
}
|
||||
}
|
||||
values.push(current);
|
||||
|
||||
rows.push(values);
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
// Escape CSV field
|
||||
function escapeCSV(field) {
|
||||
if (field.includes(',') || field.includes('"') || field.includes('\n')) {
|
||||
return '"' + field.replace(/"/g, '""') + '"';
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
// Main function
|
||||
function main() {
|
||||
console.log('Reading README.md...');
|
||||
const readmeContent = fs.readFileSync(README_PATH, 'utf-8');
|
||||
|
||||
console.log('Parsing contributors from README.md...');
|
||||
const promptContributors = parseReadme(readmeContent);
|
||||
console.log(`Found ${promptContributors.size} prompts with contributors`);
|
||||
|
||||
console.log('\nReading prompts.csv...');
|
||||
const csvContent = fs.readFileSync(CSV_PATH, 'utf-8');
|
||||
const rows = parseCSV(csvContent);
|
||||
|
||||
// Check if contributor column already exists
|
||||
const header = rows[0];
|
||||
const hasContributorCol = header.includes('contributor');
|
||||
|
||||
if (!hasContributorCol) {
|
||||
header.push('contributor');
|
||||
}
|
||||
|
||||
// Trim header to only have 5 columns (act, prompt, for_devs, type, contributor)
|
||||
rows[0] = header.slice(0, 5);
|
||||
if (rows[0].length < 5) rows[0].push('contributor');
|
||||
|
||||
let matched = 0;
|
||||
let unmatched = [];
|
||||
|
||||
// Process each row
|
||||
for (let i = 1; i < rows.length; i++) {
|
||||
const row = rows[i];
|
||||
if (row.length < 1) continue;
|
||||
|
||||
const act = row[0].replace(/^"|"$/g, ''); // Remove surrounding quotes
|
||||
const normalizedAct = normalizeTitle(act);
|
||||
|
||||
// Try to find contributor
|
||||
let contributor = '';
|
||||
|
||||
// Direct match
|
||||
if (promptContributors.has(normalizedAct)) {
|
||||
contributor = promptContributors.get(normalizedAct);
|
||||
} else {
|
||||
// Try partial matching
|
||||
for (const [title, user] of promptContributors) {
|
||||
if (title.includes(normalizedAct) || normalizedAct.includes(title)) {
|
||||
contributor = user;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (contributor) {
|
||||
matched++;
|
||||
} else {
|
||||
unmatched.push(act);
|
||||
}
|
||||
|
||||
// Trim row to 4 columns and add contributor as 5th
|
||||
rows[i] = row.slice(0, 4);
|
||||
rows[i].push(contributor);
|
||||
}
|
||||
|
||||
console.log(`\nMatched ${matched} prompts with contributors`);
|
||||
if (unmatched.length > 0) {
|
||||
console.log(`\nUnmatched prompts (${unmatched.length}):`);
|
||||
unmatched.slice(0, 10).forEach(title => console.log(` - ${title}`));
|
||||
if (unmatched.length > 10) {
|
||||
console.log(` ... and ${unmatched.length - 10} more`);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate new CSV
|
||||
console.log('\nWriting updated prompts.csv...');
|
||||
const newCSV = rows.map(row => row.map(escapeCSV).join(',')).join('\n');
|
||||
fs.writeFileSync(CSV_PATH, newCSV);
|
||||
|
||||
console.log('Done!');
|
||||
|
||||
// Print some stats
|
||||
console.log('\n--- Contributor Stats ---');
|
||||
const contributorCounts = new Map();
|
||||
for (let i = 1; i < rows.length; i++) {
|
||||
const contributor = rows[i][rows[i].length - 1];
|
||||
if (contributor) {
|
||||
contributorCounts.set(contributor, (contributorCounts.get(contributor) || 0) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
const sorted = [...contributorCounts.entries()].sort((a, b) => b[1] - a[1]);
|
||||
console.log(`\nTop contributors:`);
|
||||
sorted.slice(0, 10).forEach(([user, count]) => {
|
||||
console.log(` @${user}: ${count} prompts`);
|
||||
});
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user