Pular para o conteúdo principal

Building from Source

AI Supreme Council is a single-file HTML application assembled from 80 modular source files in src/. This guide covers the full build pipeline, from TypeScript compilation to final assembly.

Prerequisites

  • Node.js 20+ and npm
  • Bash (Linux/macOS, or WSL on Windows)
  • Python 3.10+ (for registry validation only)

Setup

Clone the repository and install development dependencies:

git clone https://github.com/nicholasgasior/bcz.git
cd bcz
npm install

This installs:

  • esbuild -- TypeScript type-stripping (no bundling)
  • vitest + jsdom -- Testing framework
  • typescript -- Type checking (tsc --noEmit)
informação

These are development dependencies only. Nothing from node_modules ships to the browser. The production output is a single index.html with zero external dependencies.

Build Steps

1. TypeScript Compilation

If you have TypeScript modules in modules/*/index.ts, compile them first:

npm run build:ts

Or compile a single module:

node scripts/compile-ts.js grid
dica

build.sh automatically runs TypeScript compilation if esbuild is installed. You only need to run npm run build:ts manually if you want to compile without assembling.

2. Assembly

Concatenate all 80 source parts into index.html:

./build.sh

Output:

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. Verification

Check that src/ matches the current index.html without overwriting:

./build.sh --check

Output on match:

OK: src/ matches index.html (80 parts)

Output on mismatch:

MISMATCH: src/ does not match index.html

TypeScript Pipeline

The TypeScript pipeline is a lightweight type-stripping system, not a bundler.

How It Works

For each module in modules/*/:

  1. Source: modules/{name}/index.ts -- TypeScript source with types
  2. Wrapper: modules/{name}/wrapper.txt -- IIFE template with {CODE} and {Name} placeholders
  3. Output: src/{name}.js -- Ready-to-concatenate <script> block

The scripts/compile-ts.js script:

  1. Reads the TypeScript source
  2. Calls esbuild.transformSync() to strip types (no bundling, no format conversion)
  3. Removes any import/export statements (the module is wrapped in an IIFE)
  4. Indents the code and inserts it into the wrapper template
  5. If the code defines __exports, appends return __exports;

Wrapper Template

Each TypeScript module has a wrapper.txt that defines the <script> envelope:

<script>
// ============================================================================
// MODULE: AIS.{Name} (compiled from TypeScript)
// ============================================================================
if (!AIS.{Name}) AIS.lazy('{Name}', function() {
'use strict';
{CODE}
});
</script>

The {Name} placeholder is replaced with the capitalized module name (e.g., grid becomes Grid). The {CODE} placeholder is replaced with the type-stripped, indented source.

Writing TypeScript Modules

Use the var __exports = {...} pattern for the module's public API:

// modules/mymodule/index.ts

interface MyConfig {
name: string;
value: number;
}

function doSomething(config: MyConfig): string {
return config.name + ': ' + config.value;
}

var __exports = {
doSomething,
};
aviso

Do not use bare return statements -- they cause errors with tsc --noEmit. Use var __exports = {...} and compile-ts.js will append return __exports; automatically.

aviso

Do not set format: 'esm' in esbuild options. This causes CommonJS wrapping that breaks the IIFE pattern. The compile script omits the format option intentionally.

Type Checking

Run the TypeScript compiler in check-only mode (no output):

npm run check

This uses tsc --noEmit with the project tsconfig.json. Type definitions are in:

  • core-types/index.d.ts -- Full AIS namespace types
  • core-types/grid.d.ts -- Grid-specific types

Source File Order

The order of files in build.sh is critical. The PARTS array defines the exact concatenation sequence:

Shell (HTML/CSS/DOM):
shell-head.html # DOCTYPE, meta tags, early redirect
shell-style.html # Classless CSS styles
shell-body.html # HTML body, layout, dialogs, forms

Core Modules (single <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 # Local accounts, device password
core-auth-init.js # Auth UI wiring, init, export
core-billing.js # Subscription tier, trial
core-ads.js # Static ad system
core-codec.js # Base80, VLQ, compression
core-storage.js # IndexedDB + SQLite
core-providers.js # SSE factory, registration API
core-providers-builtin.js # Built-in provider definitions
core-ui.js # DOM utils, markdown, toast
core-session.js # Bot session CRUD
core-chat.js # Messages, streaming
core-config.js # Bot config panel
core-app-botlist.js # Bot list, context menu
core-app-switch.js # switchBot, createBot, mega menu
core-app-events.js # bindEvents, council UI
core-app-search.js # Search, export, import, addons
core-app-init.js # Council helpers, init, boot
core-end.js # </script>

WASM-Replaceable (each in own <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

Infrastructure:
kernel-bootstrap.html, moduleloader.js, plugins.js,
mcp.js, channels-*.js, sandbox.js, publish.js,
perf.js, p2p.js, profiles.js, cron.js

Platform:
settings-main.js, i18n.js, miniprograms.js,
docs.js, billing-ui.js, pwa.js

Tail:
shell-bottom.js # Welcome screen handler, closing tags
aviso

Do not rearrange the file order. Core modules share a single <script> block opened by core-boot.js and closed by core-end.js. Inserting a file between them that contains </script> will break the build.

Running Tests

The test suite uses Vitest with a jsdom environment.

# Run all tests once
npm test

# Run tests in watch mode (re-runs on file changes)
npm run test:watch

# Run only TypeScript module tests
npm run test:modules

# Run a specific test suite
npm run test:settings

Worker tests run separately from within the worker/ directory:

cd worker
npm test

Development Workflow

The standard edit-build-test cycle:

# 1. Edit source files
$EDITOR src/core-chat.js

# 2. Assemble into index.html
./build.sh

# 3. Test in browser
# Open index.html or use a local server

# 4. Run tests
npm test

# 5. Verify build integrity
./build.sh --check

For TypeScript modules:

# 1. Edit TypeScript source
$EDITOR modules/grid/index.ts

# 2. Type-check
npm run check

# 3. Compile + assemble (build.sh does both)
./build.sh

# 4. Test
npm run test:modules

Adding a New Module

To add a new lazy-loaded module:

  1. Create src/mymodule.js with the standard pattern:
<script>
if (!AIS.MyModule) AIS.lazy('MyModule', function() {
'use strict';

function doWork() { /* ... */ }

return { doWork };
});
</script>
  1. Add the file to the PARTS array in build.sh at the appropriate position.

  2. Run ./build.sh to verify it assembles correctly.

To add a new TypeScript module:

  1. Create modules/mymodule/index.ts with the source code.
  2. Create modules/mymodule/wrapper.txt with the IIFE template (copy from an existing module like modules/grid/wrapper.txt).
  3. Optionally add type definitions to core-types/index.d.ts.
  4. Add src/mymodule.js to the PARTS array in build.sh.
  5. Run ./build.sh.

Registry Validation

The model and package registries have validation scripts:

# Validate model registry
python3 registry/validate.py

# Validate package registry
python3 registry/validate.py packages

# Validate a single manifest
python3 registry/validate.py manifest examples/hello-world/manifest.json

WASM Kernel (Optional)

The WASM kernel is an optional component. Building it requires Zig 0.14.0+:

cd kernel
../tools/zig/zig build # outputs zig-out/bin/kernel.wasm (~5.5 KB)

The kernel is not required for the main application to function. All kernel features have JavaScript fallbacks.