contributor-context
AgentContributor context for coding agents working in this repository. Human contributors should start with `README.md` and…
<!-- GENERATED from docs/api/extensions.md by scripts/build-agent-skill.mjs. Do not edit. -->
Claude Code
$ npx -y skills add crossbind/crossbind --agent claude-code
Cursor
Cursor also loads subagents from .claude/agents, so copy this file there to use it in Cursor.
<!-- GENERATED from docs/api/extensions.md by scripts/build-agent-skill.mjs. Do not edit. -->
An app extension adds native code to an app (`target.runtimeEnv: 'app'`), which the app's host builds in: functions the page calls by name, the URLs its route serves the page, the files it carries, and what it does as the app launches, comes before its user and quits, as the system opens it with a link, a file, a user activity or a quick action, hands it a notification or a push, and as the page navigates, downloads, drops files or asks for what it uses. A package of its own carries it, as [`@crossbind/extension-clipboard`](../../extensions/clipboard/README.md) carries the system clipboard's text on macOS, iOS, Android, Windows and Linux, which an app lists. An extension may add a store the app is published to as well, as [Publishers](#publishers) says, what installs a desktop app, as [Installers](#installers) says, and commands of `crossbind app`, as [Commands](#commands) says. One kind of extension is no app's: a package source, which gives any project the packages of another package manager, as [Package sources](#package-sources) says.
crossbind's own are packages of the same kind, in its repository's `extensions/`: the host's, `activities`, `dialog`, `files`, `instance`, `links`, `menu`, `page-dialogs`, `page-feel`, `page-files`, `page-downloads`, `page-drops`, `page-location`, `page-navigation`, `page-permissions`, `power`, `shell`, `shortcuts` and `updater`; the stores, `google-play`, `app-store` and `github`; and the installers, `dmg`, `deb`, `tar-gz`, `nsis` and `zip`. An app has them without installing or listing them, as `@crossbind/core-app-host` has them as its dependencies, and an app's extension takes the place of one, or of one of its roles, as [The host's own extensions](#the-hosts-own-extensions) says. The package source `conan` is crossbind's own too, and a dependency of `crossbind` itself, so every project has it.
An extension names the version of this contract it is written for, as [Versions](#versions) says.
Install the package and list it in `crossbind.config.js`, which `crossbind add @crossbind/extension-clipboard` does with the project's package manager, then import its functions in the page:
// crossbind.config.js
import clipboard from '@crossbind/extension-clipboard/crossbind.extension.js';
export default {
target: { runtimeEnv: 'app' },
extensions: [clipboard()],
};// the page
import { initNative } from './native/native.h';
import { readText, writeText } from '@crossbind/extension-clipboard';
await initNative();
await writeText('Copied from the app');Only the extensions `extensions` lists are built in, with the host's own, and nothing loads at run time. A build checks each one as the config loads, before anything compiles, and what the extensions give together, as their Info.plist keys and Android manifests, as it writes each platform's project (see [crossbind-config.md](./crossbind-config.md)), and sees the project's `paths.base` alone: a package linked in from beside the project, as a workspace's, takes `paths.base` set above both. [`new-extension.md`](../playbooks/new-extension.md) is the order of the work of writing one.
An extension names the versions of the contract it is written for: `contract: 1`, or a list, as `[1, 2]` for one written for both. Each crossbind takes a range of them, from the oldest it still builds to the newest, `1` to `2` in this one: a build stops on an extension that names none of them, saying what to update, crossbind where the extension names newer ones alone, else the extension's package, or `@crossbind/core-app-host` where the host's own extensions are of another crossbind. Native code tells the versions apart with `CROSSBIND_EXTENSION_CONTRACT`, the newest its host is built for, as `#if CROSSBIND_EXTENSION_CONTRACT >= 2` does, and an Android extension's Java with `Extension.CONTRACT`.
Version 2 added [package sources](#package-sources) and changed nothing else: an extension written for 1 builds as it did, and one that gives a `packageSource` names 2, or a build stops, saying so.
A change that every extension written for the contract goes on working with raises the newest version alone: a function, a hook, a member of a struct or of a request, a key of the descriptor or a member of the api that is new, and a role a new extension of the host's holds. One that breaks an extension raises the oldest as well, so that an extension names the new version once it is written for it: a name, a signature or a meaning that changes or goes, a hook that runs on another thread or in another order, and a rule of a build's or of the app's that refuses more. Until crossbind 2.0.0 such a change may come in any release, which marks it as breaking and says in its notes what an extension's author changes; from 2.0.0 it waits for a major version. An extension's package names the crossbind versions it works with as a peer dependency as well.
The contract is what this page gives, with `<crossbind/extension.h>` and `<crossbind/app.h>`, and Android's `dev.crossbind.app.Extension` and `ExtensionHost`: no other file of crossbind's, as one a package imports from `crossbind/src/`, is in it.
A package with:
lists it; its arguments are the extension's options, which the app sets;
The extension the function gives:
| Key | Value | |---|---| | `name` | Lowercase letters and digits, from a letter, which dashes may join. Each of the extension's function names starts with it and a dot, as `clipboard.readText`, or with a role's it takes, as `tray.set` does for on
Contributor context for coding agents working in this repository. Human contributors should start with `README.md` and…
<!-- GENERATED from docs/api/app.md by scripts/build-agent-skill.mjs. Do not edit. -->
<!-- GENERATED from docs/api/build-state.md by scripts/build-agent-skill.mjs. Do not edit. -->
<!-- GENERATED from docs/api/conan.md by scripts/build-agent-skill.mjs. Do not edit. -->
<!-- GENERATED from docs/api/cpp-binding-rules.md by scripts/build-agent-skill.mjs. Do not edit. -->
Surgical 1-2 file edit. Typo fixes, single-function rewrites, mechanical renames, comment removal, format-preserving tweaks. Hard…