Skip to content
Development
Agent

extension

<!-- GENERATED from docs/playbooks/new-extension.md by scripts/build-agent-skill.mjs. Do not edit. -->

From plugin
crossbind
14934 skills34 agents

Claude Code

$ npx -y skills add crossbind/crossbind --agent claude-code

Agent definition

extension.md

<!-- GENERATED from docs/playbooks/new-extension.md by scripts/build-agent-skill.mjs. Do not edit. -->

Playbook — Author an app extension

> **Extension author** — Use this workflow when an app needs a native function crossbind's host does not have, and it > should ship as a package any crossbind app lists.

Goal

A package that:

  • adds functions to an app's host, which its page calls by name, on every platform it takes;
  • builds from sources it carries, with no download;
  • checks every option the page gives, and rejects what it refuses with what mends it;
  • has page-side checks that pass in an app on each of its platforms.

[`docs/api/extensions.md`](../api/extensions.md) is the contract; this playbook is the order of the work.

When to use

  • The function is the app's, on the device: the clipboard, a sensor, a system dialog or service.
  • The web's own API cannot do it in the system webview, or does it worse.

For C or C++ the page calls as a library, with no host of its own, port the library instead (see [`new-port.md`](./new-port.md)). For code of one app alone, keep the extension in the app's repository and list it in its `crossbind.config.js` with `root` its folder, as a package would give. For the packages of another package manager, which a project declares and imports as it does Conan's, write a package source, which needs no app (see [Package sources](../api/extensions.md#package-sources)).

Package shape

`npm create crossbind@beta -- <name> Extension` makes a start: `crossbind-extension-<name>`, with one function every platform compiles from `native/<name>.cpp`, the page's module and types, and a README, named after the project.

Compare with `extensions/clipboard/`:

<name>/
├── package.json              # @<scope>/extension-<name>, crossbind.extension, the crossbind-extension keyword
├── crossbind.extension.js    # default export: (options) => ({ name, contract: 1, root, app, options })
├── index.js                  # the page's functions, each through invoke('<name>.<function>')
├── index.d.ts
├── README.md                 # install, use, and what each platform does
└── native/
    ├── <name>.h              # the functions each platform defines
    ├── <name>.cpp            # crossbind_extension_<name>(Registry &): checks options, calls the platform
    ├── darwin.mm             # macOS
    ├── ios.mm                # iOS
    ├── linux.cpp             # GTK and GLib
    ├── windows.cpp           # Win32
    ├── android.cpp           # android::callJava() to the extension's Java
    └── android/dev/<...>/<Name>Extension.java

Every platform compiles `app.sources`, so a source there that calls a platform's code needs that code on every platform. An extension that takes some platforms alone gives its sources per platform, the entry among them; on a platform it gives none, the page's call rejects as the host has no such function: say so in the README.

Beyond functions

An extension takes more than calls through the same registry, each as a section of [`docs/api/extensions.md`](../api/extensions.md) tells:

| What | Through | |---|---| | URLs the page loads, as `<img>` and `<video>` do | `registry.route()`, [Routes](../api/extensions.md#routes) | | Progress before an answer, and the page's cancel | `call.send()`, `call.onCancel()`, [Messages, cancels and bytes](../api/extensions.md#messages-cancels-and-bytes) | | What it starts as the app runs, the app's windows, pages, state before its user, quit and reopening | `onStart`, `onWindow`, `onWindowClosed`, `onPage`, `onActive`, `onClose`, `onQuitRequest`, `onQuit`, `onReopen`, [The native side](../api/extensions.md#the-native-side) | | Events the page listens for | `registry.events()`, [The native side](../api/extensions.md#the-native-side) | | Launches, and the links, files, user activities and quick actions the system opens the app with | `onLaunch`, `onOpenUrl`, `onOpenFiles`, `onUserActivity`, `onShortcutItem`, with what the descriptor declares, [Launches and links](../api/extensions.md#launches-and-links) | | Notifications and push on iOS and macOS | `onNotification`, `addNotificationCategories()`, `registerForPush()`, `onPushToken`, `onPushTokenFailure`, `onPushMessage`, [Notifications and push](../api/extensions.md#notifications-and-push) | | The page's navigations, downloads, drops, dialogs, permissions and file inputs | the hooks of the role of each, which an extension takes from the host's with `replaces`, [The page's requests](../api/extensions.md#the-pages-requests) | | What one of the host's own does, as its tray | `replaces`, [The host's own extensions](../api/extensions.md#the-hosts-own-extensions) | | Files the app carries for it, as models | `app.files`, `registry.files()`, [What an extension is](../api/extensions.md#what-an-extension-is) | | A store the app is published to, or what installs a desktop app | `publisher`, `installer`, [Publishers](../api/extensions.md#publishers), [Installers](../api/extensions.md#installers) | | A command of `crossbind app` | `commands`, [Commands](../api/extensions.md#commands) | | A widget, a share extension or a notification service of an iOS app, and the App Group it shares with the app | `app.ios.targets`, [iOS app extensions](../api/extensions.md#ios-app-extensions) |

What the system hands an app at launch reaches the owner the descriptor names: a scheme, a file type, a site, a user activity's type or a quick action has one owner, the app or one extension, and an extension that declares one calls its hook. What the host keeps for itself, [What the host keeps](../api/extensions.md#what-the-host-keeps) lists.

Steps

1. **Name it.** Lowercase letters and digits, from a letter, dashes between. Look on npm for the keyword `crossbind-extension` first, so two extensions do not take one name, which stops an app that lists both: crossbind keeps `app`, `events`, `windows`, `crossbind` and those that start with `page-`, one named as a role of the h

Read more
@crossbind
Ships withcrossbind

Import C++ and Rust like JavaScript modules (WebAssembly & React Native)

1491 skill34 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
149
Star history of crossbind/crossbind on GitHub, a chart by star-history.com

Other agents on crossbind.

contributor-context

contributor-context

Agent

Contributor context for coding agents working in this repository. Human contributors should start with `README.md` and…

@crossbind@crossbindInstall Agent
app

app

Agent

<!-- GENERATED from docs/api/app.md by scripts/build-agent-skill.mjs. Do not edit. -->

@crossbind@crossbindInstall Agent
build-state

build-state

Agent

<!-- GENERATED from docs/api/build-state.md by scripts/build-agent-skill.mjs. Do not edit. -->

@crossbind@crossbindInstall Agent
conan

conan

Agent

<!-- GENERATED from docs/api/conan.md by scripts/build-agent-skill.mjs. Do not edit. -->

@crossbind@crossbindInstall Agent

More agents from other plugins.

a11y-architect
Auto-invoked

a11y-architect

Agent

Accessibility Architect specializing in WCAG 2.2 compliance for Web and Native platforms. Use PROACTIVELY when designing UI…

ecc2w293k
@affaan-m@affaan-mInstall Agent
analyze-pass-impact

analyze-pass-impact

Agent

Analyzes how a specific topic affects a group of compiler passes. Used by the /plan-update skill to parallelize research across…

react5d252k
@facebook@facebookInstall Agent
orchestrator

orchestrator

Agent

- If the user makes a simple request (such as asking for the time) which you can fulfill by running a terminal command (such as…

codex5d135k
@openai@openaiInstall Agent
cavecrew-builder

cavecrew-builder

Agent

Surgical 1-2 file edit. Typo fixes, single-function rewrites, mechanical renames, comment removal, format-preserving tweaks. Hard…

caveman6d119k
@juliusbrussee@juliusbrusseeInstall Agent

Questions about extension.

Which coding agents can use extension?
extension installs in Claude Code and Cursor: each loads subagents from .claude/agents, so copy the file there. Flowy's auto-invocation runs in Claude Code only.