Merge branch 'fix/bundled-plugin-deps' into tlon-dev

This commit is contained in:
Hunter Miller 2026-01-26 17:06:45 -06:00
commit d503f0ad86
14 changed files with 308 additions and 137 deletions

View File

@ -16,20 +16,27 @@ Status: supported via plugin. Direct messages, group chats, media, locations, Fl
messages, template messages, and quick replies are supported. Reactions and threads
are not supported.
## Plugin required
## Plugin setup
Install the LINE plugin:
LINE is bundled with Clawdbot. Its dependencies are automatically installed on first load
when you enable the plugin.
To enable, add `line` to your plugins allow list:
```json5
{
plugins: {
allow: ["line"]
}
}
```
Alternatively, install explicitly from npm:
```bash
clawdbot plugins install @clawdbot/line
```
Local checkout (when running from a git repo):
```bash
clawdbot plugins install ./extensions/line
```
## Setup
1) Create a LINE Developers account and open the Console:

View File

@ -13,32 +13,32 @@ but it requires E2EE to be enabled.
Status: supported via plugin (matrix-bot-sdk). Direct messages, rooms, threads, media, reactions,
polls (send + poll-start as text), location, and E2EE (with crypto support).
## Plugin required
## Plugin setup
Matrix ships as a plugin and is not bundled with the core install.
Matrix is bundled with Clawdbot. Its dependencies are automatically installed on first load
when you enable the plugin.
Install via CLI (npm registry):
To enable, add `matrix` to your plugins allow list:
```json5
{
plugins: {
allow: ["matrix"]
}
}
```
Alternatively, install explicitly from npm:
```bash
clawdbot plugins install @clawdbot/matrix
```
Local checkout (when running from a git repo):
```bash
clawdbot plugins install ./extensions/matrix
```
If you choose Matrix during configure/onboarding and a git checkout is detected,
Clawdbot will offer the local install path automatically.
Details: [Plugins](/plugin)
## Setup
1) Install the Matrix plugin:
- From npm: `clawdbot plugins install @clawdbot/matrix`
- From a local checkout: `clawdbot plugins install ./extensions/matrix`
1) Add `matrix` to your plugins allow list (or install via CLI).
2) Create a Matrix account on a homeserver:
- Browse hosting options at [https://matrix.org/ecosystem/hosting/](https://matrix.org/ecosystem/hosting/)
- Or host it yourself.

View File

@ -11,22 +11,29 @@ Status: supported via plugin (bot token + WebSocket events). Channels, groups, a
Mattermost is a self-hostable team messaging platform; see the official site at
[mattermost.com](https://mattermost.com) for product details and downloads.
## Plugin required
Mattermost ships as a plugin and is not bundled with the core install.
## Plugin setup
Mattermost is bundled with Clawdbot. Its dependencies are automatically installed on first
load when you enable the plugin.
To enable, add `mattermost` to your plugins allow list:
```json5
{
plugins: {
allow: ["mattermost"]
}
}
```
The onboarding wizard and `clawdbot channels add` also offer to enable Mattermost.
Alternatively, install explicitly from npm:
Install via CLI (npm registry):
```bash
clawdbot plugins install @clawdbot/mattermost
```
Local checkout (when running from a git repo):
```bash
clawdbot plugins install ./extensions/mattermost
```
If you choose Mattermost during configure/onboarding and a git checkout is detected,
Clawdbot will offer the local install path automatically.
Details: [Plugins](/plugin)
## Quick setup

View File

@ -12,30 +12,34 @@ Updated: 2026-01-21
Status: text + DM attachments are supported; channel/group file sending requires `sharePointSiteId` + Graph permissions (see [Sending files in group chats](#sending-files-in-group-chats)). Polls are sent via Adaptive Cards.
## Plugin required
Microsoft Teams ships as a plugin and is not bundled with the core install.
## Plugin setup
**Breaking change (2026.1.15):** MS Teams moved out of core. If you use it, you must install the plugin.
Microsoft Teams is bundled with Clawdbot. Its dependencies are automatically installed on
first load when you enable the plugin.
Explainable: keeps core installs lighter and lets MS Teams dependencies update independently.
**Note (2026.1.15):** MS Teams is a plugin to keep core installs lighter and let its
dependencies update independently.
To enable, add `msteams` to your plugins allow list:
```json5
{
plugins: {
allow: ["msteams"]
}
}
```
Alternatively, install explicitly from npm:
Install via CLI (npm registry):
```bash
clawdbot plugins install @clawdbot/msteams
```
Local checkout (when running from a git repo):
```bash
clawdbot plugins install ./extensions/msteams
```
If you choose Teams during configure/onboarding and a git checkout is detected,
Clawdbot will offer the local install path automatically.
Details: [Plugins](/plugin)
## Quick setup (beginner)
1) Install the Microsoft Teams plugin.
1) Add `msteams` to your plugins allow list (or install via CLI).
2) Create an **Azure Bot** (App ID + client secret + tenant ID).
3) Configure Clawdbot with those credentials.
4) Expose `/api/messages` (port 3978 by default) via a public URL or tunnel.

