@ibgib/web-gib
v0.0.46
Published
Framework for creating agentic ibGib web apps. Contains plumbing for ibgib components, agentic framework (currently only Gemini implemented), web-based IndexedDB storage substrate, and more.
Maintainers
Readme
web-gib - agent-driven ibGib web apps
:under_construction: I'm currently in the process of pulling this out as a framework from @ibgib/blank-gib.
This library enables ibgib apps with...
Build (Monorepo Policy)
[!IMPORTANT] This project is part of a monorepo. Build and development tasks are centralized in the monorepo root via the
@ibgib/build-giborchestrator.
Development & Build
Run these from the monorepo root:
npm run build:web-gib- Performs a full clean and build.npm run test:web-gib- Runs the full respec-gib test suite for this library.
Legacy Scripts
Individual package scripts have been streamlined to avoid redundancy. Previous scripts are archived in docs/ARCHIVE_SCRIPTS.md at the monorepo root.
- initializing the ibgib environment
- bootstrapping the metaspace
- utilizing and interacting with IndexedDB
- IndexedDB-based ibgib space implementation
- IndexedDB helper functions
- building with the ibgib component framework
src notes
*.ext.mts, *.web.mts, *.app.mts
All ibgib code is TypeScript + ES Modules.
- .ext for chrome extension-only (not the app)
- .web.mts - web (not node)
- .app.mts - blank-gib app (not the web extension)
AI Agent Skills (Scaffolding)
In lieu of a heavy framework CLI, the @ibgib/web-gib package comes bundled with built-in agent instructions and templates structure to help your IDE's AI agents natively scaffold new ibgib applications, components, and shells.
Because AI coding assistants typically do not read files inside node_modules, you must initialize these skills by copying them directly into your project's root folder. You can do this manually, or we have provided a simple script to do the copying for you.
Option 1 (For standard projects)
If @ibgib/web-gib is installed at your project root, you can run the executable directly via npx:
npx web-gib-init-agentsOption 2 (For Monorepos & Workspaces)
If @ibgib/web-gib is a dependency on a sub-app (e.g. apps/my-app) instead of the workspace root, package manager "hoisting" rules may prevent the executable from appearing at your root level.
To properly initialize the .agents folder at your monorepo's root, pull from one of the following commands:
Choice A (Execute via npx): Let npx automatically resolve and execute the binary hook from the package registry:
npx -p @ibgib/web-gib web-gib-init-agentsChoice B (Execute script directly): Bypass the broken .bin symlink entirely and execute the raw script locally from within the nested workspace dependency:
node ./apps/my-app/node_modules/@ibgib/web-gib/tools/init-agents.jsRecommendation for Monorepos:
To streamline future updates, it is highly recommended to map whichever execution method you prefer directly into your root package.json scripts:
"scripts": {
"init-agents": "npx -p @ibgib/web-gib web-gib-init-agents"
}Or for the direct script approach:
"scripts": {
"init-agents": "node ./apps/my-app/node_modules/@ibgib/web-gib/tools/init-agents.js"
}Bootstrapping an IbGib App
@ibgib/web-gib provides a streamlined, multi-phase bootstrap process that minimizes boilerplate while maximizing performance. A standard ibgib application consists of 8 foundational files:
index.html: The entry point with script tags forscript.mjsandindex.mjs.script.mts: Phase 1. Immediate UI Shell initialization (e.g., burger menus).index.mts: Phase 2. Storage (IndexedDB) and Engine orchestration.bootstrap.mts: Phase 3. The heavy ibgib engine and App witness loading.constants.mts: App-specific configuration and UUIDs.types.mts: App-specific global state typing.helpers.web.mts: Environment-aware initialization utilities.style.css: Core application styling.
Phase 1: Immediate Shell Interactivity (script.mts)
To ensure the UI is responsive immediately, the Shell is initialized in a dedicated entry point. This script runs as soon as the HTML is parsed.
import { getMyAppShellSvc } from "./ui/shell/my-app-shell-service.mjs";
// Early init of UI Shell logic so the burger menu responds immediately.
getMyAppShellSvc();Phase 2: Environment Orchestration (index.mts)
The index.mts file handles the asynchronous setup of storage and triggers the dynamic loading of the heavy ibgib engine.
In your app's entry point (index.mts), you should initialize the global namespace immediately, then "spin off" the storage and bootstrap loading to avoid blocking the initial DOM paint.
import {
initIbGibStorage,
initIbGibGlobalThis,
dynamicallyLoadBootstrapScript
} from '@ibgib/web-gib/dist/app-bootstrap/init-orchestration.mjs';
import { APP_CONFIG } from './constants.mjs';
import { simpleIbGibRouterSingleton as router } from './ui/router/router-one-file.mjs';
// 1. Initialize global namespace immediately
initIbGibGlobalThis(APP_CONFIG, 'my_app_key');
/**
* spin off to avoid forestalling the DOMContentLoaded from firing
*/
async function spinOffStartup(): Promise<void> {
document.addEventListener('DOMContentLoaded', async () => {
// 2. Prepare storage (IndexedDB)
await initIbGibStorage(APP_CONFIG);
// 3. Initialize Router
router.loadCurrentURLPath();
// 4. Defer loading the heavy engine
await dynamicallyLoadBootstrapScript('./bootstrap.mjs', 'bootstrapMyApp');
});
}
spinOffStartup();Phase 2: Dynamic Engine Bootstrap (bootstrap.mts)
The bootstrap.mts file is loaded dynamically. It handles the initialization of the metaspace, identity, and the application witness using a rich set of lifecycle hooks.
import { bootstrapIbGibApp } from '@ibgib/web-gib/dist/app-bootstrap/bootstrap.mjs';
import { getIbGibGlobalThis_IbGibApp } from '@ibgib/web-gib/dist/app-bootstrap/init-orchestration.mjs';
import {
APP_CONFIG,
TAG_AGENT_TEXT, TAG_AGENT_ICON, TAG_AGENT_DESCRIPTION,
MY_APP_SPACE_PREFIX
} from './constants.mjs';
import { MyAppApp_V1 } from './witness/app/my-app-app-v1.mjs';
import { PARAM_INFOS } from './witness/app/my-app-constants.mjs';
import { DEFAULT_MY_APP_DATA_V1 } from './witness/app/my-app-types.mjs';
import { registerAgentFunctionInfos } from './api/function-infos.web.mjs';
export async function bootstrapMyApp() {
await bootstrapIbGibApp({
config: APP_CONFIG,
// Bridge function that provides the typed globalThis for your app
getGlobalThis: (config) => getIbGibGlobalThis_IbGibApp('my_app_key', config),
AppClass: MyAppApp_V1,
defaultAppData: DEFAULT_MY_APP_DATA_V1,
paramInfos: PARAM_INFOS,
// Lifecycle hooks
registerAgentFunctionInfos,
ensureTags: [
{ text: TAG_AGENT_TEXT, icon: TAG_AGENT_ICON, description: TAG_AGENT_DESCRIPTION }
],
localSpaceNamePrefix: MY_APP_SPACE_PREFIX,
onReady: async (app) => {
console.log('Engine ready!');
// Initialize your UI shell service here
// getAppShellSvc().onEngineReady();
}
});
}UI Architecture: Custom @ibgib component framework
tl;dr: Web Component-based components react to ibgib's unique Merkle DAG DLT time-centric data model.
The front end that this library enables is not built with a conventional framework like React or Vue. Instead, it uses a custom architecture built on top of standard Web Components and the ibgib protocol. This creates a reactive framework against an infinite space built on ibgib's unique DLT content-addressing system.
In particular, components are linked to a backing ibgib timeline, using the
ibgib's tjp address (specifically the gib part, i.e., the tjpGib) as the
pointer to the genesis of the timeline. This acts as a unique, content-addressed
timeline/stream identifier. And components subscribe to the metaspace's local
pubsub, specifically listening to timeline updates, reacting accordingly.
Big Idea
All current approaches to data are disconnected. So the best you can do with a front-end component framework is a Redux-like approach where you usually have a local data store and you provide pathing into that store. Slightly better is you can have a store provider layer. Then your local-only components react to updates via the lambdas/reducers.
The lone exception - and the reason for its ENORMOUS success - is git itself. Think of git's coarse branches as the paths and remotes as the components. Now think of a DLT-based approach to timeline dynamics (like version control systems), that wasn't built with source code as its only use case, rather with each piece of data as its own timeline. Now you have a universally-sized distributed computation addressing system that enables distributed component architecture.
Framework Parts
The component framework itself consists of three main parts:
The Component Service (
IbGibComponentService): A singleton service that acts as a central registry and router for all components in the application. When the application needs to display a new view, it asks the service to find and create the appropriate component for the given data (ibGibAddr).The Component Meta (
IbGibDynamicComponentMeta): This is a "blueprint" or factory object for a component. It doesn't render any UI itself; instead, it defines the component's custom HTML tag name (e.g.,ibgib-sidepanel), its routing rules (how it matches a URL or path), and contains the factory method (createInstance) to stamp out new instances.The Component Instance (
IbGibDynamicComponentInstance): This is the component itself - an actualHTMLElementweb component that gets rendered in the DOM. It contains the UI logic, event handling, and maintains a live link to its correspondingibgibdata. It uses aLiveProxyIbGibto automatically update the UI when the underlying data changes.
This architecture allows for a highly dynamic and modular UI where components can be loaded, unloaded, and updated in response to changes in the ibgib knowledge graph. For a more detailed technical breakdown, see the README.md in the apps/blank-gib/src/extension directory.
