- deploy-biibaye.sh: VPS deploy script - patch-index-html.js: post-build HTML patching (title, favicon, meta) - patch-css-colors.js: post-build CSS color replacement (blue -> orange) - patch-index-html.py: Python alternative for host-side HTML patching - console-package.json: snapshot with @biibaye/branding link dependency - AGENTS.md: full session docs for 2026-05-24 and 2026-05-25
20 KiB
AGENTS.md — Fleetbase
Architecture
- Dual-stack monorepo: Laravel 10 (PHP) backend + Ember.js 5.4 frontend + 12 Git submodules
- Docker services:
application(FrankenPHP/Caddy :8000),httpd(:80→8000),console(Nginx :4200),socket(SocketCluster :38000),database(MySQL 8.0 :3306),cache(Redis),queue,scheduler - Console port 4200, API port 8000 — both must be free or mapped differently
- Packages: Each
packages/<name>/is a Git submodule; contains PHP (composer.json+server/) and/or Ember code (addon/,app/,extension.json) - Core packages:
core-api,ember-core,ember-ui,dev-engine— framework layers all extensions depend on
Prerequisites & Constraints
- PHP >= 8.0, <= 8.2.30 (strict upper bound — 8.3+ will break)
- Node.js >= 22
- pnpm is the JS package manager (not npm/yarn) —
pnpm@11.0.9 - Composer uses private registry at
https://registry.fleetbase.io— authentication may be required for private packages - Git submodules must be initialized:
git submodule update --init --recursive
Commands
Docker (most common)
docker compose up -d # Start all services
docker compose exec application bash # Shell into API container
docker compose exec application php artisan … # Run artisan commands
docker compose exec application bash -c "./deploy.sh" # Run deployment script
Backend (api/)
cd api && composer install # Install PHP deps (uses fleetbase registry)
cd api && php artisan … # Laravel artisan (run inside container or locally with DB access)
cd api && php artisan test # Run PHPUnit tests
cd api && ./vendor/bin/php-cs-fixer fix # Fix PHP style
cd api && vendor/bin/phpstan analyse # Static analysis (in packages with phpstan.neon.dist)
Frontend (console/)
cd console && pnpm install # Install JS deps
cd console && pnpm start # Ember dev server (requires API + socket running)
cd console && pnpm lint # ESLint + stylelint + template-lint
cd console && pnpm test # Lint + ember test (QUnit via Testem)
cd console && pnpm build # Production build → dist/
Single test runs
cd api && php artisan test --filter=MyTest # PHP: single test class
cd api && php artisan test --filter=MyTest::testFoo # PHP: single test method
cd console && pnpm test --filter='My test name' # Ember: filter by test name
cd console && pnpm test --server # Ember: watch mode
Extensions (Custom Packages)
Each extension is a Git submodule under packages/<name>/ with this structure:
extension.json # Metadata (name, version, engine, api)
composer.json # PHP dependencies (if has API)
package.json # JS dependencies (if has Ember engine)
server/ # PHP API code (PSR-4)
addon/ # Ember engine files
app/ # Ember app files
Scaffold a new extension
flb scaffold # CLI wizard
# Or manually: create packages/<name>/ with extension.json, composer.json, package.json
# Register it as submodule: git submodule add <repo-url> packages/<name>
Link local extensions for development
node scripts/package-linker.mjs # Symlink all packages/ into api/ and console/
Package registry flow
flb register # One-time: create registry account
flb verify -e <email> -c <code> # Verify email
flb generate-token -e <email> # Get auth token
flb set-auth <token> # Save token for installs
flb install fleetbase/<extension> # Install extension from registry
Production Deployment (VPS: 37.27.183.102)
SSH key: Config/fleet_key (chmod 600, OpenSSH RSA private key)
SSH command: ssh -i Config/fleet_key root@37.27.183.102
Key env vars for production (docker-compose.override.yml)
ENVIRONMENT=production,APP_DEBUG=falseAPP_KEY— generate withdocker compose exec application bash -c "php artisan key:generate --show"APP_URL,CONSOLE_HOST— set to actual domain/IPSESSION_DOMAIN— domain for session cookiesSOCKETCLUSTER_OPTIONS— restrict origins to production domainsMAIL_*— configure real mailer (not log driver)FILESYSTEM_DRIVER=s3— S3 for file storage (not local disk)GOOGLE_MAPS_API_KEY,IPINFO_API_KEY,TWILIO_*— for full feature setREGISTRY_HOST,REGISTRY_PREINSTALLED_EXTENSIONS— extension registry configOSRM_HOST— routing engine URL
Production checklist
- Copy repo to server, run
docker compose up -d(with correct override) - Ensure ports 80/443/8000/4200/38000 are open in firewall
- Set up SSL/reverse proxy (Caddyfile for API, Nginx for console)
- Use external/managed MySQL in production (not bundled container)
- S3 for file storage (not local disk)
- Restrict
SOCKETCLUSTER_OPTIONSorigins
Environment File Locations
| Env | Notes |
|---|---|
docker-compose.override.yml |
Primary — env vars injected into all Docker services |
api/.env |
Only needed for local PHP runs outside Docker |
api/.env.example |
Template reference |
console/environments/.env.development |
Ember dev env |
console/environments/.env.production |
Ember prod env |
Git Submodule Gotchas
- Always
git submodule update --init --recursiveafter clone - Submodules track specific commits — working on a package means committing inside
packages/<name>/first, then updating the parent repo's submodule pointer - After
git pullin parent, rungit submodule update --recursiveto sync submodules - Package linker script (
scripts/package-linker.mjs) symlinks submodules into api/console/ for local dev — run it after changing module structure
Linting (all layers)
| Layer | Tool | Command |
|---|---|---|
| PHP | php-cs-fixer | ./vendor/bin/php-cs-fixer fix (in api/ or package) |
| PHP | PHPStan | vendor/bin/phpstan analyse (in packages with neon config) |
| JS | ESLint + Prettier | pnpm lint (in console/) |
| CSS | Stylelint | pnpm lint:css |
| Templates | ember-template-lint | pnpm lint:hbs |
| i18n | fleetbase-intl-lint | pnpm lint:intl |
Conventions
- Ember Octane edition — use Glimmer components (
@glimmer/component),<template>tags,@tracked - Tailwind CSS 3.4 is the styling framework,
inter-uiis the typeface - PHP controllers return API resources via
\App\Http\Resources\namespace - Caddy replaces traditional Nginx/Apache for the API server (FrankenPHP)
- SocketCluster handles real-time WebSocket connections
- Prettier config: 4-space tabs, single quotes for JS, double quotes for HBS, 190 print width
Session: 2026-05-24 — Biibaye Branding Extension
Branch Strategy
- main: Clean upstream from
github.com:fleetbase/fleetbase. Never commit here — onlygit pull. - custom-production: Working branch with custom branding + WhatsApp alterations. Created off
mainat v0.7.41.
Private Git Repo
- URL:
ssh://git@git.1.warancloud.com:2222/Ali/biibaye.git - SSH Key:
~/.ssh/deploy_key(same key present on both local and VPS) - SSH Config entry (on VPS at
/root/.ssh/config):Host git.1.warancloud.com IdentityFile ~/.ssh/deploy_key IdentitiesOnly yes AddKeysToAgent yes port 2222 user git
New Extension: packages/biibaye-branding/
Git submodule pointing at private repo. Provides all custom branding:
packages/biibaye-branding/
├── extension.json # "Biibaye Branding" v1.0.0
├── package.json # @biibaye/branding, fleetbase-extension + ember-engine keywords
├── index.js # Ember addon entry
├── config/environment.js # Engine config
├── addon/
│ ├── engine.js # Minimal Ember Engine (required by Fleetbase build system)
│ └── extension.js # Branding logic — runs at Ember boot
└── public/
├── favicon/ # 22 Biibaye-branded icon files (apple-icon-*, android-icon-*, ms-icon-*)
└── images/ # logo SVGs, icon PNGs
extension.js does 5 things on boot:
document.title = "Biibaye - Delivery System"(in both setupExtension and onEngineLoaded)intl.addTranslations('en-us', { 'app.name': 'Biibaye' })— runtime translation injection- Injects CSS:
--primary: #FF4500, dark themebackground-color: #343538 - Replaces all
<link rel="icon">/<link rel="apple-touch-icon">with Biibaye files - Updates meta tags:
msapplication-TileColor,theme-color,msapplication-TileImage
Why translations/en-us.yaml was removed: ember-intl merges translations at build time with host app files taking HIGHEST priority. console/translations/en-us.yaml defines app.name: Fleetbase, which always wins over any addon's app.name. Other Fleetbase extensions avoid this by using namespaced keys (e.g., fleet-ops.*, storefront.*). Solution: in overrideAppName(), look up the intl service from appInstance and call intl.addTranslations('en-us', { 'app.name': 'Biibaye' }) at runtime.
Key implementation detail: setupExtension() calls universe.extensionManager.ensureEngineLoaded('@biibaye/branding') to force the engine to boot. Without this, the engine never loads (root-mounted engines have no route to trigger boot). onEngineLoaded re-sets translation and title after boot, defeating any race with ember-page-title re-render.
Deploy Script: /opt/fleetbase/scripts/deploy-biibaye.sh
Located on VPS. Handles the Docker build context issue (console build context is ./console/, not repo root). Steps:
git pull origin mainin extension submodule- Copies extension into
console/packages/biibaye-branding/(Docker build context) - Copies
public/favicon/*andpublic/images/*intoconsole/public/(so files serve from root/favicon/*URLs) - NEW — Patch
console/app/index.html: Replace Fleetbase defaults to prevent branding flash during reload:sed -i 's|<title>Fleetbase Console</title>|<title>Biibaye - Delivery System</title>|' console/app/index.html sed -i 's|content="#da532c"|content="#FF4500"|' console/app/index.html sed -i 's|content="#ffffff"|content="#FF4500"|' console/app/index.html sed -i 's|href="/favicon/apple-touch-icon.png"|href="/favicon/apple-icon-180x180.png"|' console/app/index.html sed -i 's|href="/favicon/android-chrome-192x192.png"|href="/favicon/android-icon-192x192.png"|' console/app/index.html sed -i 's|href="/favicon/android-chrome-256x256.png"|href="/favicon/android-icon-144x144.png"|' console/app/index.html sed -i 's|color="#5bbad5"|color="#FF4500"|' console/app/index.html - NEW — Patch
console/tailwind.config.js: Replace sky-500 blue (#3485e2) palette with Biibaye orange (#FF4500). This is the PRIMARY fix for the color theme — without this, Fleetbase shows blue buttons/accents because all UI uses Tailwindsky-*classes directly:sed -i "s/'#e6f0fb'/'#FFF0E6'/" console/tailwind.config.js sed -i "s/'#bad5f5'/'#FFD0B3'/" console/tailwind.config.js sed -i "s/'#8dbbef'/'#FFB380'/" console/tailwind.config.js sed -i "s/'#61a0e8'/'#FF7A33'/" console/tailwind.config.js sed -i "s/'#3485e2'/'#FF4500'/" console/tailwind.config.js sed -i "s/'#1c6cc7'/'#E03D00'/" console/tailwind.config.js sed -i "s/'#16539a'/'#B33100'/" console/tailwind.config.js sed -i "s/'#103b6d'/'#8A2600'/" console/tailwind.config.js sed -i "s/'#092341'/'#611A00'/" console/tailwind.config.js - Adjusts pnpm workspace paths for Docker (
../packages/→packages/) - Injects
COPY packages/ packages/beforepnpm installin Dockerfile (so pnpm resolve the link dependency) - Removes
--frozen-lockfileduring build (new dep not in lockfile) - Runs
docker compose build console --no-cache - Restores all original configs (Dockerfile, package.json, workspace, index.html, tailwind.config.js) — restore is critical to keep the clean checkout intact
- Restarts console, httpd, application containers
Why both tailwind.config.js patching AND extension.js CSS injection?
- tailwind.config.js patching (build-time): Changes primary color at the Tailwind compilation level. This prevents the blue flash because the compiled
@fleetbase/console.cssalready contains orange colors. However,ember-ui's pre-compiled CSS invendor.css(like.btn.btn-primary) uses#3485e2at@applycompile time and is NOT affected by the console's tailwind config. - extension.js CSS injection (runtime): Acts as a safety net, overriding any blue that leaks through from
vendor.csswith!importantrules. Covers the gap where ember-ui's pre-compiled CSS still references blue.
To update branding assets in the future:
# Locally: replace files in packages/biibaye-branding/public/ then:
cd packages/biibaye-branding
git add -A && git commit -m "Update assets" && git push origin main
# On VPS:
ssh root@37.27.183.102
/opt/fleetbase/scripts/deploy-biibaye.sh
VPS Changes Made (37.27.183.102)
| What | Where | Details |
|---|---|---|
custom-production branch |
/opt/fleetbase/ |
Created off main, committed submodule addition |
packages/biibaye-branding submodule |
/opt/fleetbase/.gitmodules |
Points at private repo |
APP_NAME: "Biibaye" |
docker-compose.override.yml |
Was "Fleetbase" |
MAIL_FROM_NAME: "Biibaye" |
docker-compose.override.yml |
Was "Fleetbase" |
EXTENSIONS: "@biibaye/branding" |
console/fleetbase.config.json |
Critical — without this extension.js never runs |
| SSH config | /root/.ssh/config |
Added git.1.warancloud.com entry |
| SSH key | /root/.ssh/deploy_key |
Copied for private repo access |
| Deploy script | /opt/fleetbase/scripts/deploy-biibaye.sh |
Rebuilds console with branding |
VPS State (Pre-existing)
| What | Value |
|---|---|
| Fleetbase version | v0.7.41 |
| Domains | api.biibaye.com, console.biibaye.com, socket.biibaye.com |
.env.development |
API: http://37.27.183.102:8000 |
.env.production |
API: https://api.biibaye.com |
fleetbase.config.json |
API/Socket prod URLs |
| Docker services | All running (scheduler unhealthy — pre-existing) |
Branding Spec
| Property | Value |
|---|---|
| App name | Biibaye |
| Window title | Biibaye - Delivery System |
| Primary color | #FF4500 |
| Dark theme background | #343538 |
| Favicon files | 22 Biibaye-branded icons (apple-icon-, android-icon-, ms-icon-*) |
| Logo files | SVG-02.svg, icon.svg, icon.png, fleetbase-logo-svg.svg |
Troubleshooting: app.name Translation
Problem: {{t "app.name"}} still shows "Fleetbase" after extension loaded.
Root cause: ember-intl v6.3.2 build-time merge gives host app (console/translations/en-us.yaml) priority over addon translations. Key app.name: Fleetbase at line 2 of console translations defeats any addon override.
Fix: Instead of relying on build-time translations/en-us.yaml, use runtime injection via intl.addTranslations():
// In setupExtension + onEngineLoaded:
const intl = appInstance.lookup('service:intl');
intl.addTranslations('en-us', { 'app.name': 'Biibaye' });
Verification: Check that appInstance.lookup('service:intl') returns the intl service and addTranslations method exists. ember-intl 6.3.2 has this API confirmed via addTranslations in test-support.js.
Troubleshooting: Primary Color Not Applied (CSS Variables Don't Work)
Problem: Extension injected :root { --primary: #FF4500; } but Fleetbase UI still shows blue (#3485e2).
Root cause: Fleetbase does NOT use CSS custom properties for theming. All colors are hardcoded via Tailwind's sky-* palette (e.g., bg-sky-500, text-sky-500). The --primary variable is never referenced by any Fleetbase component or CSS rule.
Fix (two layers):
-
Build-time — Patch
tailwind.config.jsto replace the sky palette with Biibaye orange before the Docker build. This changes allsky-*class definitions in the compiledconsole.css. -
Runtime — extension.js injects
!importantCSS overrides targeting Tailwind utility classes (.bg-sky-500,.text-sky-500, etc.) and component classes (.btn.btn-primary). This catches any blue that leaks through fromember-ui's pre-compiledvendor.css.
Session: 2026-05-25 — CSS Color Fix + Fleetbase UI Removal
Two critical fixes applied
1. Post-build CSS color patching (the approach that finally worked)
Problem: Building tailwind.config.js patches into Docker failed repeatedly (host-side sed, Dockerfile-internal Node.js patching, post-build sed — none worked). The built CSS always retained Fleetbase blue rgba(52, 133, 226, ...).
Solution: console/patch-css-colors.js — a Node.js script that runs AFTER pnpm build inside the Dockerfile. It walks the dist/ directory tree, finds all .css files, and replaces Fleetbase blue hex/RGB values with Biibaye orange directly in the compiled output.
RUN pnpm build --environment $ENVIRONMENT
RUN node patch-index-html.js && node patch-css-colors.js
Result: 4 CSS files patched (console.css, vendor.css, fleetops-engine/engine.css, registry-bridge-engine/engine.css). Zero blue references remain — 11 orange refs in console.css, 16 in vendor.css.
2. Extension loading fix
Problem: The @biibaye/branding extension never loaded because extensions.json (generated at build time by scanning node_modules) didn't include it. The deploy script's sed commands to modify pnpm workspace paths were no-ops because the source files never contained the biibaye entries to begin with.
Solution: Added "@biibaye/branding": "link:../packages/biibaye-branding" to console/package.json dependencies. Committed to custom-production branch. The deploy script converts the link path from link:../packages/ (host) to link:packages/ (Docker build context) via sed. This is the ONLY reliable sed in the deploy script — the workspace.yaml sed was removed.
Result: extensions.json now contains @biibaye/branding. The extension loads, all runtime features fire on boot.
Extension.js Enhancements
Added in this session:
-
CSS color overrides — replaced non-functional
--primary: #FF4500CSS variables with!importantoverrides for actual Tailwind classes (.bg-sky-500,.text-sky-500,.border-sky-500,.btn.btn-primary, etc.) and dark themebody[data-theme="dark"]background. -
Fleetbase UI removal:
- Menu links — CSS rules hide
.support-user-nav-item(Help & Support),.docs-user-nav-item(Documentation), anda[href*="discord.gg"](Discord). - Default widgets —
removeFleetbaseWidgets()accesses the widget registry and removesdashboard#fleetbase-bloganddashboard#fleetbase-github-cardfrom bothwidgetanddefault-widgetlists.
- Menu links — CSS rules hide
Patch Scripts (in console/ directory on VPS)
| Script | Purpose | When runs |
|---|---|---|
patch-index-html.js |
Replace Fleetbase title/favicon/meta in dist/index.html | Docker: after pnpm build |
patch-css-colors.js |
Replace Fleetbase blue → Biibaye orange in all compiled CSS | Docker: after pnpm build |
patch-index-html.py |
Same as .js version but in Python (used on host) | Deprecated — uses .js version now |
patch-tailwind.js |
Replace sky palette in tailwind.config.js | Deprecated — didn't work reliably in Docker |
Deploy Script (current version)
Located at /opt/fleetbase/scripts/deploy-biibaye.sh on VPS. Current steps:
git pull origin mainin extension submodule- Copy extension into
console/packages/biibaye-branding/ - Copy public assets (favicon, images) into
console/public/ - Run
python3 patch-index-html.pyon host (patches sourceapp/index.html) - Adjust Dockerfile: remove
--frozen-lockfile, injectCOPY packages/ packages/, injectRUN node patch-index-html.jsbefore build - Adjust package.json: convert
link:../packages/→link:packages/for Docker context docker compose build console --no-cache- Restore all modified files (index.html, package.json, Dockerfile)
- Restart containers
Fleetbase Source Changes (custom-production branch)
| File | Change |
|---|---|
console/package.json |
Added "@biibaye/branding": "link:../packages/biibaye-branding" in dependencies |
AGENTS.md |
All session documentation |
These changes are mirrored in the custom-pr branch of the biibaye extension repo under fleetbase-source/ for safekeeping.