Custom Extensions
Extension API
Custom extensions communicate with RebelOps through window.postMessage. This works in browser iframes and in the native in-app web view via a compatibility polyfill.
Transport Contract
The host and extension exchange JSON messages. The web runtime uses iframe postMessage directly; the native runtime polyfills window.parent.postMessage and forwards payloads to Flutter.
Message Shape
{
"type": "request | response | event | tool_call | tool_response",
"id": "unique-message-id",
"method": "optional.method.name",
"data": {},
"timestamp": 1730000000000
} Keep id unique per request/tool call so responses can be correlated.
Recommended Initialization
JavaScript
const REBELOPS_ORIGIN = 'https://web.rebelops.app'
function handleRebelOpsMessage(message) {
switch (message?.type) {
case 'tool_call':
return handleToolCall(message)
case 'response':
return handleResponse(message)
case 'event':
return handleEvent(message)
default:
return
}
}
window.addEventListener('message', (event) => {
// Enforce in production for web-hosted extensions:
// if (event.origin !== REBELOPS_ORIGIN) return
handleRebelOpsMessage(event.data)
})
function sendToRebelOps(message) {
window.parent.postMessage(message, REBELOPS_ORIGIN)
}Tool Call Flow
When RebelOps invokes extension logic, your extension receives a tool_call and should reply with tool_response.
{
"type": "tool_call",
"id": "call-123",
"tool": "create_task",
"parameters": { "title": "Draft release notes" },
"context": {
"organizationId": "org-123",
"projectId": "proj-456",
"userId": "user-789"
},
"timestamp": 1730000000000
}Error Response Format
Error Response
{
"type": "tool_response",
"id": "call-123",
"success": false,
"error": {
"code": "TOOL_ERROR",
"message": "Human-readable error",
"details": {}
},
"timestamp": 1730000000500
}Security Requirements
- Validate
event.originbefore processing inbound messages. - Use HTTPS extension sources.
- Never trust message payloads without validation.
- Keep permission and authorization checks server-side in your extension backend where applicable.
Current Runtime Status (Updated)
- Web host bridge sends and receives JSON payloads via iframe postMessage.
- Native web view polyfills parent postMessage and forwards payloads to Flutter handler
rebelopsPostMessage. - Native bridge currently returns a generic
responseecho for forwarded payloads; advanced host methods should be treated as evolving contracts.
Build integrations around postMessage transport and explicit tool call handling first; keep method-specific integrations versioned and defensive.