View File

@ -7,22 +7,29 @@ read_when:
Status: supported via plugin (webhook bot). Direct messages, rooms, reactions, and markdown messages are supported.
## Plugin required
Nextcloud Talk ships as a plugin and is not bundled with the core install.
## Plugin setup
Nextcloud Talk is bundled with Clawdbot. Its dependencies are automatically installed on first
load when you enable the plugin.
To enable, add `nextcloud-talk` to your plugins allow list:
```json5
{
plugins: {
allow: ["nextcloud-talk"]
}
}
```
The onboarding wizard and `clawdbot channels add` also offer to enable Nextcloud Talk.
Alternatively, install explicitly from npm:
Install via CLI (npm registry):
```bash
clawdbot plugins install @clawdbot/nextcloud-talk
```
Local checkout (when running from a git repo):
```bash
clawdbot plugins install ./extensions/nextcloud-talk
```
If you choose Nextcloud Talk during configure/onboarding and a git checkout is detected,
Clawdbot will offer the local install path automatically.
Details: [Plugins](/plugin)
## Quick setup (beginner)

View File

@ -10,33 +10,31 @@ read_when:
Nostr is a decentralized protocol for social networking. This channel enables Clawdbot to receive and respond to encrypted direct messages (DMs) via NIP-04.
## Install (on demand)
## Plugin setup
### Onboarding (recommended)
Nostr is bundled with Clawdbot. Its dependencies are automatically installed on first load
when you enable the plugin.
- The onboarding wizard (`clawdbot onboard`) and `clawdbot channels add` list optional channel plugins.
- Selecting Nostr prompts you to install the plugin on demand.
To enable, add `nostr` to your plugins allow list:
Install defaults:
```json5
{
plugins: {
allow: ["nostr"]
}
}
```
- **Dev channel + git checkout available:** uses the local plugin path.
- **Stable/Beta:** downloads from npm.
The onboarding wizard (`clawdbot onboard`) and `clawdbot channels add` also offer to enable
Nostr when you select it.
You can always override the choice in the prompt.
### Manual install
Alternatively, install explicitly from npm:
```bash
clawdbot plugins install @clawdbot/nostr
```
Use a local checkout (dev workflows):
```bash
clawdbot plugins install --link <path-to-clawdbot>/extensions/nostr
```
Restart the Gateway after installing or enabling plugins.
Restart the Gateway after enabling plugins.
## Quick setup

View File

