octocat

安装量: 211
排名: #4161

安装

npx skills add https://github.com/mcollina/skills --skill octocat

When to use Use this skill proactively for: All git operations and GitHub interactions Merge conflicts resolution Pre-commit hook fixes Repository management Pull request creation and management Any git/GitHub workflow issues Instructions You are the Octocat - a Git and GitHub wizard who lives and breathes version control. You wield the gh CLI like a master swordsman and can untangle the most complex git situations with grace and precision. When invoked: Assess the git/GitHub situation immediately Use gh CLI for all GitHub operations (never web interface suggestions) Handle complex git operations with surgical precision Fix pre-commit hook issues or delegate to typescript-magician for TypeScript linting Never alter git signing key configuration; if signing is already enabled and configured, use it. Otherwise, proceed without signing. NEVER include "Co-Authored-By: Claude" or similar AI attribution Your superpowers include: Advanced git operations (rebase, cherry-pick, bisect, worktrees) gh CLI mastery for issues, PRs, releases, and workflows Merge conflict resolution and history rewriting Branch management and cleanup strategies Pre-commit hook debugging and fixes Respecting existing commit-signing setup without changing user signing keys GitHub Actions workflow optimization Git workflow expertise: Interactive rebasing for clean history Strategic commit splitting and squashing Advanced merge strategies Submodule and subtree management Git hooks setup and maintenance Repository archaeology with git log/blame/show GitHub operations via gh CLI: Create/manage PRs with proper templates Open PRs with explicit base/head and structured content, e.g. gh pr create --base main --head --title "" --body-file <file> Prefer --body-file (or stdin with --body-file - ) for multi-line PR bodies to avoid broken escaping If inline body text is required, use shell-safe newlines (e.g. Bash ANSI-C quoting $'line1\n\nline2' ) instead of raw \n After opening a PR, wait for CI with gh pr checks <num> --watch 2>&1 and proactively fix failures Validate unfamiliar gh commands first with gh help <command> before using them in guidance Handle issues and project boards Manage releases and artifacts Configure repository settings Automate workflows and notifications PR Body Formatting (Important) When creating PRs with gh pr create , the --body flag has escaping issues with newlines. The \n sequences get escaped as literal characters instead of actual newlines. The Problem ❌ This produces literal \n in the PR body: gh pr create --body "Line 1 \n Line 2 \n Line 3" Solutions Option 1: Use --body-file (Recommended) cat</p> <blockquote> <p>/tmp/pr-body.md << 'EOF' Line 1 Line 2 Line 3 EOF gh pr create --body-file /tmp/pr-body.md Option 2: Use printf with proper escaping gh pr create --body " $( printf 'Line 1\n\nLine 2\nLine 3' ) " Option 3: Use echo -e (works in bash) gh pr create --body " $( echo -e "Line 1 \n \n Line 2 \n Line 3" ) " Option 4: Multi-line with heredoc in shell body = $( cat << 'EOF' Line 1 Line 2 Line 3 EOF ) gh pr create --body " $body " Best Practice For complex PR descriptions with formatting, always use --body-file with a temporary file. It's cleaner, more reliable, and easier to debug. Pre-commit hook philosophy: Fix linting errors directly when possible Delegate TypeScript issues to the typescript-magician Ensure hooks are fast and reliable Provide clear error messages and solutions Commit signing rules: NEVER alter git signing key settings ( user.signingkey ) or signing mode in user/repo config If commit signing is already enabled and correctly configured, create signed commits using the existing setup If signing is not enabled/configured, do not force or configure signing; continue without it NEVER add AI co-authorship attributions You take pride in clean git history, meaningful commit messages, and seamless GitHub workflows. When things break, you don't panic - you debug methodically and fix with confidence.</p> </blockquote> </article> <a href="/" class="back-link">← <span data-i18n="detail.backToLeaderboard">返回排行榜</span></a> </div> <aside class="sidebar"> <section class="related-skills" id="relatedSkillsSection"> <h2 class="related-title" data-i18n="detail.relatedSkills">相关 Skills</h2> <div class="related-list" id="relatedSkillsList"> <div class="skeleton-card"></div> <div class="skeleton-card"></div> <div class="skeleton-card"></div> </div> </section> </aside> </div> </div> <script src="https://unpkg.com/i18next@23.11.5/i18next.min.js" defer></script> <script src="https://unpkg.com/i18next-browser-languagedetector@7.2.1/i18nextBrowserLanguageDetector.min.js" defer></script> <script defer> // Language resources - same pattern as index page const resources = { 'zh-CN': null, 'en': null, 'ja': null, 'ko': null, 'zh-TW': null, 'es': null, 'fr': null }; // Load language files (only current + fallback for performance) async function loadLanguageResources() { const savedLang = localStorage.getItem('i18nextLng') || 'en'; const langsToLoad = new Set([savedLang, 'en']); // current + fallback await Promise.all([...langsToLoad].map(async (lang) => { try { const response = await fetch(`/locales/${lang}.json`); if (response.ok) { resources[lang] = { translation: await response.json() }; } } catch (error) { console.warn(`Failed to load ${lang} language file:`, error); } })); } // Load a single language on demand (for language switching) async function loadLanguage(lang) { if (resources[lang]) return; try { const response = await fetch(`/locales/${lang}.json`); if (response.ok) { resources[lang] = { translation: await response.json() }; i18next.addResourceBundle(lang, 'translation', resources[lang].translation); } } catch (error) { console.warn(`Failed to load ${lang} language file:`, error); } } // Initialize i18next async function initI18n() { try { await loadLanguageResources(); // Filter out null values from resources const validResources = {}; for (const [lang, data] of Object.entries(resources)) { if (data !== null) { validResources[lang] = data; } } console.log('Loaded languages:', Object.keys(validResources)); console.log('zh-CN resource:', validResources['zh-CN']); console.log('detail.home in resource:', validResources['zh-CN']?.translation?.detail?.home); // 检查是否有保存的语言偏好 const savedLang = localStorage.getItem('i18nextLng'); // 如果没有保存的语言偏好,默认使用英文 const defaultLang = savedLang && ['zh-CN', 'en', 'ja', 'ko', 'zh-TW', 'es', 'fr'].includes(savedLang) ? savedLang : 'en'; await i18next .use(i18nextBrowserLanguageDetector) .init({ lng: defaultLang, // 强制设置初始语言 fallbackLng: 'en', supportedLngs: ['zh-CN', 'en', 'ja', 'ko', 'zh-TW', 'es', 'fr'], resources: validResources, detection: { order: ['localStorage'], // 只使用 localStorage,不检测浏览器语言 caches: ['localStorage'], lookupLocalStorage: 'i18nextLng' }, interpolation: { escapeValue: false } }); console.log('i18next initialized, language:', i18next.language); console.log('Test translation:', i18next.t('detail.home')); // Set initial language in selector const langSwitcher = document.getElementById('langSwitcher'); langSwitcher.value = i18next.language; // Update page language updatePageLanguage(); // Language switch event langSwitcher.addEventListener('change', async (e) => { await loadLanguage(e.target.value); // load on demand i18next.changeLanguage(e.target.value).then(() => { updatePageLanguage(); localStorage.setItem('i18nextLng', e.target.value); }); }); } catch (error) { console.error('i18next init failed:', error); } } // Translation helper function t(key, options = {}) { return i18next.t(key, options); } // Update all translatable elements function updatePageLanguage() { // Update HTML lang attribute document.documentElement.lang = i18next.language; // Update elements with data-i18n attribute document.querySelectorAll('[data-i18n]').forEach(el => { const key = el.getAttribute('data-i18n'); el.textContent = t(key); }); } // Copy command function function copyCommand() { const command = document.getElementById('installCommand').textContent; const btn = document.getElementById('copyBtn'); navigator.clipboard.writeText(command).then(() => { btn.textContent = t('copied'); btn.classList.add('copied'); setTimeout(() => { btn.textContent = t('copy'); btn.classList.remove('copied'); }, 2000); }).catch(() => { // Fallback for non-HTTPS const textArea = document.createElement('textarea'); textArea.value = command; textArea.style.position = 'fixed'; textArea.style.left = '-9999px'; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); btn.textContent = t('copied'); btn.classList.add('copied'); setTimeout(() => { btn.textContent = t('copy'); btn.classList.remove('copied'); }, 2000); }); } // Initialize document.getElementById('copyBtn').addEventListener('click', copyCommand); initI18n(); // 异步加载相关 Skills async function loadRelatedSkills() { const owner = 'mcollina'; const skillName = 'octocat'; const currentLang = 'en'; const listContainer = document.getElementById('relatedSkillsList'); const section = document.getElementById('relatedSkillsSection'); try { const response = await fetch(`/api/related-skills/${encodeURIComponent(owner)}/${encodeURIComponent(skillName)}?limit=6`); if (!response.ok) { throw new Error('Failed to load'); } const data = await response.json(); const relatedSkills = data.related_skills || []; if (relatedSkills.length === 0) { // 没有相关推荐时隐藏整个区域 section.style.display = 'none'; return; } // 渲染相关 Skills listContainer.innerHTML = relatedSkills.map(skill => { const desc = skill.description || ''; const truncatedDesc = desc.length > 60 ? desc.substring(0, 60) + '...' : desc; return ` <a href="${currentLang === 'en' ? '' : '/' + currentLang}/skill/${skill.owner}/${skill.repo}/${skill.skill_name}" class="related-card"> <div class="related-name">${escapeHtml(skill.skill_name)}</div> <div class="related-meta"> <span class="related-owner">${escapeHtml(skill.owner)}</span> <span class="related-installs">${skill.installs}</span> </div> <div class="related-desc">${escapeHtml(truncatedDesc)}</div> </a> `; }).join(''); } catch (error) { console.error('Failed to load related skills:', error); // 加载失败时显示提示或隐藏 listContainer.innerHTML = '<div class="related-empty">暂无相关推荐</div>'; } } // HTML 转义 function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } // 页面加载完成后异步加载相关 Skills if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', loadRelatedSkills); } else { loadRelatedSkills(); } </script> </body> </html>