@abide/abide 0.40.2 → 0.41.1
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/AGENTS.md +327 -326
- package/CHANGELOG.md +62 -0
- package/README.md +87 -78
- package/package.json +1 -1
- package/src/lib/ui/compile/SSR_ESCAPE.ts +3 -1
- package/src/lib/ui/compile/compileShadow.ts +5 -0
- package/src/lib/ui/compile/destructureBindingNames.ts +38 -0
- package/src/lib/ui/compile/generateBuild.ts +96 -12
- package/src/lib/ui/compile/generateSSR.ts +26 -9
- package/src/lib/ui/compile/lowerContext.ts +29 -9
- package/src/lib/ui/compile/parseTemplate.ts +2 -0
- package/src/lib/ui/compile/renameSignalRefs.ts +19 -2
- package/src/lib/ui/compile/skeletonContext.ts +67 -79
- package/src/lib/ui/compile/templateAnchorAdapter.ts +61 -0
- package/src/lib/ui/compile/templateElementAdapter.ts +44 -0
- package/src/lib/ui/compile/types/TemplateNode.ts +2 -0
- package/src/lib/ui/compile/walkAnchorOrder.ts +57 -0
- package/src/lib/ui/compile/walkElementOrder.ts +60 -0
- package/src/lib/ui/dom/appendSnippet.ts +9 -8
- package/src/lib/ui/dom/applyResolved.ts +3 -4
- package/src/lib/ui/dom/awaitBlock.ts +106 -46
- package/src/lib/ui/dom/buildDetachedRange.ts +30 -0
- package/src/lib/ui/dom/depthZeroNodes.ts +34 -0
- package/src/lib/ui/dom/domAnchorAdapter.ts +29 -0
- package/src/lib/ui/dom/domElementAdapter.ts +20 -0
- package/src/lib/ui/dom/each.ts +33 -17
- package/src/lib/ui/dom/eachAsync.ts +34 -26
- package/src/lib/ui/dom/isElement.ts +6 -0
- package/src/lib/ui/dom/markerDepthDelta.ts +19 -0
- package/src/lib/ui/dom/mountRange.ts +4 -3
- package/src/lib/ui/dom/mountSlot.ts +4 -3
- package/src/lib/ui/dom/on.ts +6 -1
- package/src/lib/ui/dom/replaceRange.ts +24 -0
- package/src/lib/ui/dom/skeleton.ts +35 -92
- package/src/lib/ui/dom/switchBlock.ts +13 -10
- package/src/lib/ui/dom/types/EachRow.ts +9 -2
- package/src/lib/ui/dom/when.ts +13 -10
- package/src/lib/ui/runtime/RANGE_MARKER.ts +16 -0
- package/src/lib/ui/runtime/batch.ts +22 -0
- package/src/lib/ui/runtime/clientPage.ts +3 -8
- package/src/lib/ui/runtime/createDoc.ts +9 -13
- package/src/lib/ui/seedResolved.ts +28 -0
- package/src/lib/ui/startClient.ts +6 -4
- package/src/lib/ui/types/ResolvedFrame.ts +15 -0
package/AGENTS.md
CHANGED
|
@@ -1,403 +1,404 @@
|
|
|
1
1
|
# AGENTS.md — abide complete surface map
|
|
2
2
|
|
|
3
|
-
> The exhaustive index of abide's public surface: every `exports` key appears
|
|
4
|
-
> grouped by namespace, with its import specifier and a one-line spec
|
|
5
|
-
> grasps the whole API in one read
|
|
6
|
-
>
|
|
7
|
-
> glossary
|
|
8
|
-
>
|
|
9
|
-
>
|
|
10
|
-
>
|
|
11
|
-
>
|
|
12
|
-
>
|
|
3
|
+
> The exhaustive index of abide's public surface: every `exports` key appears
|
|
4
|
+
> once, grouped by namespace, with its import specifier and a one-line spec, so
|
|
5
|
+
> an agent grasps the whole API in one read. The README is the curated
|
|
6
|
+
> three-primitive intro (RPCs, sockets, components); this map is complete.
|
|
7
|
+
> `CONTEXT.md` is the glossary; `docs/adr/` holds the rationale.
|
|
8
|
+
>
|
|
9
|
+
> **No barrels.** Every public name has its own module path —
|
|
10
|
+
> `@abide/abide/server/GET`, `@abide/abide/shared/cache`, `@abide/abide/ui/scope`. The namespace
|
|
11
|
+
> marks the side a name runs on: `@abide/abide/server/*` is server-only,
|
|
12
|
+
> `@abide/abide/ui/*` is client-only, `@abide/abide/shared/*` is isomorphic (same callable,
|
|
13
|
+
> same behaviour on both sides — the bundler swaps the runtime). There is no
|
|
14
|
+
> umbrella `index.ts`, so importing one name never drags in side-effecting
|
|
15
|
+
> siblings.
|
|
16
|
+
>
|
|
17
|
+
> Package `@abide/abide`, runtime Bun ≥ 1.3.0, one direct dependency
|
|
18
|
+
> (`typescript`); `tailwindcss` + `bun-plugin-tailwind` are optional peers.
|
|
19
|
+
> Import specifiers below are `package.json` `exports` keys, not file paths —
|
|
20
|
+
> `@abide/abide/server/GET` resolves to `src/lib/server/GET.ts`.
|
|
13
21
|
|
|
14
22
|
## The premise
|
|
15
23
|
|
|
16
|
-
One typed verb declaration fans out to
|
|
24
|
+
One typed verb declaration fans out to every consumer:
|
|
25
|
+
|
|
17
26
|
```text
|
|
18
27
|
getMessages = GET(fn, { inputSchema })
|
|
19
28
|
│
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
29
|
+
┌─────────────┬─────────┼──────────┬──────────────┐
|
|
30
|
+
▼ ▼ ▼ ▼ ▼
|
|
31
|
+
SSR call browser MCP tool CLI sub- OpenAPI
|
|
32
|
+
cache(fn)() fetch (read) command operation
|
|
33
|
+
proxy
|
|
23
34
|
```
|
|
24
35
|
|
|
25
|
-
A
|
|
26
|
-
never auto-exposes to MCP — it
|
|
36
|
+
A Standard Schema unlocks the CLI for every verb and MCP for read-only verbs
|
|
37
|
+
(`GET` / `HEAD`); a mutating verb never auto-exposes to MCP — it opts in with
|
|
38
|
+
`clients: { mcp: true }`. The same gating applies to sockets: a schema flips
|
|
39
|
+
the MCP/CLI read faces on.
|
|
27
40
|
|
|
28
41
|
## File-based conventions
|
|
29
42
|
|
|
30
|
-
The bundler reads these paths by convention:
|
|
31
|
-
|
|
32
|
-
| Path
|
|
33
|
-
|
|
|
34
|
-
| `src/server/rpc/<name>.ts`
|
|
35
|
-
| `src/server/sockets/<name>.ts`
|
|
36
|
-
| `src/server/
|
|
37
|
-
| `src/
|
|
38
|
-
| `src/
|
|
39
|
-
| `src/
|
|
40
|
-
| `src/
|
|
41
|
-
| `src/
|
|
42
|
-
| `src/ui/
|
|
43
|
-
| `src
|
|
44
|
-
| `
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
`$mcp` → `src/mcp/`, `$cli` → `src/cli/`.
|
|
43
|
+
The bundler reads these paths by convention (`cwd` is the app root):
|
|
44
|
+
|
|
45
|
+
| Path | Meaning |
|
|
46
|
+
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
47
|
+
| `src/server/rpc/<name>.ts` | One RPC verb per file; export name = filename = URL under `/rpc/`. Server: real handler; client: `remoteProxy`. |
|
|
48
|
+
| `src/server/sockets/<name>.ts` | One socket per file; export name = filename. Server: `defineSocket`; client: `socketProxy`. |
|
|
49
|
+
| `src/server/config.ts` | Optional. Eager-imported for boot-time `env()` validation (virtual `abide:config`). |
|
|
50
|
+
| `src/mcp/prompts/*.md` | MCP prompts; frontmatter (description, JSON Schema) + `{{name}}` body. Rewritten to `definePrompt`. |
|
|
51
|
+
| `src/mcp/resources/**` | MCP resource files, gzip-embedded into the standalone binary. |
|
|
52
|
+
| `src/app.ts` | Optional `AppModule` — `init` / `handle` / `handleError` / `health` / `forwardHeaders` hooks (virtual `abide:app`). |
|
|
53
|
+
| `src/bundle/window.ts` | Optional desktop-bundle config (`BundleWindow`); baked into the launcher. |
|
|
54
|
+
| `src/bundle/disconnected.abide` | Optional custom connect screen; falls back to the built-in component. |
|
|
55
|
+
| `src/ui/pages/**/page.abide` | A page; its folder path is the route. `[id]` folder = dynamic segment → `page.params.id`. |
|
|
56
|
+
| `src/ui/pages/**/layout.abide` | A layout wrapping pages at/below its folder; its `<slot/>` is the router outlet. |
|
|
57
|
+
| `src/ui/public/**` | Static assets served at site root; gzip-embedded into the standalone binary. |
|
|
58
|
+
| `src/.abide/*.d.ts` | Generated types written each build — `routes`, `rpc`, `sockets`, `health`, `publicAssets`, and test surfaces. |
|
|
59
|
+
| `dist/_app/` | Client bundle output (hashed chunks; prod adds precompressed `.gz` siblings). |
|
|
48
60
|
|
|
49
61
|
## CLI
|
|
50
62
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
Tests preload the framework: `preload = ["@abide/abide/preload"]` in `bunfig.toml`
|
|
66
|
-
registers `.abide` compilation so `bun test` runs the same runtime as the server.
|
|
67
|
-
|
|
68
|
-
## Authoring contracts
|
|
69
|
-
|
|
70
|
-
What you write into each convention path, and the contract the framework holds
|
|
71
|
-
you to. The per-export specs below are exhaustive; this is the shape of the code
|
|
72
|
-
that produces them.
|
|
73
|
-
|
|
74
|
-
### RPC verb — `src/server/rpc/<name>.ts`
|
|
75
|
-
|
|
76
|
-
- One `export const <name> = METHOD(handler, opts?)` per file (`METHOD` ∈ `GET`/`POST`/`PUT`/`PATCH`/`DELETE`/`HEAD`); the file path is the route.
|
|
77
|
-
- The handler receives the **validated** input — `InferOutput<inputSchema>`, or `{}` when schemaless — and may read request scope via `request()` / `cookies()`. It returns `json()`, `jsonl()`, `sse()`, `error()`, `redirect()`, or a raw `Response`; the union of those branches is the verb's typed result.
|
|
78
|
-
- `opts`: `{ inputSchema?, outputSchema?, filesSchema?, clients?: { browser, mcp, cli }, crossOrigin?, maxBodySize?, timeout? }`. A Standard Schema flips MCP + CLI on automatically; a **mutating** verb still needs explicit `clients: { mcp: true }`. `crossOrigin: true` exempts a mutating verb from the same-origin CSRF check. `timeout` (ms) bounds the handler on every surface (504 past it). `filesSchema` validates multipart `File` parts (the caller sends `FormData`).
|
|
79
|
-
- Query args arrive as **strings** — validate with `z.coerce.*`.
|
|
80
|
-
- Consume four ways: `cache(verb)(args)` in-process (SSR, warm hydration), the same call over a swapped `fetch` in the browser, `verb.raw(args)` for the undecoded `Response`, `verb.stream(args)` for an iterable body view.
|
|
81
|
-
|
|
82
|
-
### Socket — `src/server/sockets/<name>.ts`
|
|
83
|
-
|
|
84
|
-
- One `export const <name> = socket({ schema, tail?, ttl?, clientPublish?, clients? })`; the file name is the topic.
|
|
85
|
-
- `.publish(msg)` validates then broadcasts; `.tail(n?)` replays the retained window then streams live; bare `for await` is live-only. `tail` = frames retained, `ttl` = frame expiry (ms), `clientPublish` = allow a browser `POST` (default off, so route writes through a verb that validates first).
|
|
86
|
-
- HTTP face `/__abide/sockets/<name>`: `GET` returns the tail, `POST` publishes (gated by `clientPublish`).
|
|
87
|
-
- Consume in a component with `tail(socket)` (latest-wins) or `tail(socket, { last: n })` (window).
|
|
88
|
-
|
|
89
|
-
### Page & layout — `src/ui/pages/**`
|
|
90
|
-
|
|
91
|
-
- `page.abide` is a route; the folder path is the URL. `[id]` segments become params read off the `page` proxy (`page.params.id`), typed via generated `src/.abide/routes.d.ts`, reactive across navigation.
|
|
92
|
-
- `layout.abide` wraps every page at or below its folder; its `<slot/>` (compiled to an outlet) holds the nested page or child layout.
|
|
93
|
-
- Build links with `url('/pages/product/[id]', { id })` and move with `navigate(href)`.
|
|
94
|
-
|
|
95
|
-
### App module & config — `src/app.ts`, `src/server/config.ts` (both optional)
|
|
63
|
+
```text
|
|
64
|
+
abide scaffold <name> scaffold the bundled template, install deps, start dev
|
|
65
|
+
abide dev build client + run server with hot reload
|
|
66
|
+
abide build single client build into dist/_app
|
|
67
|
+
abide start run the production server against a built dist/
|
|
68
|
+
abide run <file> [...] run a script under the abide preload (same runtime)
|
|
69
|
+
abide compile build a standalone server executable
|
|
70
|
+
abide cli build a thin CLI binary (remote client + bundled server)
|
|
71
|
+
abide bundle build a movable self-contained desktop app bundle
|
|
72
|
+
abide check type-check every .abide template + props
|
|
73
|
+
abide lsp run the .abide language server over stdio (JSON-RPC)
|
|
74
|
+
abide init-agent write/refresh the CLAUDE.md pointer to this surface map
|
|
75
|
+
```
|
|
96
76
|
|
|
97
|
-
|
|
98
|
-
|
|
77
|
+
`bun test` in a scaffolded app preloads abide via `bunfig.toml`
|
|
78
|
+
(`[test] preload = ["@abide/abide/preload"]`) so `.abide` modules resolve.
|
|
99
79
|
|
|
100
|
-
|
|
80
|
+
## Authoring contracts
|
|
101
81
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
82
|
+
**RPC verb** — `export const <name> = GET(handler, opts?)` (same shape for
|
|
83
|
+
`POST` / `PUT` / `PATCH` / `DELETE` / `HEAD`). The handler receives the parsed
|
|
84
|
+
args bag (`InferOutput<inputSchema>`, merged with validated files when
|
|
85
|
+
`filesSchema` is set), may read `request()` / `cookies()` / `server()` from
|
|
86
|
+
request scope, and returns `json` / `jsonl` / `sse` / `error` / `redirect` or a
|
|
87
|
+
raw `Response`. `opts`: `inputSchema` (validates args, infers the type, gates
|
|
88
|
+
CLI + read-MCP), `outputSchema` (documents the 200 body for OpenAPI/MCP),
|
|
89
|
+
`filesSchema` (multipart File parts), `clients: { browser, mcp, cli }` (explicit
|
|
90
|
+
surface targeting; explicit wins over schema auto-flip), `crossOrigin` (exempt
|
|
91
|
+
a mutating verb from the same-origin gate), `maxBodySize` (per-verb 413
|
|
92
|
+
ceiling), `timeout` (handler deadline in ms; 504 on every surface). Query args
|
|
93
|
+
arrive as strings — use `z.coerce.*`. Consume four ways: `cache(verb)(args)`
|
|
94
|
+
in-process, the swapped browser `fetch`, `verb.raw(args)` for the `Response`,
|
|
95
|
+
`verb.stream(args)` to iterate a streaming body.
|
|
96
|
+
|
|
97
|
+
**Socket** — `export const <name> = socket({ schema?, tail?, ttl?,
|
|
98
|
+
clientPublish?, clients? })`. `tail` retains the last N frames for late joiners
|
|
99
|
+
and the read faces; `ttl` lazily evicts frames older than N ms; `clientPublish`
|
|
100
|
+
(default off) gates browser publishes; `schema` validates publishes
|
|
101
|
+
synchronously and flips MCP/CLI on. Isomorphic `AsyncIterable<T>`: bare
|
|
102
|
+
iteration is the live stream, `.tail(count?)` seeds from retention,
|
|
103
|
+
`.publish(msg)` fans out in-process + over the multiplexed ws.
|
|
104
|
+
|
|
105
|
+
**Page / layout** — a `[id]` folder segment becomes `page.params.id`. A layout's
|
|
106
|
+
`<slot/>` is the outlet the next layer fills. Read `page` (route, params, url,
|
|
107
|
+
navigating) and call `navigate(path)` for SPA transitions.
|
|
108
|
+
|
|
109
|
+
**App / config** — `src/app.ts` default-exports an `AppModule`; `src/server/config.ts`
|
|
110
|
+
runs `env(schema)` at boot.
|
|
111
|
+
|
|
112
|
+
**Isomorphism move** — wrap an SSR read in `cache(fn)()` so the value serializes
|
|
113
|
+
into the document and the client hydrates warm instead of refetching.
|
|
107
114
|
|
|
108
115
|
## .abide template grammar
|
|
109
116
|
|
|
110
|
-
A
|
|
111
|
-
|
|
112
|
-
component-scoped `<style>`. Ambient in
|
|
113
|
-
`props`, `effect`, `html`,
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
|
142
|
-
|
|
|
143
|
-
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
|
148
|
-
|
|
|
149
|
-
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
### RPC verbs — @documentation rpc
|
|
176
|
-
|
|
177
|
-
- `@abide/abide/server/GET` — HTTP verb helper; the bundler rewrites `export const x = GET(fn, opts)` in `src/server/rpc/<file>.ts` to `defineVerb` server-side and `remoteProxy` client-side.
|
|
178
|
-
- `@abide/abide/server/POST` — as `GET`, for `POST`.
|
|
179
|
-
- `@abide/abide/server/PUT` — as `GET`, for `PUT`.
|
|
180
|
-
- `@abide/abide/server/PATCH` — as `GET`, for `PATCH`.
|
|
181
|
-
- `@abide/abide/server/DELETE` — as `GET`, for `DELETE`.
|
|
182
|
-
- `@abide/abide/server/HEAD` — as `GET`, for `HEAD`.
|
|
183
|
-
- `@abide/abide/server/rpc/defineVerb` — the verb factory (plumbing): handler + options (`inputSchema`, `outputSchema`, `filesSchema`, `clients`, `timeout`, `maxBodySize`, `crossOrigin`); returns a `RemoteFunction` — plain call decodes by Content-Type and throws `HttpError` on non-2xx, `.raw(args)` returns the `Response`, `.stream(args)` an iterable body view; auto-exposes to CLI/MCP per schema + method.
|
|
184
|
-
|
|
185
|
-
### Response helpers — @documentation response
|
|
186
|
-
|
|
187
|
-
- `@abide/abide/server/json` — JSON `Response`, `Cache-Control: no-store`; `undefined` → 204; phantom `TypedResponse` brand carries the return type.
|
|
188
|
-
- `@abide/abide/server/jsonl` — wraps `AsyncIterable<Frame>` as JSON Lines; frame errors emit a `{"$error":...}` line; cancellation flows to `iter.return()`.
|
|
189
|
-
- `@abide/abide/server/sse` — wraps `AsyncIterable<Frame>` as Server-Sent Events; 15s keepalive comments, error frames as `event: error`.
|
|
190
|
-
- `@abide/abide/server/error` — plain-text error `Response(status, message?, init?)`; defaults to the standard status text; `TypedResponse<never>` so error branches union cleanly.
|
|
191
|
-
- `@abide/abide/server/redirect` — redirect `Response(url, status=302, init?)`; relative URLs allowed, 301/302/303/307/308, `TypedResponse<never>`.
|
|
117
|
+
A component file is `<script>` (module-level JS: imports, handlers,
|
|
118
|
+
reactive declarations) + optional `<template name="…">` snippet definitions +
|
|
119
|
+
markup + an optional component-scoped `<style>`. Ambient in-scope names need no
|
|
120
|
+
import: `scope`, `props` / `prop`, `effect`, `html`, `snippet`.
|
|
121
|
+
|
|
122
|
+
**Reactive state**
|
|
123
|
+
|
|
124
|
+
| Form | Meaning |
|
|
125
|
+
| ---------------------------------- | ---------------------------------------------------------------------------------- |
|
|
126
|
+
| `scope().state(v)` | Writable reactive cell (`{ value }`); the sole writable surface. |
|
|
127
|
+
| `scope().computed(fn)` | Read-only derived cell; re-runs when its reads change. |
|
|
128
|
+
| `scope().linked(initial, reseed?)` | Cell bound to a reactive-document path; reflects/drives the root doc. |
|
|
129
|
+
| `effect(fn)` | Runs now, re-runs on dep change; may return a teardown; returns a disposer. |
|
|
130
|
+
| `props()` / `prop(name)` | Read the component's props (thunks for reactivity), e.g. `const { id } = props()`. |
|
|
131
|
+
|
|
132
|
+
**Bindings**
|
|
133
|
+
|
|
134
|
+
| Form | Meaning |
|
|
135
|
+
| --------------------------- | -------------------------------------------------------------------------------------------- |
|
|
136
|
+
| `{expr}` | Escaped text interpolation; raw markup via the `html` tag; `{snippet(args)}` mounts a snippet. |
|
|
137
|
+
| `name={expr}` | Reactive attribute (boolean `true` sets bare, falsy removes). |
|
|
138
|
+
| `on<event>={fn}` | Event listener, e.g. `onclick={handler}`. |
|
|
139
|
+
| `bind:value={x}` | Two-way input binding. |
|
|
140
|
+
| `bind:checked={x}` | Two-way checkbox binding. |
|
|
141
|
+
| `bind:group={x}` | Radio/checkbox group (radio → one value, checkbox → array). |
|
|
142
|
+
| `bind:value={{ get, set }}` | Writable computed at the binding site. |
|
|
143
|
+
| `{...expr}` | Spread keys as attributes (elements) or props (components). |
|
|
144
|
+
| `attach={fn}` | Build-time element attachment with optional teardown. |
|
|
145
|
+
|
|
146
|
+
**Control flow** — native `<template>` tags:
|
|
147
|
+
|
|
148
|
+
| Form | Meaning |
|
|
149
|
+
| ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
|
150
|
+
| `<template if={c}>` / `<template elseif={c}>` / `<template else>` | Conditional, source-order, re-evaluated reactively. |
|
|
151
|
+
| `<template each={list} as="x" key="x.id" index="i">` | Keyed list; reorder/re-key updates rows in place; `index` is reactive. |
|
|
152
|
+
| `<template each await={asyncIter} as="x" key="…">` | Async keyed list; rows append as the iterator yields. |
|
|
153
|
+
| `<template await={p}>` / `<template then="v">` / `<template catch="e">` / `<template finally>` | Promise branches; `await={p} then="v"` on one tag renders inline (blocking) on the server. |
|
|
154
|
+
| `<template switch={s}>` / `<template case="v">` / `<template default>` | First strict (`===`) match wins. |
|
|
155
|
+
| `<template try>` / `<template catch="e">` / `<template finally>` | Synchronous render error boundary. |
|
|
156
|
+
| `<template name="row" args={item}>` … `{row(item)}` | Snippet definition + call. |
|
|
157
|
+
|
|
158
|
+
**Components & slots** — a capitalised tag (`<Card title={x}>`) mounts a child;
|
|
159
|
+
attributes become props, children fill the child's `<slot>` (with fallback when
|
|
160
|
+
empty). `<style>` is scoped to the component and its children. Component files
|
|
161
|
+
end in `.abide`. `then`/`each` value names lexically shadow same-named
|
|
162
|
+
component state inside the block.
|
|
163
|
+
|
|
164
|
+
## Server surface — abide/server/\* (server-only)
|
|
165
|
+
|
|
166
|
+
### RPC — @documentation rpc
|
|
167
|
+
|
|
168
|
+
- `@abide/abide/server/GET` — declare a `GET` verb; args from the query string. Schema auto-exposes CLI + read-MCP.
|
|
169
|
+
- `@abide/abide/server/POST` — declare a `POST` verb; args from JSON/form/multipart body (body wins on collision).
|
|
170
|
+
- `@abide/abide/server/PUT` — declare a `PUT` verb (body args; mutating).
|
|
171
|
+
- `@abide/abide/server/PATCH` — declare a `PATCH` verb (body args; mutating).
|
|
172
|
+
- `@abide/abide/server/DELETE` — declare a `DELETE` verb (query args; mutating).
|
|
173
|
+
- `@abide/abide/server/HEAD` — declare a `HEAD` verb (query args; read-only, headers-only response).
|
|
174
|
+
|
|
175
|
+
### Response — @documentation response
|
|
176
|
+
|
|
177
|
+
- `@abide/abide/server/json` — `json(data, init?)`: JSON `TypedResponse` (`Cache-Control: no-store`); `undefined` → 204.
|
|
178
|
+
- `@abide/abide/server/jsonl` — `jsonl(asyncIterable, init?)`: JSONL stream, one value per line; errors emit a `{"$error"}` final line.
|
|
179
|
+
- `@abide/abide/server/sse` — `sse(asyncIterable, init?)`: Server-Sent Events with 15s keepalive comments; errors as an `error` event.
|
|
180
|
+
- `@abide/abide/server/error` — `error(status, message?, init?)`: plain-text error `TypedResponse<never>` (narrows out of the success union).
|
|
181
|
+
- `@abide/abide/server/redirect` — `redirect(url, status=302, init?)`: redirect accepting relative URLs; `TypedResponse<never>`.
|
|
192
182
|
|
|
193
183
|
### Request scope — @documentation request-scope
|
|
194
184
|
|
|
195
|
-
- `@abide/abide/server/request` — the inbound `Request`
|
|
196
|
-
- `@abide/abide/server/cookies` — `Bun.CookieMap
|
|
197
|
-
- `@abide/abide/server/server` — the active `Bun.serve` instance (
|
|
185
|
+
- `@abide/abide/server/request` — `request()`: the inbound `Request` from request-scoped ALS; throws outside scope.
|
|
186
|
+
- `@abide/abide/server/cookies` — `cookies()`: live `Bun.CookieMap`; writes flush to `Set-Cookie`; throws outside scope.
|
|
187
|
+
- `@abide/abide/server/server` — `server()`: the active `Bun.serve` instance (in-process shim for CLI/MCP/test dispatch).
|
|
198
188
|
|
|
199
189
|
### Configuration — @documentation configuration
|
|
200
190
|
|
|
201
|
-
- `@abide/abide/server/env` — validate `
|
|
202
|
-
|
|
203
|
-
### Reachability — @documentation observability
|
|
204
|
-
|
|
205
|
-
- `@abide/abide/server/reachable` — server-only probe of an external host: awaits a `HEAD` (`ABIDE_REACHABLE_TIMEOUT`), then background-polls at `ABIDE_REACHABLE_TTL`; returns a boolean, status-agnostic (any completed HTTP counts).
|
|
191
|
+
- `@abide/abide/server/env` — `env(schema)`: validate `process.env` against a Standard Schema at boot (synchronous; reports all issues).
|
|
206
192
|
|
|
207
193
|
### Sockets — @documentation sockets
|
|
208
194
|
|
|
209
|
-
- `@abide/abide/server/socket` — `
|
|
210
|
-
- `@abide/abide/server/sockets/defineSocket` — server socket factory (plumbing): `name` + `{ tail, ttl, schema, clientPublish, clients }`; `.publish(msg)` validates then broadcasts via `server.publish`, `.tail(count?, hooks?)` replays history then streams live, bare iteration is live-only; auto-MCP/CLI when a schema is present.
|
|
195
|
+
- `@abide/abide/server/socket` — `socket({ schema?, tail?, ttl?, clientPublish?, clients? })`: declare a broadcast topic; isomorphic `Socket<T>`.
|
|
211
196
|
|
|
212
197
|
### Agent — @documentation agent
|
|
213
198
|
|
|
214
|
-
- `@abide/abide/server/agent` —
|
|
199
|
+
- `@abide/abide/server/agent` — `agent(engine, messages)`: run an `AgentEngine` against the request's MCP surface; yields `AgentFrame`s (wrap in `jsonl`/`sse`). Exports the `AgentEngine` / `AgentSurface` / `NeutralMessage` / `AgentFrame` types; provider engines ship in `@abide/<provider>`.
|
|
215
200
|
|
|
216
|
-
###
|
|
201
|
+
### Observability — @documentation observability
|
|
217
202
|
|
|
218
|
-
- `@abide/abide/server/
|
|
219
|
-
- `@abide/abide/server/prompts/renderPromptTemplate` — substitute `{{name}}` placeholders in a markdown template from a `Record<string,string>`; missing args render empty.
|
|
203
|
+
- `@abide/abide/server/reachable` — `reachable(host)`: cached outbound reachability HEAD (first call probes, then polls every TTL); any HTTP response counts as up. Tuned by `ABIDE_REACHABLE_TTL` / `ABIDE_REACHABLE_TIMEOUT`.
|
|
220
204
|
|
|
221
|
-
###
|
|
205
|
+
### Plumbing — @documentation plumbing
|
|
222
206
|
|
|
223
|
-
- `@abide/abide/server/AppModule` —
|
|
224
|
-
- `@abide/abide/server/InspectorContext` —
|
|
207
|
+
- `@abide/abide/server/AppModule` — type of `src/app.ts`: optional `forwardHeaders`, `init`, `handle`, `handleError`, `health` hooks.
|
|
208
|
+
- `@abide/abide/server/InspectorContext` — type of the capability bundle the core injects into `@abide/inspector` when `ABIDE_ENABLE_INSPECTOR=true`.
|
|
209
|
+
- `@abide/abide/server/rpc/defineVerb` — `defineVerb(method, url, handler, opts?)`: low-level builder the GET/POST/… helpers wrap.
|
|
210
|
+
- `@abide/abide/server/sockets/defineSocket` — `defineSocket(name, opts?)`: server-side `Socket` construction (per-subscriber queue, shared retained tail).
|
|
225
211
|
|
|
226
|
-
## Isomorphic surface — abide/shared
|
|
212
|
+
## Isomorphic surface — abide/shared/\* (same callable both sides)
|
|
227
213
|
|
|
228
|
-
###
|
|
214
|
+
### Cache — @documentation cache
|
|
229
215
|
|
|
230
|
-
- `@abide/abide/shared/
|
|
216
|
+
- `@abide/abide/shared/cache` — `cache(fn, opts?)`: coalesce/memoize a remote verb or producer per store (request-scoped server, tab-scoped client). `opts`: `global` (process store), `ttl`, `swr`. Methods: `cache.invalidate`, `cache.on`, `cache.patch`. Warm SSR reads resolve synchronously on hydrate.
|
|
231
217
|
|
|
232
|
-
###
|
|
218
|
+
### Templating — @documentation templating
|
|
233
219
|
|
|
234
|
-
- `@abide/abide/shared/
|
|
220
|
+
- `@abide/abide/shared/html` — `html` (tagged template or `html(str)`): mark a string as trusted raw HTML so `{expr}` inserts nodes verbatim (no auto-escape).
|
|
221
|
+
- `@abide/abide/shared/snippet` — `snippet(payload)`: brand a snippet payload (client DOM builder / server HTML string) so `{expr}` mounts it.
|
|
235
222
|
|
|
236
|
-
###
|
|
223
|
+
### Response — @documentation response
|
|
237
224
|
|
|
238
|
-
- `@abide/abide/shared/
|
|
225
|
+
- `@abide/abide/shared/HttpError` — `class HttpError extends Error`: thrown by remote calls on non-2xx; carries `status`, `statusText`, the raw `response`.
|
|
239
226
|
|
|
240
|
-
###
|
|
227
|
+
### RPC — @documentation rpc
|
|
241
228
|
|
|
242
|
-
- `@abide/abide/shared/
|
|
243
|
-
- `@abide/abide/shared/snippet` — brand a snippet payload (DOM builder on the client, HTML string on the server) so interpolations mount it instead of escaping.
|
|
229
|
+
- `@abide/abide/shared/withJsonSchema` — `withJsonSchema(schema, toJsonSchema)`: attach a `toJSONSchema()` method (for schemas lacking one) feeding OpenAPI/MCP/CLI/bundle forms.
|
|
244
230
|
|
|
245
231
|
### Page — @documentation page
|
|
246
232
|
|
|
247
|
-
- `@abide/abide/shared/page` — reactive page
|
|
233
|
+
- `@abide/abide/shared/page` — reactive `page` proxy: `{ route, params, url, navigating }`; server reads per-request store, client reads the router snapshot.
|
|
248
234
|
|
|
249
|
-
###
|
|
235
|
+
### URL — @documentation url
|
|
250
236
|
|
|
251
|
-
- `@abide/abide/shared/
|
|
252
|
-
- `@abide/abide/shared/refreshing` — reactive: a cache call holds a value while revalidating, or a stream reconnects with its window retained.
|
|
253
|
-
- `@abide/abide/shared/online` — reactive connectivity: `navigator.onLine` on the client, the request's `OFFLINE_HEADER` on the server.
|
|
254
|
-
- `@abide/abide/shared/health` — reactive backend health: a `reachable` flag polled from `/__abide/health` every 10s while visible, plus app `health()` fields; `navigator.onLine` composes at read.
|
|
237
|
+
- `@abide/abide/shared/url` — `url(path, ...args)`: base-correct, typed in-app URLs for RPCs (args → query), page routes (`[name]` params), and assets; external URLs pass through untouched.
|
|
255
238
|
|
|
256
|
-
###
|
|
239
|
+
### Probes — @documentation probes
|
|
257
240
|
|
|
258
|
-
- `@abide/abide/shared/
|
|
241
|
+
- `@abide/abide/shared/pending` — `pending(selector?, args?)`: reactive — any/specific/exact/tagged call in flight, or a stream awaiting its first frame.
|
|
242
|
+
- `@abide/abide/shared/refreshing` — `refreshing(selector?, args?)`: reactive — a value held while fresh data is in flight (SWR refetch / reconnect with retained value).
|
|
243
|
+
- `@abide/abide/shared/online` — `online()`: reactive connectivity (client `navigator.onLine`; server reads the caller's reported state); reports, never acts.
|
|
259
244
|
|
|
260
245
|
### Observability — @documentation observability
|
|
261
246
|
|
|
262
|
-
- `@abide/abide/shared/
|
|
263
|
-
- `@abide/abide/shared/
|
|
247
|
+
- `@abide/abide/shared/health` — `health()`: reactive backend health (`reachable` + app fields) polled from `/__abide/health` only while read; SSR-seeded.
|
|
248
|
+
- `@abide/abide/shared/log` — `log(...)` / `.warn` / `.error` / `.trace(label, fn)` / `.channel(name)`: request-scoped logger; TSV or JSON (`ABIDE_LOG_FORMAT`).
|
|
249
|
+
- `@abide/abide/shared/trace` — `trace()`: the current request's W3C `traceparent`, or `undefined` outside request scope; isomorphic.
|
|
264
250
|
|
|
265
|
-
###
|
|
251
|
+
### Plumbing — @documentation plumbing
|
|
266
252
|
|
|
267
|
-
- `@abide/abide/shared/createSubscriber` —
|
|
253
|
+
- `@abide/abide/shared/createSubscriber` — `createSubscriber(start)`: open-on-first-read / close-on-last-reader resource lifecycle on the signal core.
|
|
268
254
|
|
|
269
|
-
## UI surface — abide/ui
|
|
255
|
+
## UI surface — abide/ui/\* (client-only)
|
|
270
256
|
|
|
271
257
|
### Reactive state — @documentation reactive-state
|
|
272
258
|
|
|
273
|
-
- `@abide/abide/ui/scope` —
|
|
259
|
+
- `@abide/abide/ui/scope` — `scope(address?)`: resolve the lexical reactive scope; `.state` / `.computed` / `.linked` are the reactive cells (see grammar).
|
|
274
260
|
|
|
275
|
-
###
|
|
261
|
+
### Effect — @documentation effect
|
|
276
262
|
|
|
277
|
-
- `@abide/abide/ui/effect` —
|
|
263
|
+
- `@abide/abide/ui/effect` — `effect(fn)`: run now, re-run on dep change, optional teardown return; returns a disposer.
|
|
278
264
|
|
|
279
265
|
### Tail — @documentation tail
|
|
280
266
|
|
|
281
|
-
- `@abide/abide/ui/tail` — reactive
|
|
282
|
-
|
|
283
|
-
###
|
|
284
|
-
|
|
285
|
-
- `@abide/abide/ui/navigate` —
|
|
286
|
-
|
|
287
|
-
###
|
|
288
|
-
|
|
289
|
-
- `@abide/abide/ui/outbox` — durable FIFO mutation queue for local-first writes
|
|
290
|
-
|
|
291
|
-
###
|
|
292
|
-
|
|
293
|
-
- `@abide/abide/ui/
|
|
294
|
-
- `@abide/abide/ui/
|
|
295
|
-
- `@abide/abide/ui/
|
|
296
|
-
- `@abide/abide/ui/
|
|
297
|
-
- `@abide/abide/ui/
|
|
298
|
-
- `@abide/abide/ui/
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
- `@abide/abide/ui/dom/
|
|
306
|
-
- `@abide/abide/ui/dom/
|
|
307
|
-
- `@abide/abide/ui/dom/
|
|
308
|
-
- `@abide/abide/ui/dom/
|
|
309
|
-
- `@abide/abide/ui/dom/
|
|
310
|
-
- `@abide/abide/ui/dom/
|
|
311
|
-
- `@abide/abide/ui/dom/
|
|
312
|
-
- `@abide/abide/ui/dom/appendStatic` — a static text node,
|
|
313
|
-
- `@abide/abide/ui/dom/
|
|
314
|
-
- `@abide/abide/ui/dom/
|
|
315
|
-
- `@abide/abide/ui/dom/
|
|
316
|
-
- `@abide/abide/ui/dom/
|
|
317
|
-
- `@abide/abide/ui/dom/
|
|
318
|
-
- `@abide/abide/ui/dom/attr` — bind an element attribute to
|
|
319
|
-
- `@abide/abide/ui/dom/on` — attach an event listener
|
|
320
|
-
- `@abide/abide/ui/dom/attach` — run
|
|
321
|
-
- `@abide/abide/ui/dom/each` — keyed list binding
|
|
322
|
-
- `@abide/abide/ui/dom/eachAsync` — async keyed list
|
|
323
|
-
- `@abide/abide/ui/dom/when` — conditional binding
|
|
324
|
-
- `@abide/abide/ui/dom/awaitBlock` — async binding
|
|
325
|
-
- `@abide/abide/ui/dom/tryBlock` — synchronous error boundary
|
|
326
|
-
- `@abide/abide/ui/dom/switchBlock` — multi-branch binding
|
|
327
|
-
- `@abide/abide/ui/dom/applyResolved` — bundle-side consumer of
|
|
328
|
-
- `@abide/abide/ui/
|
|
329
|
-
- `@abide/abide/ui/
|
|
330
|
-
- `@abide/abide/ui/
|
|
331
|
-
- `@abide/abide/ui/
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
- `@abide/abide/
|
|
338
|
-
- `@abide/abide/
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
- `@abide/abide/
|
|
344
|
-
- `@abide/abide/
|
|
345
|
-
- `@abide/abide/
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
- `@abide/abide/
|
|
353
|
-
- `@abide/abide/bundle/
|
|
354
|
-
- `@abide/abide/bundle/
|
|
355
|
-
- `@abide/abide/bundle/
|
|
356
|
-
- `@abide/abide/bundle/
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
- `@abide/abide/
|
|
367
|
-
- `@abide/abide/
|
|
267
|
+
- `@abide/abide/ui/tail` — `tail(subscribable, opts?)`: reactive consumer of a `Socket<T>` or `fn.stream` result (latest-wins, or windowed via `{ last }`); seeds from retention; no-op on the server.
|
|
268
|
+
|
|
269
|
+
### Navigate — @documentation navigate
|
|
270
|
+
|
|
271
|
+
- `@abide/abide/ui/navigate` — `navigate(path, { replace?, keepScroll? })`: client navigation; writes history and re-mounts the page chain.
|
|
272
|
+
|
|
273
|
+
### UI — @documentation ui
|
|
274
|
+
|
|
275
|
+
- `@abide/abide/ui/outbox` — `outbox({ key, send, store, online, onDrop })`: durable FIFO mutation queue for local-first writes; drains while online, retries on reconnect, at-least-once.
|
|
276
|
+
|
|
277
|
+
### Plumbing — @documentation plumbing
|
|
278
|
+
|
|
279
|
+
- `@abide/abide/ui/enterScope` — `enterScope()`: open a fresh lexical scope for an SSR render; returns the previous to restore.
|
|
280
|
+
- `@abide/abide/ui/exitScope` — `exitScope(previous)`: restore the scope `enterScope` saved.
|
|
281
|
+
- `@abide/abide/ui/router` — `router(host, loaders, layoutLoaders, probe?)`: History-API router; diffs the layout/page chain on nav. Returns a disposer.
|
|
282
|
+
- `@abide/abide/ui/startClient` — `startClient(routes, layoutRoutes, target)`: official client entry; reads `__SSR__`, seeds cache, starts the router.
|
|
283
|
+
- `@abide/abide/ui/renderToStream` — `renderToStream(render)`: out-of-order SSR streaming; yields the shell, then one `<abide-resolve>` fragment per streaming await.
|
|
284
|
+
- `@abide/abide/ui/remoteProxy` — `remoteProxy(method, url)`: client substitute for a verb handler; identical `RemoteFunction` shape so `cache()` matches both sides.
|
|
285
|
+
- `@abide/abide/ui/socketProxy` — `socketProxy(name)`: client substitute for a server `Socket`; subscribes over the multiplexed ws channel.
|
|
286
|
+
- `@abide/abide/ui/dom/mount` — mount a top-level page/layout into a host under an ownership scope; returns a disposer.
|
|
287
|
+
- `@abide/abide/ui/dom/mountChild` — mount a child component as a marker-bounded range (no wrapper element); records the instance for hot reload.
|
|
288
|
+
- `@abide/abide/ui/dom/mergeProps` — compose child props from ordered layers (thunks, spreads, slot) via a Proxy; last layer wins.
|
|
289
|
+
- `@abide/abide/ui/dom/spreadProps` — wrap a `{...source}` spread so each key resolves to a live thunk.
|
|
290
|
+
- `@abide/abide/ui/dom/restProps` — the unconsumed rest of a component's props as a live, enumerable object.
|
|
291
|
+
- `@abide/abide/ui/dom/spreadAttrs` — spread an object onto a native element: `on*` keys as listeners, others as reactive attributes.
|
|
292
|
+
- `@abide/abide/ui/dom/readCall` — guarded reactive-doc method call with scope-path error messages.
|
|
293
|
+
- `@abide/abide/ui/dom/hydrate` — adopt server-rendered DOM, attaching listeners/effects in place with a claim cursor.
|
|
294
|
+
- `@abide/abide/ui/dom/text` — a text node whose content tracks `read()`.
|
|
295
|
+
- `@abide/abide/ui/dom/appendText` — reactive `{expr}` interpolation (escaped text, raw `html`, or snippet).
|
|
296
|
+
- `@abide/abide/ui/dom/appendTextAt` — reactive `{expr}` at a skeleton anchor comment, interleaved with element siblings.
|
|
297
|
+
- `@abide/abide/ui/dom/appendSnippet` — `{snippet(args)}` interpolation in a marker-bounded range; re-reads args reactively.
|
|
298
|
+
- `@abide/abide/ui/dom/appendStatic` — a static (non-reactive) text node, created or claimed from SSR.
|
|
299
|
+
- `@abide/abide/ui/dom/cloneStatic` — append a fully-static subtree by template clone (create) or claim (hydrate).
|
|
300
|
+
- `@abide/abide/ui/dom/skeleton` — realize a compiled skeleton under a parent; returns element holes (by path) and anchors (in order).
|
|
301
|
+
- `@abide/abide/ui/dom/anchorCursor` — position a skeleton-anchored control-flow block; parks the claim cursor (hydrate) or returns a create reference.
|
|
302
|
+
- `@abide/abide/ui/dom/mountSlot` — mount a component's `<slot>` content in a marker-bounded range (rendered once).
|
|
303
|
+
- `@abide/abide/ui/dom/outlet` — a layout's `<slot/>` outlet (comment-bounded boundary the router fills with the next layer).
|
|
304
|
+
- `@abide/abide/ui/dom/attr` — bind an element attribute to `read()` (boolean present/absent semantics).
|
|
305
|
+
- `@abide/abide/ui/dom/on` — attach an event listener pinned to its ownership scope.
|
|
306
|
+
- `@abide/abide/ui/dom/attach` — run a build-time attachment against an element with optional teardown.
|
|
307
|
+
- `@abide/abide/ui/dom/each` — keyed list binding; reconciles by key, reorders/re-keys in place; claims SSR rows on hydrate.
|
|
308
|
+
- `@abide/abide/ui/dom/eachAsync` — async keyed list over an `AsyncIterable`; rows append/reconcile as the iterator yields.
|
|
309
|
+
- `@abide/abide/ui/dom/when` — conditional binding; swaps the range on truthy↔falsy flips; adopts the server branch on hydrate.
|
|
310
|
+
- `@abide/abide/ui/dom/awaitBlock` — async binding (pending/then/catch); patches a re-settling `then` value in place rather than rebuilding.
|
|
311
|
+
- `@abide/abide/ui/dom/tryBlock` — synchronous error boundary; builds the catch subtree if the guarded one throws (rendered once).
|
|
312
|
+
- `@abide/abide/ui/dom/switchBlock` — multi-branch binding; picks the first matching case, else default; swaps on subject change.
|
|
313
|
+
- `@abide/abide/ui/dom/applyResolved` — bundle-side consumer of an SSR stream chunk; routes cache-seed/resolve frames into await boundaries.
|
|
314
|
+
- `@abide/abide/ui/runtime/escapeKey` — escape one object key into a JSON-Pointer token (`~`→`~0`, `/`→`~1`).
|
|
315
|
+
- `@abide/abide/ui/runtime/nextBlockId` — the next block id in the current render pass (await/try blocks, document order).
|
|
316
|
+
- `@abide/abide/ui/runtime/enterRenderPass` — mark entry into a render/mount pass; depth 0 resets the block-id counter.
|
|
317
|
+
- `@abide/abide/ui/runtime/exitRenderPass` — mark exit from a render/mount pass, unwinding the depth.
|
|
318
|
+
|
|
319
|
+
## Build / tooling
|
|
320
|
+
|
|
321
|
+
### Building — @documentation building
|
|
322
|
+
|
|
323
|
+
- `@abide/abide/build` — `build(opts)`: build the client bundle into `dist/_app` (optional gzip); returns success.
|
|
324
|
+
- `@abide/abide/compile` — `compile(opts)`: build a standalone server executable (runs the client build first); returns the binary path.
|
|
325
|
+
|
|
326
|
+
### Plumbing — @documentation plumbing
|
|
327
|
+
|
|
328
|
+
- `@abide/abide/preload` — the Bun plugin stack (`abideUiPlugin` + resolver) registered via `bunfig.toml` preload.
|
|
329
|
+
- `@abide/abide/resolver-plugin` — `abideResolverPlugin({ cwd, embedAssets, target })`: resolves the `abide:*` virtual modules and convention dirs.
|
|
330
|
+
- `@abide/abide/ui-plugin` — `abideUiPlugin`: Bun plugin that compiles `.abide` single-file components (with scoped CSS) to ES modules.
|
|
331
|
+
- `@abide/abide/tsconfig` — `tsconfig.app.json`: the app TypeScript config (ESNext, DOM lib, Bun types, strict, no-emit).
|
|
332
|
+
|
|
333
|
+
## Desktop bundle
|
|
334
|
+
|
|
335
|
+
### Bundle — @documentation bundle
|
|
336
|
+
|
|
337
|
+
- `@abide/abide/server/appDataDir` — `appDataDir()`: the running bundle's per-user data directory (keyed by injected program name; cwd-independent). Overridable via `ABIDE_DATA_DIR`.
|
|
338
|
+
- `@abide/abide/bundle/BundleWindow` — type of `src/bundle/window.ts`: window config (title, size, menu, `configSchema`).
|
|
339
|
+
- `@abide/abide/bundle/BundleMenu` — type of a top-level menu-bar menu (label + items).
|
|
340
|
+
- `@abide/abide/bundle/BundleMenuItem` — type of one menu entry (divider, emit event, or navigate URL).
|
|
341
|
+
- `@abide/abide/bundle/onMenu` — `onMenu(name?, handler)`: subscribe to bundle menu clicks (`abide:menu` CustomEvent).
|
|
342
|
+
- `@abide/abide/bundle/bundled` — `bundled()`: true when running inside the abide desktop bundle.
|
|
343
|
+
|
|
344
|
+
## MCP
|
|
345
|
+
|
|
346
|
+
### MCP — @documentation mcp
|
|
347
|
+
|
|
348
|
+
- `@abide/abide/mcp/createMcpServer` — `createMcpServer(opts)`: MCP server bound to the project registry; derives tools from verbs/sockets, handles auth.
|
|
349
|
+
|
|
350
|
+
### Prompts — @documentation plumbing
|
|
351
|
+
|
|
352
|
+
- `@abide/abide/server/prompts/definePrompt` — `definePrompt(name, opts)`: build a `Prompt` from an `src/mcp/prompts/*.md` file (the bundler emits the call).
|
|
353
|
+
- `@abide/abide/server/prompts/renderPromptTemplate` — `renderPromptTemplate(template, args)`: substitute `{{name}}` placeholders (missing → empty string).
|
|
354
|
+
|
|
355
|
+
## Testing
|
|
356
|
+
|
|
357
|
+
### Testing — @documentation testing
|
|
358
|
+
|
|
359
|
+
- `@abide/abide/test/createTestApp` — `createTestApp(opts)`: in-memory test server with a typed `app.rpc.<verb>` / `app.sockets.<name>` surface.
|
|
360
|
+
|
|
361
|
+
### Plumbing — @documentation plumbing
|
|
362
|
+
|
|
363
|
+
- `@abide/abide/test/createScriptedSurface` — `createScriptedSurface(tools)`: a scripted `AgentSurface` for engine tests (records calls, stubs results).
|
|
364
|
+
- `@abide/abide/test/assertAgentFrameConformance` — `assertAgentFrameConformance(stream)`: assert engine frame-stream invariants (done frame, tool use/result pairing).
|
|
368
365
|
|
|
369
366
|
## Generated machine surfaces
|
|
370
367
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
|
374
|
-
|
|
|
375
|
-
| `/
|
|
376
|
-
| `/__abide/
|
|
377
|
-
| `/__abide/
|
|
378
|
-
| `/__abide/
|
|
379
|
-
| `/__abide/
|
|
368
|
+
Runtime routes the framework serves:
|
|
369
|
+
|
|
370
|
+
| Route | Serves |
|
|
371
|
+
| -------------------- | ----------------------------------------------------------------------------------------- |
|
|
372
|
+
| `/openapi.json` | OpenAPI document for the `/rpc/*` HTTP surface. |
|
|
373
|
+
| `/__abide/mcp` | MCP endpoint (POST) routed to `createMcpServer`. |
|
|
374
|
+
| `/__abide/health` | Unauthenticated health payload (`reachable` + `src/app.ts` `health` fields). |
|
|
375
|
+
| `/__abide/sockets` | WebSocket multiplex for every declared socket; `/<name>` adds the HTTP tail/publish face. |
|
|
376
|
+
| `/__abide/cli` | CLI download (`/<platform>`): gzipped tarball with the thin binary + `.env`. |
|
|
377
|
+
| `/__abide/hot/<id>` | Dev-only hot-module endpoint for edited `.abide` components. |
|
|
378
|
+
| `/__abide/identity` | Server identity (app name + version) for CLI connectivity probes. |
|
|
379
|
+
| `/__abide/inspector` | Inspector UI, gated by `ABIDE_ENABLE_INSPECTOR` and the installed package. |
|
|
380
380
|
|
|
381
381
|
## Environment variables
|
|
382
382
|
|
|
383
|
-
| Variable
|
|
384
|
-
|
|
|
385
|
-
| `PORT`
|
|
386
|
-
| `APP_URL`
|
|
387
|
-
| `ABIDE_APP_URL`
|
|
388
|
-
| `ABIDE_APP_TOKEN`
|
|
389
|
-
| `ABIDE_CLIENT_TIMEOUT`
|
|
390
|
-
| `ABIDE_MAX_REQUEST_BODY_SIZE` | Server-wide request body ceiling
|
|
391
|
-
| `ABIDE_IDLE_TIMEOUT`
|
|
392
|
-
| `
|
|
393
|
-
| `
|
|
394
|
-
| `
|
|
395
|
-
| `ABIDE_LOG_FORMAT`
|
|
396
|
-
| `DEBUG`
|
|
397
|
-
| `ABIDE_ENABLE_INSPECTOR`
|
|
398
|
-
| `ABIDE_INSPECT`
|
|
383
|
+
| Variable | Effect |
|
|
384
|
+
| ----------------------------- | --------------------------------------------------------------------------------------------- |
|
|
385
|
+
| `PORT` | Port the server binds (scans upward from the default if taken). |
|
|
386
|
+
| `APP_URL` | Request origin the CLI download writes into the downloaded `.env` (`ABIDE_APP_URL`). |
|
|
387
|
+
| `ABIDE_APP_URL` | Server URL baked into a CLI binary at build time; runtime-overridable. |
|
|
388
|
+
| `ABIDE_APP_TOKEN` | Bearer token written into the CLI download's `.env` when the request carries `Authorization`. |
|
|
389
|
+
| `ABIDE_CLIENT_TIMEOUT` | Client-side RPC fetch timeout in ms (1–600000); shipped via `__SSR__`. |
|
|
390
|
+
| `ABIDE_MAX_REQUEST_BODY_SIZE` | Server-wide request body ceiling in bytes. |
|
|
391
|
+
| `ABIDE_IDLE_TIMEOUT` | Per-connection idle timeout in seconds (0–255, default 10); streaming opts out. |
|
|
392
|
+
| `ABIDE_REACHABLE_TIMEOUT` | `reachable()` probe timeout in ms (100–60000, default 3000). |
|
|
393
|
+
| `ABIDE_REACHABLE_TTL` | `reachable()` poll cadence / freshness in ms (1000–600000, default 30000). |
|
|
394
|
+
| `ABIDE_DATA_DIR` | Override for the app data directory (used as-is, no program name appended). |
|
|
395
|
+
| `ABIDE_LOG_FORMAT` | `json` for one JSON object per line; default is tab-separated. |
|
|
396
|
+
| `DEBUG` | Diagnostic channel gate (e.g. `DEBUG=abide:*` or `abide:build`). |
|
|
397
|
+
| `ABIDE_ENABLE_INSPECTOR` | `true` activates the optional inspector. |
|
|
398
|
+
| `ABIDE_INSPECT` | Enable DevTools inspection in a desktop bundle's webview. |
|
|
399
399
|
|
|
400
400
|
---
|
|
401
401
|
|
|
402
|
-
|
|
403
|
-
`bun run packages/abide/scripts/readmeSurfaces.ts` and update
|
|
402
|
+
This map mirrors `package.json` `exports`. After adding or renaming an export,
|
|
403
|
+
run `bun run packages/abide/scripts/readmeSurfaces.ts` and update the matching
|
|
404
|
+
bullet here.
|