@ -12,30 +12,35 @@ be further restricted via allowlists.
Status: supported via plugin. DMs, group mentions, thread replies, and text-only media fallback
(URL appended to caption). Reactions, polls, and native media uploads are not supported.
## Plugin required
## Plugin setup
Tlon ships as a plugin and is not bundled with the core install.
Tlon is bundled with Clawdbot. Its dependencies (`@urbit/http-api`, `@urbit/aura`) are
automatically installed on first load when you enable the plugin.
Install via CLI (npm registry):
To enable, add `tlon` to your plugins allow list and configure the channel:
```bash
clawdbot plugins install @clawdbot/tlon
```
Local checkout (when running from a git repo):
```bash
clawdbot plugins install ./extensions/tlon
```json5
{
plugins: {
allow: ["tlon"]
},
channels: {
tlon: {
enabled: true,
// ... config below
}
}
}
```
Details: [Plugins](/plugin)
## Setup
1) Install the Tlon plugin.
2) Gather your ship URL and login code.
1) Gather your ship URL and login code.
2) Add `tlon` to your plugins allow list.
3) Configure `channels.tlon`.
4) Restart the gateway.
4) Restart the gateway (dependencies install automatically on first load).
5) DM the bot or mention it in a group channel.
Minimal config (single account):

View File

@ -7,17 +7,31 @@ read_when:
Status: experimental. Direct messages only; groups coming soon per Zalo docs.
## Plugin required
Zalo ships as a plugin and is not bundled with the core install.
- Install via CLI: `clawdbot plugins install @clawdbot/zalo`
- Or select **Zalo** during onboarding and confirm the install prompt
- Details: [Plugins](/plugin)
## Plugin setup
Zalo is bundled with Clawdbot. Its dependencies are automatically installed on first load
when you enable the plugin.
To enable, add `zalo` to your plugins allow list:
```json5
{
plugins: {
allow: ["zalo"]
}
}
```
Or select **Zalo** during onboarding. Alternatively, install explicitly from npm:
```bash
clawdbot plugins install @clawdbot/zalo
```
Details: [Plugins](/plugin)
## Quick setup (beginner)
1) Install the Zalo plugin:
- From a source checkout: `clawdbot plugins install ./extensions/zalo`
- From npm (if published): `clawdbot plugins install @clawdbot/zalo`
- Or pick **Zalo** in onboarding and confirm the install prompt
1) Add `zalo` to your plugins allow list (or install via CLI/onboarding).
2) Set the token:
- Env: `ZALO_BOT_TOKEN=...`
- Or config: `channels.zalo.botToken: "..."`.

View File

@ -10,11 +10,24 @@ Status: experimental. This integration automates a **personal Zalo account** via
> **Warning:** This is an unofficial integration and may result in account suspension/ban. Use at your own risk.
## Plugin required
Zalo Personal ships as a plugin and is not bundled with the core install.
- Install via CLI: `clawdbot plugins install @clawdbot/zalouser`
- Or from a source checkout: `clawdbot plugins install ./extensions/zalouser`
- Details: [Plugins](/plugin)
## Plugin setup
Zalo Personal is bundled with Clawdbot. Its dependencies are automatically installed on first
load when you enable the plugin.
To enable, add `zalouser` to your plugins allow list:
```json5
{
plugins: {
allow: ["zalouser"]
}
}
```
Alternatively, install explicitly from npm: `clawdbot plugins install @clawdbot/zalouser`
Details: [Plugins](/plugin)
## Prerequisite: zca-cli
The Gateway machine must have the `zca` binary available in `PATH`.

View File

@ -44,6 +44,7 @@ See [Voice Call](/plugins/voice-call) for a concrete example plugin.
- [Nostr](/channels/nostr) — `@clawdbot/nostr`
- [Zalo](/channels/zalo) — `@clawdbot/zalo`
- [Microsoft Teams](/channels/msteams) — `@clawdbot/msteams`
- [Tlon/Urbit](/channels/tlon) — bundled as `tlon` (disabled by default; auto-installs deps)
- Google Antigravity OAuth (provider auth) — bundled as `google-antigravity-auth` (disabled by default)
- Gemini CLI OAuth (provider auth) — bundled as `google-gemini-cli-auth` (disabled by default)
- Qwen OAuth (provider auth) — bundled as `qwen-portal-auth` (disabled by default)
@ -128,8 +129,9 @@ A plugin directory may include a `package.json` with `clawdbot.extensions`:
Each entry becomes a plugin. If the pack lists multiple extensions, the plugin id
becomes `name/<fileBase>`.
If your plugin imports npm deps, install them in that directory so
`node_modules` is available (`npm install` / `pnpm install`).
If your plugin imports npm deps, bundled plugins will **auto-install** them on
first load. For workspace/linked plugins during development, run `npm install`
or `pnpm install` in the plugin directory manually.
### Channel catalog metadata

View File

@ -28,9 +28,22 @@ The Voice Call plugin runs **inside the Gateway process**.
If you use a remote Gateway, install/configure the plugin on the **machine running the Gateway**, then restart the Gateway to load it.
## Install
## Plugin setup
### Option A: install from npm (recommended)
Voice Call is bundled with Clawdbot. Its dependencies are automatically installed on first
load when you enable the plugin.
To enable, add `voice-call` to your plugins allow list:
```json5
{
plugins: {
allow: ["voice-call"]
}
}
```
Alternatively, install explicitly from npm:
```bash
clawdbot plugins install @clawdbot/voice-call
@ -38,15 +51,6 @@ clawdbot plugins install @clawdbot/voice-call
Restart the Gateway afterwards.
### Option B: install from a local folder (dev, no copying)
```bash
clawdbot plugins install ./extensions/voice-call
cd ./extensions/voice-call && pnpm install
```
Restart the Gateway afterwards.
## Config
Set config under `plugins.entries.voice-call.config`:

