Aus dem Quellcode builden
AISCouncil ist eine Single-File-HTML-Anwendung, die aus 80 modularen Quelldateien in src/ zusammengesetzt wird. Dieser Guide behandelt die volle Build-Pipeline, von TypeScript-Kompilierung bis zur finalen Assemblierung.
Voraussetzungen
- Node.js 20+ und npm
- Bash (Linux/macOS, oder WSL unter Windows)
- Python 3.10+ (nur für Registry-Validierung)
Setup
Klonen Sie das Repository und installieren Sie Entwicklungs-Abhängigkeiten:
git clone https://github.com/nicholasgasior/bcz.git
cd bcz
npm install
Dies installiert:
- esbuild – TypeScript-Type-Stripping (kein Bundling)
- vitest + jsdom – Test-Framework
- typescript – Type-Checking (
tsc --noEmit)
Dies sind nur Entwicklungs-Abhängigkeiten. Nichts aus node_modules wird an den Browser ausgeliefert. Der Produktions-Output ist eine einzelne index.html ohne externe Abhängigkeiten.
Build-Schritte
1. TypeScript-Kompilierung
Wenn Sie TypeScript-Module in modules/*/index.ts haben, kompilieren Sie diese zuerst:
npm run build:ts
Oder kompilieren Sie ein einzelnes Modul:
node scripts/compile-ts.js grid
build.sh führt TypeScript-Kompilierung automatisch aus, wenn esbuild installiert ist. Sie müssen npm run build:ts nur manuell ausführen, wenn Sie ohne Assemblierung kompilieren möchten.
2. Assemblierung
Konkatenieren Sie alle 80 Quell-Teile in index.html:
./build.sh
Ausgabe:
Compiling TypeScript modules...
grid: modules/grid/index.ts -> src/grid.js
Compiled 1 module.
Built index.html (15432 lines, 982451 bytes) from 80 parts
3. Verifizierung
Prüfen Sie, ob src/ mit der aktuellen index.html übereinstimmt, ohne zu überschreiben:
./build.sh --check
Ausgabe bei Übereinstimmung:
OK: src/ matches index.html (80 parts)
Ausgabe bei Nicht-Übereinstimmung:
MISMATCH: src/ does not match index.html
TypeScript-Pipeline
Die TypeScript-Pipeline ist ein leichtgewichtiges Type-Stripping-System, kein Bundler.
Wie es funktioniert
Für jedes Modul in modules/*/:
- Quelle:
modules/{name}/index.ts– TypeScript-Quelle mit Types - Wrapper:
modules/{name}/wrapper.txt– IIFE-Template mit{CODE}- und{Name}-Platzhaltern - Ausgabe:
src/{name}.js– Bereit-zu-konkatenierender<script>-Block
Das scripts/compile-ts.js-Skript:
- Liest die TypeScript-Quelle
- Ruft
esbuild.transformSync()auf, um Types zu entfernen (kein Bundling, keine Format-Konvertierung) - Entfernt alle
import/export-Statements (das Modul wird in eine IIFE gewrapped) - Rückt den Code ein und fügt ihn in das Wrapper-Template ein
- Wenn der Code
__exportsdefiniert, hängt esreturn __exports;an
Wrapper-Template
Jedes TypeScript-Modul hat eine wrapper.txt, die den <script>-Envelope definiert:
<script>
// ============================================================================
// MODULE: AIS.{Name} (compiled from TypeScript)
// ============================================================================
if (!AIS.{Name}) AIS.lazy('{Name}', function() {
'use strict';
{CODE}
});
</script>
Der {Name}-Platzhalter wird durch den kapitalisierten Modul-Namen ersetzt (z.B. grid wird zu Grid). Der {CODE}-Platzhalter wird durch den type-gestrippten, eingerückten Quellcode ersetzt.
TypeScript-Module schreiben
Verwenden Sie das var __exports = {...}-Muster für die öffentliche API des Moduls:
// modules/mymodule/index.ts
interface MyConfig {
name: string;
value: number;
}
function doSomething(config: MyConfig): string {
return config.name + ": " + config.value;
}
var __exports = {
doSomething,
};
Verwenden Sie keine bloßen return-Statements – sie verursachen Fehler mit tsc --noEmit. Verwenden Sie var __exports = {...} und compile-ts.js wird return __exports; automatisch anhängen.
Setzen Sie nicht format: 'esm' in esbuild-Optionen. Dies verursacht CommonJS-Wrapping, das das IIFE-Muster bricht. Das Kompilierungsskript lässt die format-Option absichtlich weg.
Type-Checking
Führen Sie den TypeScript-Compiler im Check-Only-Modus aus (keine Ausgabe):
npm run check
Dies verwendet tsc --noEmit mit dem Projekt-tsconfig.json. Typ-Definitionen sind in:
core-types/index.d.ts– VollständigeAIS-Namespace-Typescore-types/grid.d.ts– Grid-spezifische Types
Quelldatei-Reihenfolge
Die Reihenfolge der Dateien in build.sh ist kritisch. Das PARTS-Array definiert die exakte Konkatenations-Sequenz:
Shell (HTML/CSS/DOM):
shell-head.html # DOCTYPE, Meta-Tags, frühe Weiterleitung
shell-style.html # Klassenloses CSS
shell-body.html # HTML-Body, Layout, Dialoge, Formulare
Core-Module (einzelner <script>-Block):
core-boot.js # <script>-Tag, AIS-Namespace, Event-Bus, Lazy-Loader
core-auth-main.js # OAuth, Google Sign-In
core-auth-local.js # Lokale Konten, Geräte-Passwort
core-auth-init.js # Auth-UI-Wiring, Init, Export
core-billing.js # Abonnement-Stufe, Trial
core-ads.js # Statisches Werbesystem
core-codec.js # Base80, VLQ, Komprimierung
core-storage.js # IndexedDB + SQLite
core-providers.js # SSE-Factory, Registrierungs-API
core-providers-builtin.js # Eingebaute Anbieter-Definitionen
core-ui.js # DOM-Utils, Markdown, Toast
core-session.js # Bot-Sitzung-CRUD
core-chat.js # Nachrichten, Streaming
core-config.js # Bot-Konfigurations-Panel
core-app-botlist.js # Bot-Liste, Kontextmenü
core-app-switch.js # switchBot, createBot, Mega-Menü
core-app-events.js # bindEvents, Council-UI
core-app-search.js # Suche, Export, Import, Addons
core-app-init.js # Council-Helpers, Init, Boot
core-end.js # </script>
WASM-Ersetzbar (jedes im eigenen <script>):
registry.js, grid.js, council.js, wizard.js,
vision.js, memory.js, imagegen.js, tools.js,
reminders.js, themes.js, templates-registry.js,
model-picker.js
Infrastruktur:
kernel-bootstrap.html, moduleloader.js, plugins.js,
mcp.js, channels-*.js, sandbox.js, publish.js,
perf.js, p2p.js, profiles.js, cron.js
Plattform:
settings-main.js, i18n.js, miniprograms.js,
docs.js, billing-ui.js, pwa.js
Tail:
shell-bottom.js # Willkommensbildschirm-Handler, schließende Tags
Ordnen Sie die Dateireihenfolge nicht um. Core-Module teilen sich einen einzelnen <script>-Block, der von core-boot.js geöffnet und von core-end.js geschlossen wird. Das Einfügen einer Datei zwischen ihnen, die </script> enthält, wird den Build brechen.
Tests ausführen
Die Test-Suite verwendet Vitest mit einer jsdom-Umgebung.
# Alle Tests einmal ausführen
npm test
# Tests im Watch-Modus ausführen (erneuter Lauf bei Datei-Änderungen)
npm run test:watch
# Nur TypeScript-Modul-Tests ausführen
npm run test:modules
# Eine bestimmte Test-Suite ausführen
npm run test:settings
Worker-Tests werden separat aus dem worker/-Verzeichnis ausgeführt:
cd worker
npm test
Entwicklungs-Workflow
Der Standard Edit-Build-Test-Zyklus:
# 1. Quelldateien bearbeiten
$EDITOR src/core-chat.js
# 2. In index.html assemblieren
./build.sh
# 3. Im Browser testen
# index.html öffnen oder einen lokalen Server verwenden
# 4. Tests ausführen
npm test
# 5. Build-Integrität verifizieren
./build.sh --check
Für TypeScript-Module:
# 1. TypeScript-Quelle bearbeiten
$EDITOR modules/grid/index.ts
# 2. Type-Check
npm run check
# 3. Kompilieren + assemblieren (build.sh macht beides)
./build.sh
# 4. Testen
npm run test:modules
Ein neues Modul hinzufügen
Um ein neues Lazy-Loaded-Modul hinzuzufügen:
- Erstellen Sie
src/mymodule.jsmit dem Standard-Muster:
<script>
if (!AIS.MyModule)
AIS.lazy("MyModule", function () {
"use strict";
function doWork() {
/* ... */
}
return { doWork };
});
</script>
-
Fügen Sie die Datei zum
PARTS-Array inbuild.shan der entsprechenden Position hinzu. -
Führen Sie
./build.shaus, um zu verifizieren, dass es korrekt assembliert.
Um ein neues TypeScript-Modul hinzuzufügen:
- Erstellen Sie
modules/mymodule/index.tsmit dem Quellcode. - Erstellen Sie
modules/mymodule/wrapper.txtmit dem IIFE-Template (kopieren Sie von einem existierenden Modul wiemodules/grid/wrapper.txt). - Fügen Sie optional Typ-Definitionen zu
core-types/index.d.tshinzu. - Fügen Sie
src/mymodule.jszumPARTS-Array inbuild.shhinzu. - Führen Sie
./build.shaus.
Registry-Validierung
Die Modell- und Paket-Registrys haben Validierungsskripte:
# Modell-Registry validieren
python3 registry/validate.py
# Paket-Registry validieren
python3 registry/validate.py packages
# Ein einzelnes Manifest validieren
python3 registry/validate.py manifest examples/hello-world/manifest.json
WASM-Kernel (Optional)
Der WASM-Kernel ist eine optionale Komponente. Das Builden erfordert Zig 0.14.0+:
cd kernel
../tools/zig/zig build # gibt zig-out/bin/kernel.wasm aus (~5,5 KB)
Der Kernel ist nicht erforderlich, damit die Hauptanwendung funktioniert. Alle Kernel-Features haben JavaScript-Fallbacks.