Jedna baza kodu. 13 platform. Zero kompromisów.
Jak trzy pliki stają się formularzem webowym, poleceniem CLI, narzędziem MCP, ekranem natywnym i automatycznym zadaniem - jednocześnie.
5 802 pliki TypeScript. ~2,1 miliona linii. Zero `any`. Zero błędów typów w czasie wykonania. Jeden wzorzec. Powtórzony 374 razy.
To jest baza kodu stojąca za unbottled.ai - i framework, który ją napędza, next-vibe. Ta sama architektura obsługuje aplikację webową, mobilną, CLI, interfejs agenta AI, serwer MCP, system cron, magistralę zdarzeń WebSocket i silnik przepływu danych na żywo.
Wzorzec nazywa się Unified Surface. Oto czym jest, jak działa i dlaczego - gdy już go zobaczysz - trudno jest wrócić.
Feature to folder
Każda funkcja w next-vibe żyje w folderze. Trzy pliki są wymagane. Wszystko inne jest opcjonalne.
1explain-to-my-boss/
2 definition.ts ← co robi
3 repository.ts ← jak to robi
4 route.ts ← sprawia, że istnieje wszędzie
5 widget.tsx ← własny interfejs React (opcjonalnie)
6 widget.cli.tsx ← własny interfejs terminala (opcjonalnie)To wszystko. Jeden folder. Trzy wymagane pliki. A z tych trzech plików funkcja istnieje na maksymalnie 13 platformach jednocześnie.
13 platform z 3 plików
Gdy dodajesz funkcję do next-vibe, nie staje się ona tylko punktem końcowym API. Staje się wszystkim naraz.
Web API
Endpoint REST, automatycznie walidowany, w pełni typowany
React UI
Auto-generowany z definicji - bez pisania JSX
CLI
Każdy endpoint to polecenie z auto-generowanymi flagami
Schemat narzędzia AI
Schemat function calling generowany automatycznie
Serwer MCP
Połącz z Claude Desktop, Cursor lub dowolnym klientem MCP
React Native
Ekrany iOS i Android z tej samej definicji
Zadanie Cron
Zaplanuj dowolny endpoint do uruchamiania według harmonogramu
Zdarzenia WebSocket
Wypychaj aktualizacje do podłączonych klientów po zakończeniu
Aplikacja Electron
Natywna aplikacja desktopowa przez te same kontrakty endpoint
Panel administracyjny
Auto-generowany interfejs admina, bez dedykowanego kodu
Widget VibeFrame
Osadzalny widget iframe dla dowolnej strony
Umiejętność agenta
Wywoływalna przez agentów AI jako strukturalna umiejętność
Węzeł Vibe Sense
Węzeł w grafie przepływu danych na żywo - ten sam endpoint
Usuń folder. Feature przestaje istnieć wszędzie naraz.
Dostęp do platformy to jedna tablica enum
Nie piszesz oddzielnych warstw uprawnień dla każdej platformy. Dostęp do platformy jest deklarowany w samej definicji - jedna tablica enum, którą każda platforma odczytuje natywnie w czasie wykonania.
1// Ta pojedyncza tablica kontroluje, gdzie pojawia się feature
2allowedRoles: [
3 CLI_OFF, // blokuje CLI
4 MCP_VISIBLE, // opt-in do listy narzędzi MCP
5 REMOTE_SKILL, // umieszcza w pliku umiejętności agenta
6 PRODUCTION_OFF, // wyłącza w produkcji
7]Ta sama definicja. To samo miejsce. Brak plików konfiguracyjnych do synchronizacji. Brak oddzielnych systemów uprawnień na platformę.
Nie ma API dla ludzi i API dla AI. Jest tylko narzędzie.
Demo na żywo: Thea buduje endpoint
Zamiast abstrakcyjnie wyjaśniać wzorzec, pozwól mi pokazać, jak wygląda w praktyce.
Thea to administrator AI tej platformy. Działa na produkcji 24/7, operując przez te same kontrakty endpoint co każdy użytkownik - ta sama walidacja, te same uprawnienia, bez tylnych drzwi. I może delegować pracę do lokalnej maszyny.
Poprosiłem Thea o zbudowanie nowego endpointu - explain-to-my-boss - używając Claude Code na moim PC. Podajesz techniczną decyzję. Zwraca nietech niczne uzasadnienie, w które twój menedżer naprawdę uwierzy. Każdy programista tego potrzebował.
Demo na żywo: Thea buduje endpoint
Zapytaj Thea
Wpisz zadanie w czacie - dwa pola wejściowe, jedna odpowiedź generowana przez AI, wszystkie platformy, MCP_VISIBLE, własne widgety React i CLI.
Tworzy zadanie
Thea myśli głośno, tworzy zadanie z targetInstance="hermes" (twoja lokalna maszyna) i przechodzi w stan uśpienia.
Odbiera zadanie
Lokalna instancja synchronizuje się co 60 sekund. Brak otwartych portów. Twoja maszyna inicjuje połączenie.
Buduje endpoint
Sesja interaktywna. Najpierw czyta istniejące wzorce, tworzy pięć plików, uruchamia vibe check. Zero błędów.
Raportuje ukończenie
Wywołuje complete-task z ID zadania. Status: ukończono. Załączone podsumowanie.
Budzi się
wakeUp uruchamia się. Thea wznawia rozmowę przez WebSocket, strumieniuje odpowiedź, TTS mówi.
Istnieje wszędzie
Formularz web. Polecenie CLI. Narzędzie MCP. Ekran React Native. Wszystko na żywo. Z pięciu plików.
Dowód
Gdy Claude Code wywołał complete-task, trzy rzeczy istniały, których pięć minut wcześniej nie było:
Własny widget React - dramatyczny nagłówek, animowany gradient na wyjściu AI, fałszywy wynik dopasowania korporacyjnego.
Widget CLI - baner ASCII, spinner gdy AI myśli, uzasadnienie drukowane linia po linii na zielono.
Narzędzie MCP - explain-to-my-boss_POST - ponieważ MCP_VISIBLE było w definicji. Claude Desktop może teraz wyjaśniać twoje decyzje twojemu szefowi.
Jedna definicja. Łącznie pięć plików. Trzy zupełnie różne interfejsy. Kontrakt endpoint się nie zmienił. Tylko warstwa prezentacji.
Pod maską
definition.ts - żyjący kontrakt
Definicja nie jest generatorem kodu. To żyjący kontrakt, który każda platforma odczytuje natywnie w czasie wykonania. Zmień ją - wszystko się aktualizuje. Usuń folder - nic nie psuje się w dół strumienia. Nie ma wygenerowanego kodu do posprzątania.
1// definition.ts
2const { POST } = createEndpoint({
3 scopedTranslation,
4 aliases: [EXPLAIN_TO_MY_BOSS_ALIAS],
5 method: Methods.POST,
6 path: ["explain", "to-my-boss"],
7 title: "post.title",
8 description: "post.description",
9 icon: "sparkles",
10 category: "endpointCategories.ai",
11 allowedRoles: [UserRole.CUSTOMER, UserRole.ADMIN] as const,
12 fields: objectField(scopedTranslation, {
13 type: WidgetType.CONTAINER,
14 usage: { request: "data", response: true },
15 children: {
16 decision: requestField(scopedTranslation, {
17 type: WidgetType.FORM_FIELD,
18 fieldType: FieldDataType.TEXTAREA,
19 label: "post.fields.decision.label",
20 description: "post.fields.decision.description",
21 schema: z.string().min(1).max(2000),
22 columns: 12,
23 }),
24 justification: responseField(scopedTranslation, {
25 type: WidgetType.TEXT,
26 content: "post.fields.justification.content",
27 schema: z.string(),
28 }),
29 },
30 }),
31 errorTypes: { /* ... all 9 required error types ... */ },
32 successTypes: { title: "post.success.title", description: "post.success.description" },
33 examples: { requests: { default: { decision: "Migrate to Bun" } }, responses: { default: { justification: "..." } } },
34});repository.ts - nigdy throw
Funkcje repozytorium nigdy nie rzucają. Błędy propagują jako dane - typowane, explicite i możliwe do złapania przez wywołującego. AI może rozumować o ścieżkach błędów. Brak niespodziewanych wyjątków.
1// repository.ts
2// Zwraca ResponseType<T> - nigdy nie rzuca
3export async function explainToMyBoss(
4 data: { decision: string },
5 logger: Logger,
6): Promise<ResponseType<{ justification: string }>> {
7 const result = await ai.generateText({
8 prompt: buildPrompt(data.decision),
9 });
10 if (!result.text) {
11 return fail({ message: "AI returned empty response", errorType: EndpointErrorTypes.SERVER_ERROR });
12 }
13 return success({ justification: result.text });
14}route.ts - cały most
route.ts łączy definicję z handlerem. endpointsHandler obsługuje walidację, uwierzytelnianie, logowanie i ekspozycję dla wszystkich 13 platform. Właściwa logika biznesowa to jedna linia.
1// route.ts
2import { endpointsHandler } from "@/app/api/[locale]/system/unified-interface/shared/endpoints/route/multi";
3import { Methods } from "@/app/api/[locale]/system/unified-interface/shared/types/enums";
4import definitions from "./definition";
5import { explainToMyBoss } from "./repository";
6
7export const { POST, tools } = endpointsHandler({
8 endpoint: definitions,
9 [Methods.POST]: { handler: ({ data, logger }) => explainToMyBoss(data, logger) },
10});Liczby
374 endpointy
Jeden wzorzec, zastosowany 374 razy
Zero `any`
Wymuszane w czasie budowania, nie konwencja
Trzy języki
Sprawdzane w czasie kompilacji - t("typo.here") to błąd kompilatora
To nie jest konwencja. Jest wymuszane w czasie budowania.
Jeden wzorzec. Powtórzony 374 razy.
Każdy węzeł w grafie Vibe Sense to zwykły endpoint next-vibe. Ten sam createEndpoint(). Ta sama struktura 3 plików. Wskaźnik EMA to endpoint. Ewaluator progowy to endpoint. I ponieważ to endpoint - możesz go wywołać z CLI, z AI, skądkolwiek.
vibe analytics/indicators/ema --source=leads_created --period=7
Potok jest platformą.
Vibe Sense to po prostu... więcej endpointów. To samo, zastosowane do danych szeregów czasowych. Lejki leadów. Ekonomia kredytów. Wzrost użytkowników. Twoja platforma obserwuje siebie.
Powrót do blogaZdefiniuj raz. Istnieje wszędzie.
WordPress dał każdemu moc publikowania. next-vibe daje ci moc budowania platform, które działają w sieci, na urządzeniach mobilnych, w CLI, agentach AI i automatyzacji - które obserwują siebie, rozumują o własnych danych i działają na podstawie tego, co znajdą.
Daj gwiazdkę next-vibe na GitHubRozmawiaj, twórz i łącz się - tekst, obrazy, wideo i muzyka
Prywatna AI z 119 modelami - czat, obrazy, wideo i muzyka
Platforma
© 2026 unbottled.ai. Wszelkie prawa zastrzeżone.