TL;DR
- Kontekst: Side project obok etatu UX Leada w banku. Raycast to moje codzienne narzędzie na Macu, zamiennik Spotlight.
- Problem: Sklep rozszerzeń Raycast ma ponad 1700 pozycji, brak sensownych kategorii i po 10 wyników na stronę.
- Co zrobiłem: Zbudowałem skrypt, który pobiera dane z oficjalnego repozytorium Raycast, kategoryzuje rozszerzenia przez OpenAI API i publikuje gotowy katalog jako osobne repo na GitHubie.
- Wynik: 1716 rozszerzeń w 18 kategoriach, 600 gwiazdek i 12 forków. Utrzymywane ~5 miesięcy, dziś repo jest archiwum.
Diagnoza
Sklep rozszerzeń Raycasta ma ponad 1700 pozycji i żadnego sensownego sposobu, żeby je przeszukać: bez kategorii, po 10 wyników na stronę. Mogłem to obejść, pobierając dane prosto ze strony (web scraping). Nie chciałem jednak łamać regulaminu ani opierać się na czymś, co posypie się przy najbliższej zmianie wyglądu strony. Znalazłem więc oficjalne repozytorium na GitHubie, w którym Raycast trzyma dane wszystkich rozszerzeń. Zrobiłem forka i napisałem wokół niego skrypt, który pobiera dane, kategoryzuje je przez GPT i publikuje gotowy katalog jako README.
flowchart TD
subgraph Przed["Przed"]
A1["Szukasz rozszerzenia<br/>w sklepie Raycast"] --> A2["Brak kategorii,<br/>10 wyników na stronę"]
A2 --> A3["Przewijasz strony<br/>albo zgadujesz nazwę"]
end
subgraph Po["Po"]
B1["Fork repo raycast/extensions<br/>+ skrypt scalający dane"] --> B2["Kategoryzacja<br/>przez OpenAI API"]
B2 --> B3["Katalog na GitHubie,<br/>18 kategorii"]
end
classDef good fill:#e6f2ea,stroke:none,color:#1f4d33,rx:14,ry:14
classDef bad fill:#faeaea,stroke:none,color:#5f2626,rx:14,ry:14
classDef accent fill:#27272a,stroke:#3f3f46,stroke-width:1px,color:#fafafa,rx:14,ry:14
class A1,A2,A3 bad
class B1,B2 good
class B3 accent
style Przed fill:#fdf5f5,stroke:#e0c3c3,stroke-width:1px,color:#5f2626,rx:14,ry:14
style Po fill:#f2f8f3,stroke:#c2dcc8,stroke-width:1px,color:#1f4d33,rx:14,ry:14
linkStyle default stroke:#a8a8b3,stroke-width:1.5px
Co zrobiłem
- Zrobiłem forka oficjalnego repozytorium
raycast/extensionsi napisałem skrypt, który scala plikipackage.jsonz każdego rozszerzenia w jedną tablicę danych. - Skategoryzowałem rozszerzenia przez OpenAI API: najpierw GPT-3.5-Turbo-0125 (jeden z pierwszych modeli z kontrolowanym JSON-em na wyjściu), potem GPT-4-turbo, z promptem trzymającym model przy zamkniętej liście kategorii.
- Zautomatyzowałem cały pipeline w praktycznie jednym skrypcie: synchronizacja forka, wykrycie nowych rozszerzeń względem poprzedniej wersji, kategoryzacja, wygenerowanie README, publikacja.
- Opublikowałem wynik jako publiczne repo na GitHubie: 1716 rozszerzeń w 18 kategoriach.
Wyniki
| Metryka | Wartość |
|---|---|
| Rozszerzenia skategoryzowane | 1716 |
| Kategorie | 18 |
| Gwiazdki na GitHubie | 600 |
| Forki | 12 |
| Aktywne utrzymanie | ~5 miesięcy (maj–wrzesień 2024) |
- 1716 rozszerzeń skategoryzowanych automatycznie. Nie musiałem przeglądać każdego wpisu ręcznie.
- 600 gwiazdek i 12 forków na GitHubie, więc ludzie naprawdę z tego korzystali.
- Tylko oficjalne dane. Całość opierała się na repozytorium Raycasta, bez pobierania czegokolwiek ze strony.
- Każda aktualizacja to było uruchomienie jednego skryptu.
Problem
Dlaczego katalog rozszerzeń Raycast jest trudny do przeszukania?
Sklep nie ma porządnych kategorii, a na jednym ekranie pokazuje tylko 10 rozszerzeń. Przy ponad 1700 pozycjach trzeba przewinąć dziesiątki stron albo wpisać w wyszukiwarkę dokładną nazwę. A jeśli nie wiesz, czego szukasz (często tak jest, bo dopiero odkrywasz, co Raycast potrafi), nie masz jak sensownie przeglądać sklepu.
Dlaczego nie web scraping?
Bo to rozwiązanie kruche i na granicy regulaminu. Strona może się zmienić w każdej chwili i scraper przestanie działać. Nie chciałem też wyciągać danych z cudzej strony, skoro firma sama je publikuje. Oficjalne repozytorium na GitHubie, w którym Raycast trzyma package.json każdego rozszerzenia, dawało te same dane i mogłem na nim polegać.
Moja rola / zakres
- Solo side project, obok pełnoetatowej pracy jako UX Lead w banku.
- Zaprojektowałem cały pipeline i prompt do kategoryzacji, napisałem skrypty, utrzymywałem repozytorium przez ~5 miesięcy.
Proces
- Szukanie źródła danych: znalazłem i sforkowałem oficjalne repozytorium na GitHubie z danymi wszystkich rozszerzeń.
- Iteracja nad promptem: kilka podejść, zanim model trzymał się tylko podanych kategorii i nie tworzył własnych.
- Automatyzacja krok po kroku: sync forka → nowy folder na datę → porównanie z poprzednią wersją → kategoryzacja przez API → wygenerowanie README → publikacja.
- Utrzymanie: 11 commitów między majem a wrześniem 2024, w miarę jak pojawiały się nowe rozszerzenia.
Kluczowe decyzje i trade-offy
- Oficjalne repozytorium. Start był wolniejszy, bo musiałem znaleźć właściwe repozytorium i zrozumieć jego strukturę. W zamian rozwiązanie było stabilne i zgodne z zasadami, a zmiana wyglądu strony niczego nie psuła.
| Podejście | Ryzyko | Decyzja |
|---|---|---|
| Web scraping strony Raycast | łamanie regulaminu, kruche przy zmianie layoutu | odrzucone |
| Fork oficjalnego repo GitHub | zależne od struktury package.json w repo | wybrane |
- Odpowiedź modelu w formacie JSON. GPT-3.5-Turbo-0125 zwracał kontrolowany JSON, więc nie musiałem pisać osobnego parsera odpowiedzi. To był jeden z pierwszych razy, kiedy testowałem structured output w praktyce, zanim stał się standardem w większości modeli.
- We wrześniu 2024 przestałem aktualizować katalog. Muszę przyznać, że bez osobnego czasu obok pracy na etacie nie dawałem rady śledzić nowych rozszerzeń i poprawiać kategorii. Dziś repozytorium jest zarchiwizowane.
Jak to się skończyło
Repo ma 600 gwiazdek i 12 forków, ale ostatni commit to wrzesień 2024. Dziś jest zarchiwizowane. Oficjalny sklep Raycasta wciąż nie ma realnego przeglądania po kategoriach, tylko wyszukiwarkę i kilka linków w stopce, więc problem, który rozwiązywałem, nadal istnieje. Nie kontynuowałem, bo utrzymanie kategoryzacji obok pracy na etacie przestało się opłacać. Zakończyłem ten projekt świadomie.
Co z tego wyniosłem
- Automatyzację też trzeba utrzymywać. Nawet dobrze zaprojektowany pipeline potrzebuje kogoś, kto się nim zajmie, kiedy danych przybywa.
- Wybór źródła danych to też decyzja projektowa. Oficjalne repozytorium kosztowało mnie więcej czasu na starcie, ale przez 5 miesięcy nic się nie posypało.
- Structured output oszczędza godziny pracy. Według mnie testowanie go w praktyce, zanim stał się standardem, dało mi dobre wyczucie, kiedy AI naprawdę przyspiesza pracę, a kiedy tylko tak wygląda.