Browse API 1 documentation
GroveAPI 1preview

Grove overview

The extension model, runtime, and compatibility contract.

Mango 3.1+View Markdown

Grove is Mango’s sandboxed extension platform. It lets developers add IRC-aware tools with ordinary HTML, CSS, and JavaScript while Mango retains control of IRC connections, user consent, local files, secrets, and native UI integration.

Grove API 1 is a preview for the Mango 3.1 development line. The integer grove field in manifest.json selects the API contract. Additive API 1 changes remain compatible; a future breaking contract will use another integer.

The extension model

Grove uses one package and runtime model with two presentation names:

  • A Sprig has a visible surface, such as a pane attached to a channel, one server-scoped network tab, or a transient composer utility.
  • A Root is headless. It runs through capabilities such as slash commands, message filters, status badges, or upload providers. A Root may bind to a conversation, one IRC server, or the application; application scope is the no-IRC, app-wide choice for integrations such as a shared upload destination.

The distinction describes presentation, not trust. Sprigs and Roots are subject to the same manifest validation, capability grants, network allow-list, origin isolation, and native bridge checks.

A .grove package contains static web assets and a manifest.json. Mango installs those bytes locally and serves them from an isolated grove-ext:// origin. Extension code is never loaded from a remote website. An extension may contact its own service only when the manifest declares the destination in hostPermissions and the user accepts that access.

What Mango owns

Mango remains the authority for:

  • the live IRC connection and protocol encoding;
  • the channel, query, server, or application scope assigned to an instance;
  • the capability grant stored for the package;
  • every event delivered to JavaScript and every bridge command accepted from it;
  • native file selection and bounded reads for upload providers;
  • Keychain-backed secret storage;
  • native cards, status badges, member-menu actions, and composer insertion;
  • package installation, replacement, and removal.

An extension cannot open a raw IRC socket through the bridge or send arbitrary IRC lines. API 1 exposes modeled operations such as messages, notices, typing state, and away state. Server-scoped message and typing output may name only a confirmed joined channel and is checked natively on every call; NOTICE remains conversation-scoped.

What the extension owns

An extension owns its packaged HTML, CSS, JavaScript, images, and optional settings page. It can use standard browser rendering and timers, persistent web storage when granted, and fetch or WebSocket connections to declared TLS destinations.

The extension decides how to present its UI and how to talk to its optional backend. A weather Root, for example, can fetch a declared weather API and publish a native card. A TUS Root can stream a file selected by the user to a configured TUS server and return a shareable URL. Neither requires changes to Ergo or another IRC server because IRC receives only the resulting ordinary message.

Runtime and lifecycle

Grove runs inside Mango. Closing an instance tears down its web runtime. Closing or suspending Mango stops reliable execution, and iOS may throttle or suspend background WebKit work. A Root is headless, not server-hosted or permanently online.

Mango delivers foreground, background, and native pulse lifecycle events. Extensions that maintain a WebSocket should reconnect defensively, but must not assume timers or sockets remain active while the application is suspended.

Persistent storage preserves data, not execution. A truly always-on extension requires a separate server-side runtime and is outside Grove API 1.

Where to continue

For individual method signatures, arguments, results, and errors, open the API Reference: JavaScript objects. The Event reference documents every host event payload.