shelld is the daemon at the center of Beroun. It serves the launcher and the apps, starts and tracks programs, and owns every API of the system. An app's page, a service, an MCP server and an agent all reach the system through it, and it knows which of them is calling.
Modules
| Module | Role |
|---|---|
manifest | Reads and validates manifests and system views (format 1); capability and permission names; the OS version apps compare against |
services | The service manager: module, process and child hosts; start rules, priority, memory budget, sleep behaviour, window take-over |
sysapi | MessageBox, system sounds, vibration |
sysnotice | Notices the system raises by itself: network up or down, low battery, storage full |
timectl, netctl | Clock, network time and time zone; Wi-Fi and network state. Each is an interface with a system implementation and a test double |
extdisplay, extinput | External display rules (stack, focus, messages) and the buttons-to-pointer logic |
agents, a2a_bridge, a2a_client | The task broker for apps' agents, and A2A 1.0 in both directions |
appinstall | Install, update and remove store apps, with signature verification |
caroline, caroline_ask, caroline_update | Caroline as a service; apps asking her; installing her updates |
face | Caroline's talking head |
ratatosk* | The Ratatosk messenger: accounts, chats, end-to-end encryption, attachments, groups, audio and video calls |
sw | The shell's client of the owner's Camerlengo service: sign-in, session, speech recognition |
Who is calling
The daemon recognises its caller and answers sensitive groups with 403 to everyone else.
| Caller | Recognised by |
|---|---|
| An app's page | The address it was served from |
| A service | Header X-IntelliCat-Service-Id |
| An MCP server | Header X-IntelliCat-Mcp |
| An agent | Header X-IntelliCat-Agent: <app>/<id> |
HTTP API
Pages are served from /, /platform.js, /apps/<id>/… and /system/<id>/…. Everything else is under /api/. A taste of it:
| Group | Routes under /api/ |
|---|---|
| Basics | health, about, home, log, exit, buttons |
| Apps | apps, launch, launch-arg, open, close, running, app/<id>/<path> (passes through to an app's service) |
| Services | services, services/start, /stop, /limit, /register, window/takeover |
| Input and power | hw, hw/button, hw/stick, hw/touch, hw/battery, power, power/sleep, osk/typing, beep |
| Files (memory card only) | fs/list, read, write, mkdir, rename, copy, move, delete, space, fs/audio, fs/video |
| System API | msgbox, sound/*, vibra/* (System API) |
| Notifications | notify, notifications/list, /dismiss, /clear, /read, /dnd |
| Settings, time, network | settings, settings/set, time/*, net/status, net/scan, net/connect |
| Account | auth/status, auth/login, auth/signup, account/session, wizard/… |
| Speech | stt/start, stt/stop |
| Per-app storage | db/get, db/set: the database behind Platform.state and app settings |
| External display | display, display/open, /close, /send, /launch, /focus |
| Store | store/catalog, installed, updates, install, remove |
| Agents | agents, agents/…, agents/sw |
| Messaging | msg/… (mail and messengers), rt/… (Ratatosk) |
| Caroline | caroline/start, /stop, /status, /ask, /voice, /settings, /apps, /app/tool, /sys/<area>/<op> |
| Face | face/job, face/play, face/status, face/stop |
Other listeners: the A2A listener on 127.0.0.1:48772 (opened only when a manifest exposes an agent), the WebSocket /ws for input and typing events, and /appws, a per-page channel for events and display messages.
Launching
Apps come from manifests. config/apps.json lists extra launchables: native entries run as Wayland (or X11) clients, html entries open in a cog of their own. Store-installed apps appear and disappear without a restart.
The shared window
An app with frontend.window = "shared" has no process of its own. Its page is shown in the launcher's cog, one frontend at a time. Starting another app asks the open one to close, and it saves. MODE closes it the same way and the launcher returns. Services and the system may take the window over, as the Clock does to ring an alarm.
Services
A service is a backend that outlives an app's window. It is declared under services in a manifest (or in the system's own services list) and managed by the service manager.
| Field | Meaning |
|---|---|
host | module (an object of the shell's own code), process (a command started and watched by the manager), or child (started by another service and found among its descendants; not stoppable by the manager) |
start | system (at boot), open with required_by (with the app), or manual |
priority | 0–100. Over the memory limit the lowest goes first; 90 and above never |
memory_mb | The declared budget. GET /api/services shows each service's state and memory against the total limit |
sleep | The service keeps running while the device sleeps |
takeover | The service may take the shared window |
privileged | System services only |
port, cmd, endpoints | For process services: {port} and {app} are filled in; endpoints expose paths through /api/app/<id>/<path> to the app's page, its MCP servers and its agents |
The app's page then calls GET /api/app/clock/alarms. The shell forwards it to the service and starts the service first if it is not running. Store-installed services use ports 49000–49999 and get their own data folder.
Notifications
The status bar shows the newest notification with an unread counter. A tap or SELECT opens the panel with Do not disturb, Clear all, and the notifications newest first, with app, time and unread marks.
- A opens the app that raised it and removes the notification; X only removes it; B closes the panel.
- Sources: the system itself (network, battery at 20% and 10%, storage 95% full), the Clock, the Calendar, messengers and any app through
Platform.notifyorPOST /api/notify. - Do not disturb drops sound and vibration except the priority sounds
alarmandring. - An app sees the text of its own notifications only. Other apps get
{event:"changed", unread, dnd}.

Time and network
Time belongs to the system. Settings' Date & time page offers automatic time (on by default), the time zone and manual time, which is refused while automatic time is on. Network time is a one-shot sync run when the setting is turned on, when a network appears, and every hour, retrying every 15 seconds after a failure. Caroline has the same controls through Settings' tools.


Accounts
The shell signs in to the owner's SquirrelWisdom account itself, with the same credentials file Caroline uses. First start shows a sign-in or sign-up screen and a start wizard. When an agent calls the owner's Camerlengo service, the shell adds the session and the key, and journals the call: agent, command, outcome and cost, never the parameters or results.
Logs and debugging
Logs are shell.log, app-<id>.log and one per daemon. WPE's remote inspector listens on port 9222 for any page. The shell page is also served at http://localhost:8765/, so an ordinary browser can open it.
