// Name: Scriptkit generated scripts explorer// Description: Explore and copy scripts generated by AI for scriptkit// Cache: trueimport "@johnlindquist/kit"const getScripts = async (text: string): Promise<{ title: string, code: string }[]> => {const result = [];const sections = text.split("## ").filter(section => section.trim());sections.forEach(section => {const lines = section.split("\n");const title = lines.shift()?.trim();let codeBlock = '';let inCodeBlock = false;lines.forEach(line => {if (line.trim().startsWith("```typescript")) {inCodeBlock = true;codeBlock += line + '\n';} else if (line.trim() === "```") {inCodeBlock = false;codeBlock += line + '\n';} else if (inCodeBlock) {codeBlock += line.replaceAll("\`", "`") + '\n';}});if (title && codeBlock) {if (codeBlock.length > 20)result.push({ title, code: codeBlock });}});return result;}const removeCodeBlock = (text: string): string => {return text.replace(/```typescript/g, '').replace(/```/g, '');}const rawGist = await get("https://gist.githubusercontent.com/johnlindquist/e9b9a800ec54b1f2ebc3911d86225ea7/raw/b7e0d43c352b8b23001a8e6819cc18d41b72932a/Script%2520Kit%2520Generated%2520Examples.md")const scripts = await getScripts(rawGist.data)const script = await arg("Select a script", scripts.map(script => {return {name: script.title,value: script.code,preview: () => {return md(script.code)}}}))await clipboard.writeText(removeCodeBlock(script))
// Name: Get summary about something from wikipedia// Description: Search something on wikipedia and get a summary about it// Keycode: wiimport "@johnlindquist/kit"import wiki from 'wikipedia';await arg('What do you want to search for? (wikipedia)', async (input) => {if (input.length < 3) {return "<p class='p-2 text-slate-500'>Search value must be at least 3 characters</p>";}try {const pageSummary = await wiki.summary(input);if (pageSummary.extract == null || pageSummary.extract == "") {return (md(`No summary found for ${input}`));}else {return (md(pageSummary.extract));}} catch {return (md(`No summary found for ${input}`));}})
// Name: Search board games on BoardGameGeekimport "@johnlindquist/kit"import { parseStringPromise } from "xml2js"const BASE_URL = "https://boardgamegeek.com"type GameInfo = {href: string;id: string;name: string;nameid: string;objectid: string;objecttype: string;ordtitle: string;rep_imageid: number;sortindex: string;type: string;yearpublished: number;};//const getBoardGames = async (query: string): Promise<GameInfo[]> => {if (!query) return [];const xmlString = (await get<string>(`${BASE_URL}/xmlapi2/search?query=${encodeURIComponent(query)}&type=boardgame`)).dataconst result = await parseStringPromise(xmlString, { trim: true }).catch(async error => {await div(`Error parsing XML: ${error.message}`, "text-red-500")})if (!result) return [];const games = result['items']['item'] || [];const convertedGames = games.map(convertToGameInfo);return convertedGames;};const convertToGameInfo = (item: any) => {try {return {id: item.$.id,name: item.name[0].$.value,yearpublished: item.yearpublished[0].$.value}} catch (error) {return {id: "",name: "Error parsing game",yearpublished: 0}}}const selectedGame = await arg("Search for a board game on BoardGameGeek", async (query) => {const games = await getBoardGames(query);return games.map(game => ({name: game.name,value: game}));});const getInfoOfGameWithId = async (id: string) => {const result = await get<string>(`${BASE_URL}/xmlapi2/thing?id=${id}&videos=0&comments=0&marketplace=0&stats=1`).catch(async error => {await div(`Error parsing XML: ${error.message}`, "text-red-500")})if (!result) return;const parsed = await parseStringPromise(result.data, { trim: true }).catch(async error => {await div(`Error parsing XML: ${error.message}`, "text-red-500")})const item = parsed.items.item[0]const gameInfo = {minPLayers: item.minplayers[0].$.value,maxPlayers: item.maxplayers[0].$.value,averageRating: item.statistics[0].ratings[0].average[0].$.value,description: item.description[0],image: item.image[0],}return gameInfo;}const gameInfo = await getInfoOfGameWithId(selectedGame.id)await div({html: `<h1>${selectedGame.name} <span class="italic text-slate-500">(${selectedGame.yearpublished})</span></h1><p class="text-slate-600 italic">${gameInfo.minPLayers} - ${gameInfo.maxPlayers} players</p><p>Average rating: <span class="font-bold">${parseFloat(gameInfo.averageRating).toFixed(2)}</span></p><img class="w-20 absolute top-2 right-2" src="${gameInfo.image}" alt="${selectedGame.name}"><p class="italic">${gameInfo.description}</p>`,actions: [{name: "Open on BoardGameGeek",onAction: () => {open(`${BASE_URL}/boardgame/${selectedGame.id}`)}}]}, "p-2")
// Name: Hacker news browser// Author: Mario De Lucaimport "@johnlindquist/kit"interface Story {by: string;descendants: number;id: number;kids: number[];score: number;time: number;title: string;type: string;url: string;}const BASE_URL = "https://hacker-news.firebaseio.com/v0/"const getTopStories = async (): Promise<number[]> => {const response = await get<number[]>(`${BASE_URL}topstories.json`)return response.data.slice(0, 100)}const getStory = async (id: number): Promise<Story> => {const response = await fetch(`${BASE_URL}item/${id}.json`)return await response.json()}const getStories = async (): Promise<Story[]> => {div("Loading stories...", "p-2 text-center")const ids = await getTopStories()const stories = await Promise.all(ids.map(getStory))return stories}// sort by time and get the top 100 storiesconst stories = (await getStories()).sort((a, b) => b.time - a.time)const convertUnixToDate = (unix: number) => {const locale = Intl.DateTimeFormat().resolvedOptions().locale;return Intl.DateTimeFormat(locale, { dateStyle: "short", timeStyle: "short" }).format(new Date(unix * 1000))}const chosenStory = await arg(`Choose a story (${stories.length} stories)`, () => {return stories.map(story => {return {name: story.title,description: `by ${story.by} - ${story.url} (${convertUnixToDate(story.time)})`,value: story}})})open(chosenStory.url)