Atlas / Skills / builderio / Extension Points

Extension PointsCAUTION

skills/builderio/extension-points

A framework for building agentic apps

Verdict
CAUTION
Grade
B
Trust score
89 /100
Version
—
Hosts
—
License
—
Stars
7,191
01

Overview

A framework for building agentic apps

Read from source at commit 5977febf67f1OBSERVED · 2026-10-14
Advertisement
02

What it tells the agent

The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.

---
name: extension-points
description: >-
  How extensions render as widgets inside other apps via named UI slots — the
  framework's optional extension system. Use when an extension-enabled app
  needs to wire an ExtensionSlot or make an existing one-off custom block
  installable into a slot.
metadata:
  internal: true
---

# Extension Points

> **Terminology note.** "Extensions" in this doc are the framework's
> sandboxed Alpine.js mini-app primitive (see the `extensions` skill).
> They are NOT LLM "tools" (function calls). The slot-system tables are
> still physically named `tool_slots` and `tool_slot_installs` for
> back-compat — see the table at the bottom of this doc and the
> "Database & API names" section in the `extensions` skill.

## Mental model

**Slots** are named React-shaped holes in apps. **Extensions** are widgets
that opt into filling those holes. The framework matches them up by string
ID.

Three primitives:

| Primitive            | What it is                                                                                       |
| -------------------- | ------------------------------------------------------------------------------------------------ |
| **Slot**             | `<ExtensionSlot id="..." context={...} />` dropped into an app's JSX                            |
| **Slot target**      | A row saying "extension X can render in slot Y" — `tool_slots` table (Drizzle: `extensionSlots`) |
| **Slot install**     | A row saying "user U wants extension X in slot Y" — `tool_slot_installs` (Drizzle: `extensionSlotInstalls`) |

Slots do not make extensions a default product surface. Most apps keep
extension creation and discovery disabled while preserving installed blocks and
old deep links for compatibility. Add a slot only when the app deliberately
supports this customization seam; otherwise implement the requested behavior in
native app code.

When `<ExtensionSlot>` renders, it queries the user's installs and mounts
one `<EmbeddedTool>` (a small auto-sized iframe) per install, pushing the
slot's context into each via postMessage. (The component is still exported
as `EmbeddedTool` for back-compat.)

## Slot ID convention

`<app>.<area>.<position>` — three dot-separated lowercase-kebab segments.

- `mail.contact-sidebar.bottom`
- `mail.thread-toolbar.actions`
- `clips.right-panel.tabs`
- `calendar.event-detail.bottom`

Stable strings. Renaming a slot is a data migration — same as renaming a
route.

## How to author an extension that fills a slot

Only follow this flow when the host app explicitly enables extensions and the
user has asked for a one-off custom block. Reusable behavior belongs in app
code.

1. **Create the extension** with `create-extension`. The HTML can read
   `window.slotContext` to get the host's context (the contact email,
   recording id, etc.) and subscribe to changes via
   `window.onSlotContext(fn)`.

   ```html
   <div
     x-data="{ contact: null }"
     x-init="contact = window.slotContext; window.onSlotContext(c => contact = c)"
   >
     <template x-if="contact">
       <div class="rounded-lg border p-4 m-4">
         <p class="text-sm">
           Notes for <span x-text="contact.contactEmail"></span>
         </p>
       </div>
     </template>
   </div>
   ```

2. **Declare the slot target** with `add-extension-slot-target`:

   ```
   add-extension-slot-target { extensionId: "<id>", slotId: "mail.contact-sidebar.bottom" }
   ```

3. **Install it** for the current user with `install-extension`:

   ```
   install-extension { extensionId: "<id>", slotId: "mail.contact-sidebar.bottom" }
   ```