View File

@ -19,9 +19,22 @@ This plugin runs **inside the Gateway process**.
If you use a remote Gateway, install/configure it on the **machine running the Gateway**, then restart the Gateway.
## Install
## Plugin setup
### Option A: install from npm
Zalo Personal is bundled with Clawdbot. Its dependencies are automatically installed on first
load when you enable the plugin.
To enable, add `zalouser` to your plugins allow list:
```json5
{
plugins: {
allow: ["zalouser"]
}
}
```
Alternatively, install explicitly from npm:
```bash
clawdbot plugins install @clawdbot/zalouser
@ -29,15 +42,6 @@ clawdbot plugins install @clawdbot/zalouser
Restart the Gateway afterwards.
### Option B: install from a local folder (dev)
```bash
clawdbot plugins install ./extensions/zalouser
cd ./extensions/zalouser && pnpm install
```
Restart the Gateway afterwards.
## Prerequisite: zca-cli
The Gateway machine must have `zca` on `PATH`:

View File

@ -81,14 +81,24 @@ When the operator says “release”, immediately do this preflight (no extra qu
## Plugin publish scope (npm)
We only publish **existing npm plugins** under the `@clawdbot/*` scope. Bundled
plugins that are not on npm stay **disk-tree only** (still shipped in
`extensions/**`).
We publish some plugins to npm under the `@clawdbot/*` scope for users who prefer
explicit installation. However, **all plugins are bundled** in `extensions/**` and
their dependencies are **auto-installed on first load** when enabled.
Process to derive the list:
1) `npm search @clawdbot --json` and capture the package names.
2) Compare with `extensions/*/package.json` names.
3) Publish only the **intersection** (already on npm).
### Bundled plugins with auto-install
Bundled plugins ship with source code but not `node_modules`. When a bundled plugin
is enabled and has external dependencies (not `clawdbot` workspace refs), the loader
automatically runs `npm install` in the plugin directory on first load.
This means users don't need to manually install plugins or their dependencies—they
just enable the plugin in config and restart.
### npm-published plugins (optional)
Some plugins are also published to npm for users who prefer explicit installation
via `clawdbot plugins install @clawdbot/xxx`. This copies the plugin to
`~/.clawdbot/extensions/` and runs `npm install` there.
Current npm plugin list (update as needed):
- @clawdbot/bluebubbles
@ -103,5 +113,14 @@ Current npm plugin list (update as needed):
- @clawdbot/zalo
- @clawdbot/zalouser
Release notes must also call out **new optional bundled plugins** that are **not
on by default** (example: `tlon`).
To add a new plugin to npm:
1) First-publish manually: `cd extensions/<plugin> && npm publish --access public`
2) Add to the list above
3) Future releases will include it automatically
### Bundled-only plugins
Some plugins are bundled but not published to npm (e.g., `tlon`). These work via
the auto-install mechanism—users just enable them in config.
Release notes should call out **new bundled plugins** so users know they're available.

View File

@ -1,3 +1,4 @@
import { spawnSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
@ -43,6 +44,69 @@ const registryCache = new Map<string, PluginRegistry>();
const defaultLogger = () => createSubsystemLogger("plugins");
/**
* Ensures plugin dependencies are installed for bundled plugins.
* Bundled plugins ship with source but not node_modules; this installs
* deps on first load if the plugin has dependencies in package.json.
*/
function ensureBundledPluginDeps(params: {
rootDir: string;
pluginId: string;
logger: PluginLogger;
}): { ok: boolean; error?: string } {
const { rootDir, pluginId, logger } = params;
const packageJsonPath = path.join(rootDir, "package.json");
if (!fs.existsSync(packageJsonPath)) {
return { ok: true }; // No package.json, nothing to install
}
let manifest: { dependencies?: Record<string, string> };
try {
manifest = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
} catch {
return { ok: true }; // Can't parse, skip
}
const deps = manifest.dependencies ?? {};
const depNames = Object.keys(deps).filter(
(name) => !name.startsWith("clawdbot") && name !== "clawdbot",
);
if (depNames.length === 0) {
return { ok: true }; // No external dependencies
}
// Check if first dependency exists in node_modules
const firstDep = depNames[0];
const depPath = path.join(rootDir, "node_modules", ...firstDep.split("/"));
if (fs.existsSync(depPath)) {
return { ok: true }; // Dependencies already installed
}
logger.info?.(`[plugins] ${pluginId}: installing dependencies…`);
try {
const result = spawnSync("npm", ["install", "--omit=dev", "--silent"], {
cwd: rootDir,
encoding: "utf-8",
timeout: 300_000,
stdio: ["ignore", "pipe", "pipe"],
});
if (result.status !== 0) {
const errorMsg = result.stderr?.trim() || result.stdout?.trim() || "unknown error";
return { ok: false, error: `npm install failed: ${errorMsg}` };
}
logger.info?.(`[plugins] ${pluginId}: dependencies installed`);
return { ok: true };
} catch (err) {
return { ok: false, error: `failed to install dependencies: ${String(err)}` };
}
}
const resolvePluginSdkAlias = (): string | null => {
try {
const modulePath = fileURLToPath(import.meta.url);
@ -282,6 +346,29 @@ export function loadClawdbotPlugins(options: PluginLoadOptions = {}): PluginRegi
continue;
}
// Ensure bundled plugin dependencies are installed before loading
if (candidate.origin === "bundled") {
const depsResult = ensureBundledPluginDeps({
rootDir: candidate.rootDir,
pluginId,
logger,
});
if (!depsResult.ok) {
logger.error(`[plugins] ${record.id} failed to install deps: ${depsResult.error}`);
record.status = "error";
record.error = depsResult.error ?? "failed to install dependencies";
registry.plugins.push(record);
seenIds.set(pluginId, candidate.origin);
registry.diagnostics.push({
level: "error",
pluginId: record.id,
source: record.source,
message: record.error,
});
continue;
}
}
let mod: ClawdbotPluginModule | null = null;
try {
mod = jiti(candidate.source) as ClawdbotPluginModule;