mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-21 15:55:50 +00:00
feat: 第一版可用 pokemon
This commit is contained in:
124
packages/pokemon/scripts/fetch-sprites.ts
Normal file
124
packages/pokemon/scripts/fetch-sprites.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* Script to pre-fetch all 10 MVP Pokémon sprites from GitHub.
|
||||
* Run: bun run packages/pokemon/scripts/fetch-sprites.ts
|
||||
*/
|
||||
import { writeFileSync, mkdirSync, existsSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
import { homedir } from 'node:os'
|
||||
|
||||
const GITHUB_RAW_BASE = 'https://raw.githubusercontent.com/HRKings/pokemonsay-newgenerations/master/pokemons'
|
||||
|
||||
const COW_FILES: Record<string, string> = {
|
||||
bulbasaur: '001_bulbasaur',
|
||||
ivysaur: '002_ivysaur',
|
||||
venusaur: '003_venusaur',
|
||||
charmander: '004_charmander',
|
||||
charmeleon: '005_charmeleon',
|
||||
charizard: '006_charizard',
|
||||
squirtle: '007_squirtle',
|
||||
wartortle: '008_wartortle',
|
||||
blastoise: '009_blastoise',
|
||||
pikachu: '025_pikachu',
|
||||
}
|
||||
|
||||
const SPRITES_DIR = join(homedir(), '.claude', 'buddy-sprites')
|
||||
|
||||
function convertCowToLines(cowContent: string): string[] {
|
||||
const startMarker = '$the_cow =<<EOC;'
|
||||
const endMarker = 'EOC'
|
||||
|
||||
const startIdx = cowContent.indexOf(startMarker)
|
||||
if (startIdx === -1) return []
|
||||
|
||||
const contentStart = startIdx + startMarker.length
|
||||
const endIdx = cowContent.indexOf(endMarker, contentStart)
|
||||
if (endIdx === -1) return []
|
||||
|
||||
let content = cowContent.slice(contentStart, endIdx)
|
||||
|
||||
// Convert \N{U+XXXX} to actual Unicode characters
|
||||
content = content.replace(/\\N\{U\+([0-9A-Fa-f]{4,6})\}/g, (_, hex) =>
|
||||
String.fromCodePoint(parseInt(hex, 16)),
|
||||
)
|
||||
|
||||
// Convert \e to actual escape character (for ANSI sequences)
|
||||
content = content.replace(/\\e/g, '\x1b')
|
||||
|
||||
// Split into lines
|
||||
let lines = content.split('\n')
|
||||
|
||||
// Strip leading/trailing empty lines
|
||||
while (lines.length > 0 && lines[0].trim() === '') lines.shift()
|
||||
while (lines.length > 0 && lines[lines.length - 1].trim() === '') lines.pop()
|
||||
|
||||
// Remove first 4 lines (cowsay thought bubble guide - $thoughts lines)
|
||||
if (lines.length > 4) {
|
||||
lines = lines.slice(4)
|
||||
}
|
||||
|
||||
// Trim trailing whitespace on each line
|
||||
lines = lines.map((line) => line.trimEnd())
|
||||
|
||||
return lines
|
||||
}
|
||||
|
||||
function stripAnsi(str: string): string {
|
||||
// eslint-disable-next-line no-control-regex
|
||||
return str.replace(/\x1b\[[0-9;]*m/g, '')
|
||||
}
|
||||
|
||||
async function main() {
|
||||
// Ensure output directory
|
||||
if (!existsSync(SPRITES_DIR)) {
|
||||
mkdirSync(SPRITES_DIR, { recursive: true })
|
||||
}
|
||||
|
||||
for (const [speciesId, cowPrefix] of Object.entries(COW_FILES)) {
|
||||
const url = `${GITHUB_RAW_BASE}/${cowPrefix}.cow`
|
||||
console.log(`Fetching ${speciesId} from ${url}...`)
|
||||
|
||||
try {
|
||||
const response = await fetch(url)
|
||||
if (!response.ok) {
|
||||
console.error(` FAILED: HTTP ${response.status}`)
|
||||
continue
|
||||
}
|
||||
|
||||
const cowContent = await response.text()
|
||||
const lines = convertCowToLines(cowContent)
|
||||
|
||||
if (lines.length === 0) {
|
||||
console.error(` FAILED: No lines after conversion`)
|
||||
continue
|
||||
}
|
||||
|
||||
// Calculate visible width (strip ANSI for measurement)
|
||||
const widths = lines.map((l) => stripAnsi(l).length)
|
||||
|
||||
const sprite = {
|
||||
speciesId,
|
||||
lines,
|
||||
width: Math.max(...widths),
|
||||
height: lines.length,
|
||||
fetchedAt: Date.now(),
|
||||
}
|
||||
|
||||
const outPath = join(SPRITES_DIR, `${speciesId}.json`)
|
||||
writeFileSync(outPath, JSON.stringify(sprite, null, 2))
|
||||
|
||||
console.log(` OK: ${lines.length} lines, ${sprite.width} cols wide`)
|
||||
|
||||
// Also print first line for visual check
|
||||
console.log(` Preview line 1: ${stripAnsi(lines[0]!)}`)
|
||||
} catch (err) {
|
||||
console.error(` FAILED: ${err}`)
|
||||
}
|
||||
|
||||
// Small delay to be nice to GitHub
|
||||
await new Promise((r) => setTimeout(r, 200))
|
||||
}
|
||||
|
||||
console.log('\nDone! Sprites cached to ~/.claude/buddy-sprites/')
|
||||
}
|
||||
|
||||
main().catch(console.error)
|
||||
Reference in New Issue
Block a user