The slot will pick up the install on its next render (≤2s via polling sync,
immediate after the action's UI invalidation).

## How to declare a slot in your app

Drop `<ExtensionSlot>` wherever you want to allow extensions:

```tsx
import { ExtensionSlot } from "@agent-native/core/client/extensions";

// inside your component
<ExtensionSlot
  id="mail.contact-sidebar.bottom"
  context={{ contactEmail: contact.email, contactName: contact.name }}
  showEmptyAffordance
/>;
```

> The legacy import path `@agent-native/core/client/tools` continues to
> re-export the same component for back-compat with existing templates.

Props:

- `id` — slot identifier. Must match what extensions target.
- `context` — object pushed to each embedded extension as `slotContext`. Re-pushed
  whenever this prop changes.
- `showEmptyAffordance` — when true, shows a "+ Add widget" button in the
  empty state. Default: false (slot renders nothing when empty).
- `className` / `toolClassName` — optional styling hooks. (The `toolClassName`
  prop name is kept for back-compat; it styles the embedded extension's
  iframe wrapper.)

The host doesn't register slots in advance — `<ExtensionSlot>` is the
declaration. If an extension targets a slot ID that no app has placed, it
just won't render anywhere (the install record is harmless).

## Context contract

Each slot publishes whatever shape it wants via the `context` prop. There's
no schema enforcement in v1 — extensions should null-check fields and fail
gracefully if a field they expect is missing.

Document the context shape next to your `<ExtensionSlot>` so extension
authors know what to read. Convention: include the document in the slot
ID's prefix section so the agent can find it (`mail.contact-sidebar.*`
slots all publish `{ contactEmail, contactName }`).

## Agent actions

| Action                       | What it does                                                            |
| ---------------------------- | ----------------------------------------------------------------------- |
| `add-extension-slot-target`  | Mark an extension as installable into a slot (extension author opts in) |
| `install-extension`          | Install an extension into a slot for the current user                   |
| `uninstall-extension`        | Remove an extension from a slot for the current user                    |
| `list-extensions-for-slot
03

Trust audit

CAUTIONgrade B · trust 89/100 Install with care. The audit found things worth knowing before you trust its output.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeNA
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
none-observed
Shell
none-observed
Dependencies
pinned
Secrets in source
none-found

Findings (5)

MEDIUMInventory / provenance · inv.symlink · CWE-1104
.agents/skills/an
.agents/skills/an
Why it matters. link not followed
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.agents/skills/content-product-development
.agents/skills/content-product-development
Why it matters. link not followed
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.agents/skills/design-exploration
.agents/skills/design-exploration
Why it matters. link not followed
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.agents/skills/turn-into-app
.agents/skills/turn-into-app
Why it matters. link not followed
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.agents/skills/visual-edit
.agents/skills/visual-edit
Why it matters. link not followed

Gates applied: no_behavioural_pass.

Audited 2026-10-14 · audit v0.4.1 · source sha 5977febf67f1full audit observations/trust-audit/skill/builderio__extension-points.json · Report an issue / request a re-scan
04

Audit history

Every audit this skill has had.

DateSourceVerdictGradeScoreChange
2026-10-145977febf67f1CAUTIONB89first audit
05

Questions

What does the Extension Points skill do?

A framework for building agentic apps

Is Extension Points safe to install?

With care. The audit graded it B (89/100) and found 5 things worth knowing before you trust this skill, listed below with the exact line each was found on.

What can Extension Points access on my machine?

The audit observed no filesystem, network or shell use at all in its source.

What do I need installed to use Extension Points?

Its own instructions reference install-extension. Dependencies are pinned to exact versions.

How current is this page?

The grade is for one exact copy of the source (5977febf67f1), read on 2026-10-14. The repository is watched, and a new audit runs when it changes — this is the first audit.

Add this badge to your README

Shows this page's audit result and links back to it. It updates when the audit does.

ModelsAtlas audit badge

Markdown
[![ModelsAtlas audit: Extension Points](https://modelsatlas.com/skills/builderio/extension-points/badge.svg)](https://modelsatlas.com/skills/builderio/extension-points/)

Not your listing, or something out of date? Claim or update your listing.

Advertisement