SHLS (Sebis Hierarchical List Structure) zapisuje dane strukturalne bez cudzysłowów, nawiasów, dwukropków i powtarzanych kluczy: każda sekcja wymienia swoje klucze raz, a rekordy pod nią zawierają tylko wartości. Edytor SHLS pokazuje kod, a obok niego blok kluczy i rekordy każdej sekcji. Zmieniaj wartości, klucze i rekordy na miejscu, oglądaj problemy według wiersza, konwertuj z i do JSON, YAML i CSV i sprawdzaj, ile tokenów SHLS oszczędza w porównaniu z JSON.
Wszystko działa w przeglądarce. Dokumenty nie są nigdzie wysyłane, nie ma rejestracji ani reklam.
Sekcja zaczyna się od swojej nazwy. Jej blok kluczy wymienia klucze z wcięciem o jedną spację; klucze zagnieżdżonej listy o poziom głębiej. Po dokładnie jednym pustym wierszu następują rekordy: jedna wartość w wierszu, w kolejności kluczy. Zagnieżdżona lista ma własny wiersz (swój klucz lub PH jako symbol zastępczy), a jej rekordy są o poziom głębiej. Wszystkie wartości są tekstem - zamiana na liczby czy daty należy do programu, który je czyta.
Product
Name
Price
Smartphone A1
599.99
Laptop B2
1299.99
Company
Name
Location
Country
City
TechCorp
PH
USA
San Francisco
Te same dane w JSON powtarzają każdy klucz w każdym rekordzie i wymagają cudzysłowów, nawiasów i dwukropków. SHLS powstał z myślą o lokalnych i chmurowych modelach AI, w których liczy się każdy token. SHLS by Sebastian Grünwald - format, jego zasady oraz referencyjne SHLSDecoder i SHLSEncoder (Python) znajdują się w repozytorium SHLS na GitHubie.
Podświetlony SHLS po lewej - sekcje, klucze, wartości, poziomy zagnieżdżenia i symbole zastępcze PH. Pośrodku blok kluczy i rekordy każdej sekcji, z kluczami jako etykietami. Kliknięcie przenosi do kodu, kursor kodu zaznacza swój rekord.
Zmieniaj wartości, klucze i nazwy sekcji; dodawaj, duplikuj, przesuwaj i usuwaj rekordy i klucze. Rekordy podążają za swoim blokiem kluczy: nowy klucz dostaje „-” w każdym rekordzie. Każda zmiana to jeden krok dla Cofnij.
Edytor czyta SHLS dokładnie tak jak SHLSDecoder i wymienia to, co odczytałby inaczej, niż wygląda: rekord z brakującą lub nadmiarową wartością, wcięcia, puste wiersze po bloku kluczy, podwójny klucz.
Karta Konwersja liczy przybliżone tokeny twojego SHLS i tych samych danych w JSON, więc od razu widać oszczędność.
Z i do JSON dokładnie tak jak SHLSDecoder i SHLSEncoder, YAML, CSV (jedna sekcja jako tabela) i JSON Lines. Pliki JSON, YAML, CSV i JSON Lines otwierają się jako SHLS.
Przechowuj w przeglądarce dowolną liczbę dokumentów, każdy z własną historią cofania, i pobierz je wszystkie jako ZIP.
Każda strona https (i localhost) może osadzić edytor za pomocą <iframe> i ?embed=1 - bez rejestracji, bez klucza. Po osadzeniu edytor ukrywa ten tekst i pokazuje przycisk Zapisz. Dokument można przekazywać do edytora i z niego na dwa sposoby.
src= otwiera plik (twój serwer musi zezwalać na CORS), webhook= sprawia, że „Zapisz” (Ctrl+S) wysyła dokument pod ten adres. Dodaj &token=…, aby wysyłać nagłówek Authorization: Bearer …, i &auto, aby zapisywać po każdej zmianie.
<iframe src="https://shls.giit.ch/?embed=1&src=https://your-site.com/data/products.shls&webhook=https://your-site.com/save.php"
allow="clipboard-write" style="width:100%;height:800px;border:0"></iframe>
Webhook otrzymuje żądanie POST z JSON { editor: "shls", event: "save", id, name, content, updated }; content to dokument jako tekst. Mały skrypt PHP, który go zapisuje:
<?php
header('Access-Control-Allow-Origin: https://shls.giit.ch');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Allow-Methods: POST, OPTIONS');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') exit;
if (($_SERVER['HTTP_AUTHORIZATION'] ?? '') !== 'Bearer SECRET') { http_response_code(403); exit; }
$d = json_decode(file_get_contents('php://input'), true);
$name = preg_replace('/[^\w\- ]/u', '_', $d['name']);
file_put_contents(__DIR__ . "/data/$name.shls", $d['content']);
echo '{"ok":true}';
Edytor zgłasza shlseditor:ready, twoja strona odpowiada shlseditor:load, edytor zgłasza shlseditor:loaded, shlseditor:change przy rzeczywistych zmianach i shlseditor:save, gdy użytkownik zapisuje. Twoja strona może wysłać shlseditor:get (bieżący stan) lub shlseditor:save (naciśnięcie Zapisz). Zapis odbywa się wtedy przez twoje własne logowanie i sesję.
<iframe id="ed" src="https://shls.giit.ch/?embed=1" allow="clipboard-write" style="width:100%;height:800px;border:0"></iframe>
<script>
const ed = document.getElementById('ed');
const ORIGIN = 'https://shls.giit.ch';
addEventListener('message', async e => {
if (e.source !== ed.contentWindow || e.origin !== ORIGIN) return;
const m = e.data;
if (m.type === 'shlseditor:ready') { // edytor jest gotowy: przekaż mu dokument
ed.contentWindow.postMessage({
type: 'shlseditor:load',
name: 'Products',
content: await (await fetch('/data/products.shls')).text()
}, ORIGIN);
}
if (m.type === 'shlseditor:change') document.title = '● not saved'; // rzeczywista zmiana
if (m.type === 'shlseditor:save') { // użytkownik kliknął „Zapisz”
await fetch('/api/save', { method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: m.name, content: m.content }) });
document.title = 'Saved';
}
});
// Przycisk zapisu na twojej stronie: odpowiedź przychodzi jako shlseditor:save
function saveNow() { ed.contentWindow.postMessage({ type: 'shlseditor:get' }, ORIGIN); }
</script>
Asystent AI na twojej stronie: działa także w ramce. Z allow="clipboard-write" w iframe „Kopiuj prompt” korzysta bezpośrednio ze schowka (w przeciwnym razie edytor używa starego polecenia kopiowania albo pokazuje prompt do ręcznego skopiowania). Link wysłany przez AI nie dotrze do edytora osadzonego w innej stronie, więc edytor prosi AI i użytkownika o wklejenie całej odpowiedzi AI do edytora - albo o otwarcie edytora we własnym oknie.
window.open("https://shls.giit.ch/?embed=window", "shlseditor-17") otwiera pełny edytor we własnym oknie, który wymienia te same wiadomości z window.opener. Linki od AI docierają do niego tam. shlseditor:load może też zawierać context: { host, title, rules } - prompt dla AI mówi wtedy, gdzie należy dokument, i stosuje twoje zasady - oraz hook: { url, token }, webhook tylko dla tego dokumentu, który nigdy nie jest zapisywany. Zamknięcie okna z niezapisanymi zmianami wysyła shlseditor:closing.
Przekaż edytorowi własny prompt, adres w twojej witrynie i klucz dla tej sesji edytora. Okno AI pokazuje wtedy „Połączono z” twoją witryną, to, co przekazujesz AI, oraz wybór: zmienić bieżący dokument lub utworzyć nowy; Kopiuj prompt łączy to wszystko. AI wysyła swój wynik z kluczem na twój serwer, a twoja strona otwiera go w edytorze - nowy dokument otwiera się osobno i zostaje w przeglądarce użytkownika. Jeden klucz na sesję edytora: pozostaje ważny, dopóki edytor jest otwarty, a edytor prosi o niego przez shlseditor:key-request tylko wtedy, gdy go nie ma. Edytor nigdy sam nie wysyła klucza i nigdy go nie zapisuje; adres musi być adresem https na twoim własnym hoście lub jego subdomenie.
const key = async () => (await fetch('/api/ai-key.php?doc=17')).json(); // jeden klucz na sesję edytora
const k = await key();
ed.contentWindow.postMessage({ type: 'shlseditor:load', name: 'Products', content, ai: {
label: 'My Site', prompt: 'Keep every key. Only add records.',
endpoint: 'https://your-site.com/api/ai-result.php', key: k.key } }, ORIGIN);
// zapamiętaj id z shlseditor:loaded i ignoruj change/save/closing z innym id
// tylko gdy edytor nie ma klucza:
if (m.type === 'shlseditor:key-request') { const k = await key(); ed.contentWindow.postMessage({ type: 'shlseditor:ai', key: k.key }, ORIGIN); }
// dopóki edytor jest otwarty, informuj serwer co minutę; zamknięcie edytora lub strony unieważnia klucz
setInterval(() => fetch('/api/ai-key.php?alive=' + k.key.slice(0, 8)), 60000);
// twój serwer ma wynik (polling, SSE …): target to "current" lub "new"
ed.contentWindow.postMessage({ type: 'shlseditor:load', name: 'Products', content: draft, from: 'ai', target }, ORIGIN);
Twórz klucze z co najmniej 128 losowymi bitami, przechowuj tylko ich hash, wiąż każdy z zalogowanym użytkownikiem, dokumentem i tą sesją edytora, twórz jeden na sesję, utrzymuj go ważnym tylko wtedy, gdy twoja strona zgłasza sesję jako otwartą, i unieważniaj go, gdy edytor lub strona zostaną zamknięte.
Cały protokół jest opisany w llms.txt - przekaż go AI, a zbuduje połączenie dla twojego systemu. Edytor JSON działa tak samo z prefiksem jsoneditor: - json.giit.ch.
SHLS (Sebis Hierarchical List Structure) to tekstowy format danych strukturalnych autorstwa Sebastiana Grünwalda. Każda sekcja wymienia swoje klucze raz w bloku kluczy; rekordy pod nią zawierają tylko wartości, po jednej w wierszu, a wcięcia pokazują zagnieżdżenie. Bez cudzysłowów, nawiasów, dwukropków i powtarzanych kluczy te same dane potrzebują znacznie mniej tokenów niż JSON - dlatego to dobry format dla modeli AI.
Nie. Edytor działa w całości w przeglądarce. Dokumenty nigdy nie są wysyłane na serwer, chyba że sam skonfigurujesz webhook do własnego serwera.
Tak. Edytor czyta i zapisuje SHLS dokładnie tak jak SHLSDecoder i SHLSEncoder z repozytorium SHLS - JSON w karcie Konwersja to dane, które zwracają klasy Pythona. Tam, gdzie odczytują one dokument inaczej, niż wygląda (rekord z brakującą wartością, pusty wiersz ze spacjami), edytor wymienia to jako problem z numerem wiersza.
Tak. Kliknij wartość, klucz lub nazwę sekcji pośrodku, wpisz tekst i naciśnij Enter. Przyciski nad rekordami dodają, duplikują, przesuwają i usuwają rekordy i klucze; gdy dodajesz lub usuwasz klucz, każdy rekord sekcji dostaje lub traci swoją wartość. Każda zmiana to jeden krok dla Cofnij.
Karta Konwersja liczy przybliżone tokeny dokumentu jako SHLS i tych samych danych w JSON. Dla tabel rekordów SHLS często potrzebuje mniej niż połowy tokenów JSON z wcięciami, bo klucze są zapisywane tylko raz.
Tak. Otwórz plik .json, .yaml, .csv lub .jsonl, a stanie się SHLS zapisanym tak, jak zapisuje go SHLSEncoder; edytor mówi, czego SHLS nie może zachować (puste wartości, wartości z podziałami wierszy). Karta Konwersja i Eksport zapisują JSON, YAML, CSV, JSON Lines i zwykły tekst.
Tak, każda AI - ChatGPT, Claude, Gemini, Copilot lub AI w twoim narzędziu programistycznym. Kliknij „Asystent AI”, potem „Kopiuj prompt”: prompt wyjaśnia SHLS, więc każda AI pisze poprawny SHLS. AI odpowiada linkiem; kliknij go, a dokument pojawi się w edytorze. „Cofnij” cofa każdą zmianę.
Nie. Edytor jest darmowy, bez reklam i bez rejestracji.