@frockbot/applet-sdk 0.7.177 → 0.7.179
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 +83 -99
- package/package.json +1 -1
- package/src/build/plugin.ts +1 -2
package/README.md
CHANGED
|
@@ -1,113 +1,97 @@
|
|
|
1
1
|
# @frockbot/applet-sdk
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
kit on the theme tokens, a linter, and the build pipeline the cloud build
|
|
6
|
-
service runs.
|
|
7
|
-
|
|
8
|
-
An Applet is authored with the `applet_*` tools, built by `apps/applet-build`,
|
|
9
|
-
and mounted as a Durable Object facet from an immutable artifact. There is no
|
|
10
|
-
CLI: nothing outside the service builds an Applet, and no Computer is involved
|
|
11
|
-
at any point.
|
|
3
|
+
What a FrockBot Plugin is written against, and the build that turns a
|
|
4
|
+
Plugin's source into the module and manifest a publish stores (ADR 0026).
|
|
12
5
|
|
|
13
6
|
## Entry points
|
|
14
7
|
|
|
15
|
-
| Import | For
|
|
16
|
-
| ----------------------------------- |
|
|
17
|
-
| `@frockbot/applet-sdk/
|
|
18
|
-
| `@frockbot/applet-sdk/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
8
|
+
| Import | For |
|
|
9
|
+
| ----------------------------------- | ------------------------------------------------------------------------------------------ |
|
|
10
|
+
| `@frockbot/applet-sdk/plugin` | types only: `PluginModule`, `PluginContext` and the rest — a Plugin's `plugin.ts` |
|
|
11
|
+
| `@frockbot/applet-sdk/build/plugin` | `runPluginBuildV1` — the four stages, for the build service and the seeded Plugins' script |
|
|
12
|
+
|
|
13
|
+
## A Plugin
|
|
14
|
+
|
|
15
|
+
A Plugin is a directory: a `plugin.json` descriptor, a `plugin.ts` module,
|
|
16
|
+
and any `.ts` files beside it that the module imports. `plugin.ts` has no
|
|
17
|
+
default export. It exports `tools` and `execute` by name, and may export
|
|
18
|
+
`hooks`, `services`, `triggers`, `views`, `cards` and `modelProviders`
|
|
19
|
+
(`PluginModule`). `tools` may be empty: a Plugin that only serves hooks
|
|
20
|
+
builds.
|
|
21
|
+
|
|
22
|
+
`@frockbot/applet-sdk/plugin` is declarations only, so it is imported with
|
|
23
|
+
`import type`; a value import of it fails the bundle stage.
|
|
24
|
+
`app/plugins/sdk-types.test.ts` pins its `PluginContext`, hook events, grants
|
|
25
|
+
and hook payloads to the kernel's own types, so a Plugin that type-checks
|
|
26
|
+
here sees the `ctx` the kernel builds.
|
|
27
|
+
|
|
28
|
+
A model provider (`PluginModelProvider`, ADR 0032) answers a normalized model
|
|
29
|
+
request with normalized stream events, and makes its one upstream call
|
|
30
|
+
through `ctx.modelTransport`. The deployment serves a provider only from the
|
|
31
|
+
artifact its own provider catalog names, so this is not a way for a
|
|
32
|
+
Bot-written Plugin to reach a provider.
|
|
33
|
+
|
|
34
|
+
`plugin/template/` is the scaffold a new Plugin starts as, with
|
|
35
|
+
`__PLUGIN_ID__` and `__PLUGIN_NAME__` for `plugin_create` to fill in.
|
|
36
|
+
`scripts/build-applets-assets.ts` carries it into the Worker as
|
|
37
|
+
`app/plugins/template.generated.ts`, and carries `plugin/index.d.ts` into the
|
|
38
|
+
Plugins Skill as `app/plugins/skills/plugins/references/types.md`.
|
|
25
39
|
|
|
26
40
|
## The build
|
|
27
41
|
|
|
28
|
-
`
|
|
29
|
-
directory
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
a
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
is
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
`
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
`
|
|
71
|
-
|
|
72
|
-
The Cloudflare programming model is not hidden: an Applet is a Durable Object
|
|
73
|
-
with SQLite and hibernating sockets. What the SDK does hide is every binding
|
|
74
|
-
name — an author sees `tables`, `tools`, and `this.db`.
|
|
75
|
-
|
|
76
|
-
## Wire protocol
|
|
77
|
-
|
|
78
|
-
JSON frames, at most 64 KB each, decoded by `src/protocol/` at both ends;
|
|
79
|
-
an unknown type, field, or table fails closed. Two versions are spoken on the
|
|
80
|
-
same server, told apart by the socket URL: a page built against v2 opens with
|
|
81
|
-
`v=2`, and a page built before it opens with nothing and is spoken to in v1.
|
|
82
|
-
|
|
83
|
-
| Direction | Frame | Carries |
|
|
84
|
-
| --------------- | ---------- | ------------------------------------------------------------------------------------------- |
|
|
85
|
-
| server → client | `hello` | contract, generationId, viewer, tables, revision, cursor — and in v2, the `snapshot` itself |
|
|
86
|
-
| client → server | `hello` | contract, optional `since` cursor for catch-up; in v2 only on a resume or when asked |
|
|
87
|
-
| server → client | `snapshot` | every row of every table, plus the cursor |
|
|
88
|
-
| server → client | `changes` | ordered row changes, optionally tagged with a client txn id |
|
|
89
|
-
| client → server | `mutate` | one client transaction: insert/update/delete |
|
|
90
|
-
| server → client | `ack` | the resulting rows for that txn |
|
|
91
|
-
| server → client | `reject` | why the txn was refused (the client rolls back) |
|
|
92
|
-
|
|
93
|
-
The host hands the page its credential in an `init` postMessage, and a fresh
|
|
94
|
-
credential later in a `refresh` of the same shape; the page reconnects in
|
|
95
|
-
place rather than being reloaded, and with its cursor on the URL that is the
|
|
96
|
-
`changes` path.
|
|
97
|
-
|
|
98
|
-
A v2 page's first render waits on one frame: the server's `hello` carries the
|
|
99
|
-
snapshot when the URL named no `since` cursor, and the page marks its
|
|
100
|
-
collections ready on it. A reconnect puts `since` on the URL, gets a plain
|
|
101
|
-
`hello`, and asks for `changes` as v1 does. A snapshot that would not fit the
|
|
102
|
-
frame is left out of the hello and the v1 exchange follows.
|
|
42
|
+
`runPluginBuildV1(directory, { mode, id })` is four named stages over one
|
|
43
|
+
directory. A stage that fails stops the run and names itself, with a list of
|
|
44
|
+
`{file, line, column, message, severity}` diagnostics. `check` stops after
|
|
45
|
+
the type checker; `build` goes on to the module and its manifest.
|
|
46
|
+
|
|
47
|
+
1. `descriptor`: `plugin.json` is a JSON object whose `id` matches
|
|
48
|
+
`/^[a-z][a-z0-9-]{0,63}$/` and, when the caller passes `id`, is that id.
|
|
49
|
+
The build reads nothing else from it. The app Worker decodes the full
|
|
50
|
+
descriptor and refuses a publish whose descriptor and manifest disagree
|
|
51
|
+
(`pluginManifestDisagreementV1` in `app/plugins/authoring.ts`).
|
|
52
|
+
2. `typecheck`: every `.ts` file in the directory, strict, against ES2022
|
|
53
|
+
and the DOM lib for `fetch`, `Request` and `Response`, with
|
|
54
|
+
`@frockbot/applet-sdk/plugin` resolved to `plugin/index.d.ts`. The
|
|
55
|
+
directory must hold a `plugin.ts`. Only errors fail the stage.
|
|
56
|
+
3. `bundle`: esbuild makes one unminified ESM module with every import
|
|
57
|
+
inlined. Nothing is external, so a specifier the bundler cannot inline
|
|
58
|
+
fails here, not at mount. `module-paths.ts` rewrites esbuild's module-path
|
|
59
|
+
comments relative to the Plugin's directory, so the same source builds to
|
|
60
|
+
the same bytes wherever it is built.
|
|
61
|
+
4. `describe`: the bundle runs in Miniflare beside a describing Worker, with
|
|
62
|
+
no bindings and no outbound network: every `fetch` is answered with a 403.
|
|
63
|
+
Import-time code runs inside workerd, never in the build's own process.
|
|
64
|
+
What the module exports is the manifest. `tools` must be an array and
|
|
65
|
+
`execute` a function; each tool needs a name matching
|
|
66
|
+
`/^[a-z][a-z0-9_]{0,63}$/` and a description; `hooks`, `triggers` and
|
|
67
|
+
`views` hold functions, `services` any values, each card a `render` and
|
|
68
|
+
each model provider a `stream`. A Plugin declares at most 64 tools, each
|
|
69
|
+
name once.
|
|
70
|
+
|
|
71
|
+
Each describe spawns its own workerd, and `boot.ts` bounds the boot. A
|
|
72
|
+
runtime that is not ready within `BOOT_DEADLINE_MS` (30 seconds), or whose
|
|
73
|
+
spawn fails outright, is a `RuntimeDidNotStart`. The build lets that runtime
|
|
74
|
+
go rather than waiting on it and boots once more; if the second boot does not
|
|
75
|
+
come up either, the stage fails with that as its diagnostic.
|
|
76
|
+
|
|
77
|
+
A build answers the module text and its manifest:
|
|
78
|
+
`{ contract: 1, tools, hooks, services, triggers, views, cards, modelProviders, hashes: { module } }`,
|
|
79
|
+
where `hashes.module` is the SHA-256 of the module.
|
|
80
|
+
|
|
81
|
+
Two callers run it. The build service in `apps/applet-build` runs `check`
|
|
82
|
+
for `plugin_check` and `build` for `plugin_publish`.
|
|
83
|
+
`scripts/build-seeded-plugins.ts` builds each Plugin under
|
|
84
|
+
`app/plugins/seeded/` into the Worker bundle through the same stages.
|
|
103
85
|
|
|
104
86
|
## Tests
|
|
105
87
|
|
|
106
88
|
```sh
|
|
107
|
-
bun
|
|
89
|
+
bun run test
|
|
108
90
|
```
|
|
109
91
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
92
|
+
`test/plugin-build.test.ts` runs `runPluginBuildV1` over the real template,
|
|
93
|
+
which `test/plugin-scaffold.ts` fills in and writes to a temporary directory.
|
|
94
|
+
It covers each stage's failure and diagnostics, identical module bytes from
|
|
95
|
+
different and symlinked roots, and the manifest read off each kind of export.
|
|
96
|
+
Every build test boots workerd through Miniflare, so a run needs to bind a
|
|
97
|
+
local port. The root `bun test` runs this file too.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frockbot/applet-sdk",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.179",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Authoring SDK for FrockBot Applets: schema-first Durable Object server, TanStack DB client, component kit, linter, and the build pipeline.",
|
package/src/build/plugin.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The Plugin build (ADR 0026): four named stages over one directory
|
|
3
|
-
* the Applet build's type checker, bundler and Miniflare boot.
|
|
2
|
+
* The Plugin build (ADR 0026): four named stages over one directory.
|
|
4
3
|
*
|
|
5
4
|
* 1. `descriptor` — `plugin.json` parses and names the Plugin the caller
|
|
6
5
|
* asked for. Nothing more is decided here: the app Worker holds the full
|