@get-bb/plugin-sdk 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -0
- package/bundled-types/bb-plugin-sdk-app.d.ts +1519 -0
- package/bundled-types/bb-plugin-sdk-internal-composer-customization-validation.d.ts +30 -0
- package/bundled-types/bb-plugin-sdk-internal-composer-view.d.ts +10 -0
- package/bundled-types/bb-plugin-sdk-internal-host-policy.d.ts +141 -0
- package/bundled-types/bb-plugin-sdk-testing-app.d.ts +238 -0
- package/bundled-types/bb-plugin-sdk-testing.d.ts +309 -0
- package/bundled-types/bb-plugin-sdk.d.ts +13635 -0
- package/dist/app.js +36 -0
- package/dist/index.js +11 -0
- package/dist/internal/composer-customization-validation.js +238 -0
- package/dist/internal/composer-view.js +7 -0
- package/dist/internal/host-policy.js +261 -0
- package/dist/testing/app.js +1190 -0
- package/dist/testing/index.js +1625 -0
- package/package.json +137 -0
package/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# @get-bb/plugin-sdk
|
|
2
|
+
|
|
3
|
+
The typed facade BB plugin authors compile against. The root preserves the
|
|
4
|
+
complete `BbPluginApi` and `BbSdk` contract; `./app` is the frontend runtime
|
|
5
|
+
that `bb plugin build` replaces with BB's shared implementation.
|
|
6
|
+
|
|
7
|
+
The authoritative contracts are the exported declarations in
|
|
8
|
+
[`src/backend-contract.ts`](src/backend-contract.ts) and
|
|
9
|
+
[`src/app-contract.ts`](src/app-contract.ts). Keep author-facing guidance in
|
|
10
|
+
the built-in `bb-plugin-authoring` skill synchronized with those declarations.
|
|
11
|
+
|
|
12
|
+
## Composer customization
|
|
13
|
+
|
|
14
|
+
Composer UI extensions register through `app.composer.customize(...)`. A
|
|
15
|
+
`ComposerCustomization` can contribute React action and banner components,
|
|
16
|
+
host-rendered `ComposerPlusMenuItem` rows, and `ComposerRichTextSpec` rules.
|
|
17
|
+
Mounted components use `useComposer()` for writes, effects, and input locking,
|
|
18
|
+
and `useComposerView()` for the reactive scope, layout, draft, and run state.
|
|
19
|
+
Any mounted plugin component can use
|
|
20
|
+
`useBbNavigate().openThreadPanel(...)` to request one of the
|
|
21
|
+
same plugin's registered thread-panel actions; it returns false when the
|
|
22
|
+
current surface has no thread side panel.
|
|
23
|
+
|
|
24
|
+
See the
|
|
25
|
+
[`composer-customization` reference plugin](../../examples/plugins/composer-customization/README.md)
|
|
26
|
+
for every region in one small app. The deprecated pre-1.0
|
|
27
|
+
`app.slots.composerAccessory(...)` footer API has been removed; migrate footer
|
|
28
|
+
controls to actions or the plus menu and larger content to banners.
|
|
29
|
+
|
|
30
|
+
## Trusted frontend content scripts
|
|
31
|
+
|
|
32
|
+
Use `app.contentScripts.register({ id, mount })` for ordinary
|
|
33
|
+
bundled TypeScript/JavaScript that enhances the bb app shell without rendering
|
|
34
|
+
a React slot. The host supplies `{ pluginId, generation, signal }`, awaits
|
|
35
|
+
mount setup, and owns abort plus exact-once reverse-order disposal across hash
|
|
36
|
+
reload, disable, removal, failed replacement, and app-window teardown. The old
|
|
37
|
+
generation is disposed before candidate mounts, so generations never overlap.
|
|
38
|
+
Content scripts are trusted same-origin page code, not a sandbox.
|
|
39
|
+
|
|
40
|
+
Static styles should stay in the normal imported `app.css`; scripts may own
|
|
41
|
+
dynamic DOM/style nodes when their disposer removes them. See the
|
|
42
|
+
[`content-script` reference plugin](../../examples/plugins/content-script/README.md)
|
|
43
|
+
for a cleanup-safe editor enhancement.
|
|
44
|
+
|
|
45
|
+
## External plugin tests
|
|
46
|
+
|
|
47
|
+
The packed package includes executable JavaScript and portable declarations
|
|
48
|
+
for `@get-bb/plugin-sdk/testing` and `@get-bb/plugin-sdk/testing/app`; neither subpath
|
|
49
|
+
imports BB workspace packages or source TypeScript at runtime. Install the SDK
|
|
50
|
+
with the test stack used by your plugin (the peer dependencies are optional so
|
|
51
|
+
headless plugins do not install a browser harness):
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
npm install --save-dev @get-bb/plugin-sdk vitest better-sqlite3 zod cron-parser hono
|
|
55
|
+
npm install --save-dev react react-dom @testing-library/react jsdom # frontend tests
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Backend example:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { createFakePluginHost } from "@get-bb/plugin-sdk/testing";
|
|
62
|
+
import plugin from "./server.js";
|
|
63
|
+
|
|
64
|
+
const host = createFakePluginHost({ pluginId: "notes" });
|
|
65
|
+
await plugin(host.bb);
|
|
66
|
+
|
|
67
|
+
await host.harness.behavior.callRpc("list", { query: "today" });
|
|
68
|
+
expect(host.harness.inspection.registrations.rpcMethods).toContain("list");
|
|
69
|
+
await host.harness.lifecycle.dispose();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`harness.behavior` contains deterministic host inputs (RPC/HTTP/CLI calls,
|
|
73
|
+
events, settings, tools, interactions, and schedules), `harness.inspection`
|
|
74
|
+
contains registrations and recorded state, and `harness.lifecycle` owns atomic
|
|
75
|
+
reload and disposal. Every pre-existing direct member remains as an alias for
|
|
76
|
+
source compatibility. A successful `reload(factory)` preserves settings, KV,
|
|
77
|
+
and database state and invalidates the old API only after the replacement
|
|
78
|
+
factory succeeds; a failed factory leaves the old load live.
|
|
79
|
+
|
|
80
|
+
Frontend example (`// @vitest-environment jsdom`):
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
import {
|
|
84
|
+
loadPluginApp,
|
|
85
|
+
mountPluginContentScripts,
|
|
86
|
+
renderSlot,
|
|
87
|
+
} from "@get-bb/plugin-sdk/testing/app";
|
|
88
|
+
|
|
89
|
+
const app = await loadPluginApp(() => import("./app.js"));
|
|
90
|
+
const scripts = await mountPluginContentScripts(app, { pluginId: "notes" });
|
|
91
|
+
const slot = renderSlot(
|
|
92
|
+
app.homepageSections[0]!,
|
|
93
|
+
{ projectId: "proj_1" },
|
|
94
|
+
{
|
|
95
|
+
rpc: { list: () => [] },
|
|
96
|
+
context: { projectId: "proj_1", threadId: null },
|
|
97
|
+
},
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
await slot.behavior.emitRealtime("notes-changed", null);
|
|
101
|
+
expect(slot.inspection.rpcCalls).toHaveLength(1);
|
|
102
|
+
slot.lifecycle.unmount();
|
|
103
|
+
await scripts.lifecycle.dispose();
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`loadPluginApp` installs the runtime before a thunk import and validates all
|
|
107
|
+
registrations. `mountPluginContentScripts` mirrors the host's ordered mount,
|
|
108
|
+
rollback, independent per-window signal, and exact-once disposal. `renderSlot` supplies
|
|
109
|
+
RPC, realtime, settings, navigation, context, and scoped composer behavior,
|
|
110
|
+
then returns Testing Library queries plus the same behavior/inspection/lifecycle
|
|
111
|
+
split. Use a setup-file `installTestPluginRuntime()` only when a static app
|
|
112
|
+
import is unavoidable.
|
|
113
|
+
|
|
114
|
+
## Fidelity boundaries
|
|
115
|
+
|
|
116
|
+
The backend fake matches observable schema-RPC validation/errors and strict
|
|
117
|
+
JSON results, additive events, keyed-registration failures, atomic reload,
|
|
118
|
+
settings, KV/database storage, conditional agent configuration, request input,
|
|
119
|
+
and disposal order. HTTP runs through Hono but does not enforce BB's local or
|
|
120
|
+
token authentication. Background services and schedules run only when driven;
|
|
121
|
+
there are no restart timers or cron sweeps. Storage is process-local in a
|
|
122
|
+
temporary directory, secrets are kept in memory, `bb.sdk` is always bound and
|
|
123
|
+
unstubbed calls throw, and cross-plugin/global collision policy is outside one
|
|
124
|
+
fake host.
|
|
125
|
+
|
|
126
|
+
The frontend harness matches registration validation, content-script mount and
|
|
127
|
+
cleanup ordering, RPC/realtime JSON
|
|
128
|
+
boundaries, panel and slot props, navigation recording, and composer text,
|
|
129
|
+
scope, quote, mention, focus, and clear behavior. It does not reproduce BB
|
|
130
|
+
layout, CSS, persistence, routing, host authentication, crash boundaries, or
|
|
131
|
+
multi-plugin arbitration; use a live BB test for those boundaries.
|
|
132
|
+
|
|
133
|
+
## Declaration surface
|
|
134
|
+
|
|
135
|
+
The complete root declaration flattens the unpublished BB workspace contracts.
|
|
136
|
+
The testing declarations reuse that public `@get-bb/plugin-sdk` root instead of
|
|
137
|
+
embedding a second copy, and no declaration depends on unpublished `@bb/*`
|
|
138
|
+
packages. Genuine npm types (`hono`, `better-sqlite3`, `zod`, React, and Testing
|
|
139
|
+
Library) remain peer imports. Scaffolded plugins still vendor the root/app
|
|
140
|
+
declarations in `types/`; installing this package is needed only when their
|
|
141
|
+
tests import the testing subpaths.
|