@abide/abide 0.45.0 → 0.47.0
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 +365 -320
- package/CHANGELOG.md +96 -0
- package/README.md +203 -168
- package/package.json +12 -8
- package/src/abideLsp.ts +11 -12
- package/src/abideResolverPlugin.ts +9 -4
- package/src/lib/bundle/disconnected.abide +3 -0
- package/src/lib/cli/printCommandHelp.ts +43 -0
- package/src/lib/cli/printSessionHelp.ts +2 -1
- package/src/lib/cli/{printHelp.ts → printTopLevelHelp.ts} +3 -40
- package/src/lib/cli/runCli.ts +2 -1
- package/src/lib/mcp/buildPrompts.ts +25 -0
- package/src/lib/mcp/dispatchMcpRequest.ts +8 -6
- package/src/lib/mcp/mcpResourceServerSlot.ts +5 -10
- package/src/lib/mcp/mcpSurface.ts +13 -252
- package/src/lib/mcp/mcpTools.ts +187 -0
- package/src/lib/mcp/renderPrompt.ts +25 -0
- package/src/lib/mcp/types/McpSurface.ts +15 -0
- package/src/lib/mcp/types/PromptDescriptor.ts +5 -0
- package/src/lib/mcp/types/PromptMessage.ts +2 -0
- package/src/lib/mcp/types/ToolDescriptor.ts +7 -0
- package/src/lib/mcp/types/ToolResult.ts +2 -0
- package/src/lib/server/agent.ts +1 -1
- package/src/lib/server/jsonl.ts +2 -2
- package/src/lib/server/rpc/defineRpc.ts +7 -1
- package/src/lib/server/runtime/containsTraversal.ts +21 -17
- package/src/lib/server/runtime/createAppAssetServer.ts +11 -16
- package/src/lib/server/runtime/createServer.ts +101 -71
- package/src/lib/server/runtime/createUiPageRenderer.ts +23 -4
- package/src/lib/server/runtime/devClientFingerprint.ts +3 -3
- package/src/lib/server/runtime/devHotModuleResponse.ts +2 -1
- package/src/lib/server/runtime/finalizeResponse.ts +32 -0
- package/src/lib/server/runtime/snapshotEntryFromCache.ts +8 -17
- package/src/lib/server/socket.ts +1 -1
- package/src/lib/server/sockets/createSocketDispatcher.ts +28 -5
- package/src/lib/server/sockets/defineSocket.ts +26 -7
- package/src/lib/server/sockets/types/SocketRegistryEntry.ts +1 -1
- package/src/lib/server/sockets/types/SocketRoutes.ts +1 -1
- package/src/lib/server/sse.ts +2 -2
- package/src/lib/shared/DEFER.ts +8 -0
- package/src/lib/shared/activeCacheStore.ts +2 -2
- package/src/lib/shared/activePage.ts +2 -2
- package/src/lib/shared/attachRpcSelectorMethods.ts +42 -0
- package/src/lib/shared/attachSocketSelectorMethods.ts +34 -0
- package/src/lib/shared/basePath.ts +2 -2
- package/src/lib/shared/baseSlot.ts +6 -5
- package/src/lib/shared/bodyValueForKind.ts +1 -2
- package/src/lib/shared/buildSocketOverChannel.ts +40 -4
- package/src/lib/shared/cache.ts +477 -110
- package/src/lib/shared/cacheEntryFromSnapshot.ts +3 -22
- package/src/lib/shared/cacheStoreSlot.ts +9 -5
- package/src/lib/{server/runtime → shared}/createReachable.ts +2 -2
- package/src/lib/shared/createRemoteFunction.ts +58 -9
- package/src/lib/shared/createResolverSlot.ts +24 -31
- package/src/lib/shared/createSocketSubRegistry.ts +2 -2
- package/src/lib/shared/decodeRefJson.ts +4 -2
- package/src/lib/shared/decodeResponse.ts +8 -6
- package/src/lib/shared/done.ts +14 -0
- package/src/lib/shared/encodeRefJson.ts +4 -2
- package/src/lib/shared/globalCacheStoreSlot.ts +9 -6
- package/src/lib/shared/hydratingSlot.ts +12 -0
- package/src/lib/shared/isLayoutFile.ts +12 -0
- package/src/lib/shared/keyForRemoteCall.ts +2 -1
- package/src/lib/shared/keyPrefixForRemote.ts +12 -0
- package/src/lib/shared/matchRoute.ts +175 -0
- package/src/lib/shared/normalizePathname.ts +11 -0
- package/src/lib/shared/pageSlot.ts +14 -5
- package/src/lib/shared/pageUrlForFile.ts +3 -3
- package/src/lib/shared/parseRouteSegments.ts +16 -7
- package/src/lib/shared/patch.ts +41 -0
- package/src/lib/shared/peek.ts +35 -0
- package/src/lib/shared/prepareRemoteExport.ts +40 -0
- package/src/lib/shared/prepareRpcModule.ts +98 -16
- package/src/lib/shared/prepareSocketModule.ts +11 -15
- package/src/lib/shared/queryStringFromArgs.ts +11 -0
- package/src/lib/shared/reachable.ts +102 -0
- package/src/lib/shared/refresh.ts +22 -0
- package/src/lib/shared/requestScopeSlot.ts +10 -7
- package/src/lib/shared/routeParamsShape.ts +9 -9
- package/src/lib/shared/rpcErrorRegistry.ts +69 -0
- package/src/lib/shared/selectorPrefix.ts +3 -10
- package/src/lib/shared/setOwnProperty.ts +19 -0
- package/src/lib/shared/snippet.ts +1 -1
- package/src/lib/shared/subscribableProbes.ts +111 -0
- package/src/lib/shared/tailProbeSlot.ts +8 -1
- package/src/lib/shared/types/CacheEntry.ts +9 -15
- package/src/lib/shared/types/CacheOptions.ts +8 -0
- package/src/lib/shared/types/CacheSnapshotEntry.ts +0 -5
- package/src/lib/shared/types/RemoteCallable.ts +25 -7
- package/src/lib/shared/types/RemoteFunction.ts +48 -13
- package/src/lib/shared/types/ResolverSlot.ts +7 -4
- package/src/lib/shared/types/RpcError.ts +26 -0
- package/src/lib/shared/types/SmartReadOptions.ts +32 -0
- package/src/lib/shared/types/Socket.ts +54 -0
- package/src/lib/shared/types/SsrBootState.ts +27 -0
- package/src/lib/shared/types/SsrPayload.ts +21 -0
- package/src/lib/shared/types/Subscribable.ts +13 -13
- package/src/lib/shared/types/TailHooks.ts +2 -1
- package/src/lib/shared/url.ts +29 -14
- package/src/lib/shared/wakeHydrationPeeks.ts +20 -0
- package/src/lib/shared/writeTestSocketsDts.ts +1 -1
- package/src/lib/test/createScriptedSurface.ts +1 -1
- package/src/lib/test/createTestApp.ts +2 -2
- package/src/lib/test/createTestSocketChannel.ts +3 -3
- package/src/lib/ui/compile/REACTIVE_CALLEES.ts +5 -6
- package/src/lib/ui/compile/UI_RUNTIME_IMPORTS.ts +10 -7
- package/src/lib/ui/compile/abideUiPlugin.ts +2 -2
- package/src/lib/ui/compile/analyzeComponent.ts +28 -6
- package/src/lib/ui/compile/compileModule.ts +137 -11
- package/src/lib/ui/compile/compileShadow.ts +101 -84
- package/src/lib/ui/compile/desugarSignals.ts +120 -107
- package/src/lib/ui/compile/generateBuild.ts +47 -11
- package/src/lib/ui/compile/generateSSR.ts +117 -14
- package/src/lib/ui/compile/identifierReferencePattern.ts +13 -0
- package/src/lib/ui/compile/lowerContext.ts +10 -4
- package/src/lib/ui/compile/lowerScript.ts +72 -5
- package/src/lib/ui/compile/prepareNestedScript.ts +31 -17
- package/src/lib/ui/compile/resolveReactiveExport.ts +95 -0
- package/src/lib/ui/compile/signalCallee.ts +24 -0
- package/src/lib/ui/compile/stripEffects.ts +14 -11
- package/src/lib/ui/compile/types/AnalyzedComponent.ts +5 -0
- package/src/lib/ui/dom/appendStatic.ts +9 -1
- package/src/lib/ui/dom/appendText.ts +15 -3
- package/src/lib/ui/dom/assertClaimedText.ts +20 -0
- package/src/lib/ui/dom/awaitBlock.ts +17 -56
- package/src/lib/ui/dom/bindSelectValue.ts +48 -0
- package/src/lib/ui/dom/each.ts +12 -1
- package/src/lib/ui/dom/hydrate.ts +10 -0
- package/src/lib/ui/effect.ts +4 -3
- package/src/lib/ui/installHotBridge.ts +4 -2
- package/src/lib/ui/remoteProxy.ts +18 -2
- package/src/lib/ui/renderToStream.ts +9 -13
- package/src/lib/ui/resumeSeedScript.ts +2 -2
- package/src/lib/ui/router.ts +21 -2
- package/src/lib/ui/runtime/RESUME.ts +0 -6
- package/src/lib/ui/runtime/ambientScopeBacking.ts +1 -1
- package/src/lib/ui/runtime/types/SsrRender.ts +3 -4
- package/src/lib/ui/scope.ts +6 -3
- package/src/lib/ui/seedBootState.ts +53 -0
- package/src/lib/ui/socketChannel.ts +2 -2
- package/src/lib/ui/socketProxy.ts +9 -3
- package/src/lib/ui/startClient.ts +16 -30
- package/src/lib/ui/state.ts +44 -13
- package/src/lib/ui/sync.ts +11 -5
- package/src/lib/ui/tryEncodeResume.ts +2 -5
- package/src/lib/ui/types/Scope.ts +14 -10
- package/src/lib/ui/watch.ts +140 -0
- package/src/serverEntry.ts +6 -6
- package/template/CLAUDE.md +1 -1
- package/template/package.json +1 -1
- package/template/src/server/rpc/getHello.ts +3 -3
- package/template/src/ui/pages/page.abide +2 -2
- package/template/test/app.test.ts +1 -1
- package/src/lib/server/reachable.ts +0 -45
- package/src/lib/server/sockets/types/Socket.ts +0 -23
- package/src/lib/shared/CACHE_WRAPPED.ts +0 -9
- package/src/lib/shared/baseResolver.ts +0 -10
- package/src/lib/shared/cacheKeyOf.ts +0 -7
- package/src/lib/shared/cacheKeyStore.ts +0 -8
- package/src/lib/shared/cacheStoreResolver.ts +0 -12
- package/src/lib/shared/globalCacheStoreResolver.ts +0 -12
- package/src/lib/shared/pageResolver.ts +0 -16
- package/src/lib/shared/recordCacheKey.ts +0 -6
- package/src/lib/shared/requestScopeResolver.ts +0 -12
- package/src/lib/shared/setBaseResolver.ts +0 -4
- package/src/lib/shared/setCacheStoreResolver.ts +0 -4
- package/src/lib/shared/setGlobalCacheStoreResolver.ts +0 -4
- package/src/lib/shared/setPageResolver.ts +0 -4
- package/src/lib/shared/setRequestScopeResolver.ts +0 -4
- package/src/lib/shared/toBunRoutePattern.ts +0 -28
- package/src/lib/shared/types/TailOptions.ts +0 -10
- package/src/lib/ui/deferResume.ts +0 -29
- package/src/lib/ui/matchRoute.ts +0 -106
- package/src/lib/ui/tail.ts +0 -324
- /package/src/lib/{server/sockets → shared}/types/SocketClientFrame.ts +0 -0
- /package/src/lib/{server/sockets → shared}/types/SocketServerFrame.ts +0 -0
package/AGENTS.md
CHANGED
|
@@ -1,420 +1,465 @@
|
|
|
1
1
|
# AGENTS.md — abide complete surface map
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
>
|
|
5
|
-
>
|
|
6
|
-
>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
(same callable, same behaviour on both sides; the bundler swaps the runtime).
|
|
14
|
-
|
|
15
|
-
Package: `@abide/abide`, one runtime (Bun `>=1.3.0`), one direct dependency
|
|
16
|
-
(TypeScript). The bullets below name each export by its import specifier in the
|
|
17
|
-
`abide/…` shorthand — the published package is `@abide/abide`, so
|
|
18
|
-
`abide/server/GET` imports from `@abide/abide/server/GET`. These are import
|
|
19
|
-
specifiers, not source file paths.
|
|
3
|
+
> This file is the exhaustive public-surface map of `@abide/abide`: every
|
|
4
|
+
> `exports` key, grouped by namespace, with its import specifier and a one-line
|
|
5
|
+
> spec. The README is the curated three-primitive intro; `CONTEXT.md` is the
|
|
6
|
+
> domain glossary; `docs/adr/` holds the rationale behind decisions. Ground
|
|
7
|
+
> rules: there are **no barrels** — every public name has its own module path,
|
|
8
|
+
> and the namespace marks the side it runs on (`abide/server/*` server-only,
|
|
9
|
+
> `abide/ui/*` client-only, `abide/shared/*` isomorphic — same callable, same
|
|
10
|
+
> behavior on both sides). Package `@abide/abide`, runtime Bun ≥ 1.3, one
|
|
11
|
+
> direct dependency (TypeScript). Import specifiers below are `exports`-map
|
|
12
|
+
> keys (`@abide/abide/server/GET`), not source file paths.
|
|
20
13
|
|
|
21
14
|
## The premise
|
|
22
15
|
|
|
23
|
-
One typed
|
|
16
|
+
One typed declaration fans out to every surface:
|
|
24
17
|
|
|
25
18
|
```text
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
19
|
+
src/server/rpc/getMessages.ts
|
|
20
|
+
│
|
|
21
|
+
├─ SSR / server await getMessages({ room }) in-process, no HTTP
|
|
22
|
+
├─ browser await getMessages({ room }) typed fetch proxy
|
|
23
|
+
├─ HTTP GET /rpc/getMessages?room=…
|
|
24
|
+
├─ CLI my-app get-messages --room …
|
|
25
|
+
├─ MCP tool: get-messages
|
|
26
|
+
└─ OpenAPI operation in /openapi.json
|
|
33
27
|
```
|
|
34
28
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
A mutating method (
|
|
38
|
-
|
|
29
|
+
An `inputSchema` (any Standard Schema library — zod, valibot, arktype,
|
|
30
|
+
unadapted) is the gate: it unlocks the CLI, and for read-only methods
|
|
31
|
+
(GET/HEAD) the MCP tool. A mutating method (POST/PUT/PATCH/DELETE) never
|
|
32
|
+
auto-exposes to MCP — it requires explicit `clients: { mcp: true }`.
|
|
39
33
|
|
|
40
34
|
## File-based conventions
|
|
41
35
|
|
|
42
|
-
The bundler reads meaning from these paths (the project's own `src/`, not the
|
|
43
|
-
package):
|
|
44
|
-
|
|
45
36
|
| Path | Meaning |
|
|
46
37
|
| --- | --- |
|
|
47
|
-
| `src/server/rpc/<name>.ts` | One RPC; export name
|
|
48
|
-
| `src/server/sockets/<name>.ts` | One socket; export name = file stem
|
|
49
|
-
| `src/mcp/prompts/<name>.md` | An MCP prompt
|
|
50
|
-
| `src/
|
|
51
|
-
| `src/
|
|
52
|
-
| `src/
|
|
53
|
-
| `src/
|
|
54
|
-
| `src/ui/pages/**/
|
|
55
|
-
| `src/ui/
|
|
56
|
-
| `src
|
|
57
|
-
| `
|
|
38
|
+
| `src/server/rpc/<name>.ts` | One RPC per file; the export name must match the file stem; the file path becomes the URL `/rpc/<name>` (subdirectories nest into the path) |
|
|
39
|
+
| `src/server/sockets/<name>.ts` | One broadcast socket per file; export name = file stem = topic name |
|
|
40
|
+
| `src/mcp/prompts/<name>.md` | An MCP prompt template; `{{arg}}` placeholders become the prompt's arguments |
|
|
41
|
+
| `src/mcp/resources/**` | Files served as MCP resources (gzip-embedded into builds) |
|
|
42
|
+
| `src/server/config.ts` | Boot-time `env()` validation; eager-imported so a bad environment fails the boot |
|
|
43
|
+
| `src/app.ts` | Optional `AppModule` hooks: `init`, `handle`, `handleError`, `health`, `forwardHeaders` |
|
|
44
|
+
| `src/bundle/window.ts` | Optional `BundleWindow` default export configuring the desktop bundle's window and menus |
|
|
45
|
+
| `src/ui/pages/**/page.abide` | A routed page; the directory path is the route — a `[id]` folder is a path param, `[[id]]` an optional param, `[...rest]` a catch-all |
|
|
46
|
+
| `src/ui/pages/**/layout.abide` | A layout wrapping the pages below it; its `{children()}` is the router outlet |
|
|
47
|
+
| `src/ui/public/` | Static assets served as-is |
|
|
48
|
+
| `src/.abide/*.d.ts` | Generated typing (rpc args for `url()`, page routes, health fields, test rpc/socket clients, public asset paths) |
|
|
49
|
+
| `dist/` | Build output — `dist/_app` client bundle, `dist/cli-thin/<platform>/` CLI tarballs |
|
|
50
|
+
|
|
51
|
+
Project import aliases resolve to the five top-level source dirs: `$server`,
|
|
52
|
+
`$ui`, `$shared`, `$mcp`, `$cli` (e.g. `$server/rpc/getMessages`,
|
|
53
|
+
`$ui/pages/...`). `$server/rpc/*` and `$server/sockets/*` are proxied into
|
|
54
|
+
client bundles; any other `$server/*` import from client code is a
|
|
55
|
+
side-crossing error.
|
|
58
56
|
|
|
59
57
|
## CLI
|
|
60
58
|
|
|
61
59
|
| Command | Does |
|
|
62
60
|
| --- | --- |
|
|
63
|
-
| `bunx abide scaffold <name>` |
|
|
64
|
-
| `abide dev` |
|
|
65
|
-
| `abide build` | One client build into `dist/_app
|
|
66
|
-
| `abide start` |
|
|
67
|
-
| `abide
|
|
68
|
-
| `abide
|
|
69
|
-
| `abide
|
|
70
|
-
| `abide
|
|
71
|
-
| `abide
|
|
72
|
-
| `abide lsp` |
|
|
73
|
-
| `abide init-agent` |
|
|
74
|
-
|
|
75
|
-
For
|
|
76
|
-
`bunfig.toml`.
|
|
61
|
+
| `bunx abide scaffold <name>` | Scaffolds the bundled template, installs it, and (interactive TTY only) starts the dev server; `--no-install` / `--no-dev` opt out |
|
|
62
|
+
| `abide dev` | Dev orchestrator: builds the client, runs the server as a child, watches `src/`, rebuilds + restarts on change, live-reloads the browser |
|
|
63
|
+
| `abide build` | One-shot client build into `dist/_app` (CI / static deploys) |
|
|
64
|
+
| `abide start` | Runs the production server against an already-built `dist/` |
|
|
65
|
+
| `abide run <file> [args...]` | Runs any script under the abide preload — same runtime as the server (`.abide` compilation, `abide/*` + `$` alias resolution) |
|
|
66
|
+
| `abide compile [--target=…] [--out=…]` | Compiles a standalone server executable (client assets embedded) |
|
|
67
|
+
| `abide cli [--target=…] [--out=…] [--platforms=a,b,c]` | Builds the thin CLI binary (rpc manifest baked in) that talks to a remote server or starts a local one; `--platforms` cross-compiles into `dist/cli-thin/<platform>/` |
|
|
68
|
+
| `abide bundle` | Assembles a movable, self-contained desktop app bundle (server binary + launcher + webview) for the host platform; unsigned |
|
|
69
|
+
| `abide check` | Type-checks every `.abide` component's template + props through its shadow; non-zero exit on errors |
|
|
70
|
+
| `abide lsp` | Runs the `.abide` language server over stdio (JSON-RPC) for editor diagnostics |
|
|
71
|
+
| `abide init-agent` | Writes/refreshes the CLAUDE.md pointer to this surface map for non-scaffolded projects |
|
|
72
|
+
|
|
73
|
+
For tests, add `preload = ["@abide/abide/preload"]` under `[test]` in
|
|
74
|
+
`bunfig.toml` and use `bun test`.
|
|
77
75
|
|
|
78
76
|
## Authoring contracts
|
|
79
77
|
|
|
80
|
-
**RPC**
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
`
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
`
|
|
89
|
-
`
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
`
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
`fn
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
`
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
-
|
|
78
|
+
**RPC** — the handler receives the schema-validated args
|
|
79
|
+
(`InferOutput<inputSchema>`); typed generics on the helper are a compile error
|
|
80
|
+
— type the parameter, let the body infer. Inside it, `request()` / `cookies()`
|
|
81
|
+
/ `server()` read the request scope. Return `json(data)` (or `jsonl` / `sse`
|
|
82
|
+
for streams, `error` / `redirect`, or a raw `Response`). Options:
|
|
83
|
+
`inputSchema`, `outputSchema`, `filesSchema` (validates uploaded `File` parts,
|
|
84
|
+
kept out of the JSON-Schema projection), `clients: { browser, mcp, cli }`,
|
|
85
|
+
`crossOrigin` (exempts a mutating rpc from the same-origin CSRF gate),
|
|
86
|
+
`timeout` (handler deadline in ms → 504 on every surface, composed into
|
|
87
|
+
`request().signal`), `maxBodySize` (per-rpc 413 cap), `outbox` (durable
|
|
88
|
+
delivery, mutating methods only). Query args on GET/HEAD/DELETE travel as
|
|
89
|
+
strings — coerce in the schema (`z.coerce.number()`). A body rpc also accepts
|
|
90
|
+
a `FormData` in place of typed args (the upload escape hatch): text fields
|
|
91
|
+
validate as args, `File` parts validate against `filesSchema`.
|
|
92
|
+
|
|
93
|
+
**Consuming an rpc** — the bare call `fn(args, opts?)` IS the smart read:
|
|
94
|
+
cached, coalesced, reactive, stale-while-revalidate for replayable (GET/HEAD)
|
|
95
|
+
reads; the second arg takes `{ ttl, tags, throttle, debounce, global, n }`
|
|
96
|
+
(retention and the refetch clock — not transport). `global: true` stores the
|
|
97
|
+
entry in the process-level store instead of the request-scoped default
|
|
98
|
+
(server), so later requests reuse the value — for memoising an external
|
|
99
|
+
endpoint, never per-user data; on the client it is a no-op (one tab store).
|
|
100
|
+
During SSR the same call resolves
|
|
101
|
+
in-process and its value is baked into the HTML so hydration starts warm —
|
|
102
|
+
there is no `cache()` wrapper; the bare call carries the caching. Around it:
|
|
103
|
+
`fn.raw(args, init?)` returns the raw `Response` (per-call transport options —
|
|
104
|
+
`signal`, `headers`, `keepalive`, … — live here); `fn.refresh(args?)`
|
|
105
|
+
refetches keeping the stale value visible; `fn.patch(args?, updater)` mutates
|
|
106
|
+
the retained value locally (absent on streaming rpcs); `fn.peek(args?)` reads
|
|
107
|
+
it synchronously; `fn.pending(args?)` / `fn.refreshing(args?)` are reactive
|
|
108
|
+
probes; `fn.error(args?)` is the rpc's last typed error; `fn.watch(args?,
|
|
109
|
+
handler)` pipes each resolved value to a handler (client-only; SSR-inert);
|
|
110
|
+
`fn.isError(e, kind?)` type-guards a caught error against the rpc's declared
|
|
111
|
+
error kinds; `fn.outbox()` exposes a durable rpc's parked-write queue. A
|
|
112
|
+
handler that returns `jsonl()`/`sse()` makes the bare call return a
|
|
113
|
+
`Subscribable` (`for await` it) — detected at build, nothing to declare;
|
|
114
|
+
awaiting a streaming call is a compile error.
|
|
115
|
+
|
|
116
|
+
**Typed errors** — declare a constructor with
|
|
117
|
+
`error.typed(name, status, schema?)` and `return` it from the handler; the
|
|
118
|
+
client's `HttpError` then carries `kind` (the name) and `data` (the schema's
|
|
119
|
+
payload), narrowed via `rpc.isError`. The framework reserves
|
|
120
|
+
`kind: 'validation'` (422, `data: ValidationErrorData`) and `kind: 'queued'`
|
|
121
|
+
(a durable call parked while unreachable; `data` is the parked `OutboxEntry`).
|
|
122
|
+
|
|
123
|
+
**Durable outbox** — an `outbox: true` (mutating) rpc still fetches and throws
|
|
124
|
+
normally, but an unreachable server (transport failure or 502/503/504/52x)
|
|
125
|
+
parks the request for replay as a side-effect and throws `kind: 'queued'`;
|
|
126
|
+
once a backlog exists new calls park straight to the tail so writes stay
|
|
127
|
+
ordered. Nothing auto-drains: replay via `rpc.outbox.retry()` or the global
|
|
128
|
+
`outbox.retry()`; cancel via an entry's `controller.abort()`.
|
|
129
|
+
|
|
130
|
+
**Socket** — `socket<T>(opts)` or `socket({ schema, … })` (with a schema, `T`
|
|
131
|
+
infers and publishes validate). Options: `tail` (retained frames, default 1 —
|
|
132
|
+
`tail: 0` opts out), `ttl` (retained frames expire lazily after N ms),
|
|
133
|
+
`clientPublish` (accept browser/HTTP publishes, off by default), `clients`
|
|
134
|
+
(mcp/cli exposure; a schema flips both on by default). The socket IS the
|
|
135
|
+
`AsyncIterable` — iterating is the live stream, no replay. Members:
|
|
136
|
+
`broadcast(msg)` (isomorphic publish — server fans out in-process + to remote
|
|
137
|
+
subscribers, client sends a validated `pub` frame), `tail(count?)` (a
|
|
138
|
+
subscription seeded with retained frames), `peek()` (latest retained frame),
|
|
139
|
+
`refresh()` (drop local frames and re-pull the server tail; server-side
|
|
140
|
+
no-op), `watch(handler)` ≡ `watch(socket, handler)` (client-only, SSR-inert),
|
|
141
|
+
`pending()` / `refreshing()` / `done()` / `error()` (reactive stream probes),
|
|
142
|
+
plus `name` and `clients`.
|
|
143
|
+
|
|
144
|
+
**Pages and layouts** — `src/ui/pages/blog/[id]/page.abide` serves
|
|
145
|
+
`/blog/<id>`; the param arrives as a prop (`const { id } = props()`) and on the
|
|
146
|
+
reactive `page.params`. A `[[name]]` folder is an optional segment (the route
|
|
147
|
+
matches with or without it; the param is absent when unmatched), `[...rest]`
|
|
148
|
+
a catch-all capturing the remaining path (last segment only). One matcher
|
|
149
|
+
resolves routes on both sides — at the first position where two matching
|
|
150
|
+
patterns differ, literal beats `[name]` beats `[[name]]` beats `[...rest]`. A `layout.abide` wraps every page below its directory
|
|
151
|
+
and renders the page at its `{children()}` outlet. Links are plain `<a href>`
|
|
152
|
+
(the router intercepts in-app hrefs); build paths with `url()` and navigate
|
|
153
|
+
programmatically with `navigate()`.
|
|
154
|
+
|
|
155
|
+
**app.ts / config.ts** — `src/app.ts` optionally exports the `AppModule`
|
|
156
|
+
hooks: `init({ server })` (boot; may return a cleanup run on SIGINT/SIGTERM),
|
|
157
|
+
`handle(request, next)` (single middleware), `handleError(error, request)`,
|
|
158
|
+
`health(request)` (fields merged into the `/__abide/health` payload — public
|
|
159
|
+
and unauthenticated, keep it cheap), and `forwardHeaders` (extra inbound
|
|
160
|
+
header names forwarded onto in-process rpc requests beyond the built-in
|
|
161
|
+
auth/identity set). `src/server/config.ts` holds the `env(schema)` call so a
|
|
162
|
+
bad environment fails at boot.
|
|
163
|
+
|
|
164
|
+
## `.abide` template grammar
|
|
165
|
+
|
|
166
|
+
A component file is: an optional leading `<script>` (imports + author scope),
|
|
167
|
+
markup, optional `<style>` blocks. The compiler emits a client build and an
|
|
168
|
+
SSR render from the same parse; `abide check` / the LSP type-check the
|
|
169
|
+
template through a generated shadow. HTML comments are dropped; a bare
|
|
170
|
+
`<template>` is an inert element.
|
|
171
|
+
|
|
172
|
+
Reactive state is reached through **imported primitives**, resolved by import
|
|
173
|
+
binding (alias-safe) and lowered by the compiler — inside a component you read
|
|
174
|
+
and write the declared names as plain variables (`{count}`,
|
|
175
|
+
`onclick={() => (count += 1)}`); there is no `.value` in `.abide` authoring
|
|
176
|
+
and no `$state` sigils. In plain `.ts` modules the same imports are runtime
|
|
177
|
+
cells read/written through `.value`.
|
|
178
|
+
|
|
179
|
+
| Primitive | Import | Spec |
|
|
180
|
+
| --- | --- | --- |
|
|
181
|
+
| `state(initial, transform?)` | `@abide/abide/ui/state` | Writable cell. Plain `state(v)` lowers to a serializable doc slot (SSR-resumable); with `transform` the gate runs on every write (`(next, previous) => stored`) |
|
|
182
|
+
| `state.computed(fn)` | member of `state` | Read-only derived value, lazy, never serialized |
|
|
183
|
+
| `state.linked(fn, transform?)` | member of `state` | Writable cell re-seeded whenever the thunk's dependencies change |
|
|
184
|
+
| `state.share(key, value)` / `state.shared(key)` | members of `state` | Put a named value on the ambient scope / read the closest ancestor's |
|
|
185
|
+
| `watch(source, handler)` | `@abide/abide/ui/watch` | The single reaction primitive (client-only, stripped from SSR). Sources: a bare thunk `watch(() => …)` (auto-tracked effect), a state cell, a cell array, a socket/stream (`handler(frame)` per frame with reconnect replay), an rpc (`watch(fn, args?, handler)` — runs the smart read, `handler(value)` on each change). Returns a scope-tied disposer |
|
|
186
|
+
| `html(str)` / `` html`…` `` | `@abide/abide/ui/html` | Brands trusted raw HTML so `{expr}` inserts nodes instead of escaped text; plain `{value}` always escapes |
|
|
187
|
+
| `props()` | ambient (no import) | The prop reader: `const { name = fallback, ...rest } = props()`; a page's props are its route params |
|
|
188
|
+
|
|
189
|
+
Bindings and directives (the attribute kinds `readAttributes` parses):
|
|
190
|
+
|
|
191
|
+
| Form | Spec |
|
|
148
192
|
| --- | --- |
|
|
149
|
-
| `{expr}` |
|
|
150
|
-
| `{
|
|
151
|
-
| `name={expr}`
|
|
152
|
-
| `
|
|
153
|
-
| `
|
|
154
|
-
| `bind:value={
|
|
155
|
-
| `
|
|
156
|
-
| `
|
|
157
|
-
| `
|
|
158
|
-
| `{
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
193
|
+
| `{expr}` | Text interpolation, escaped; a snippet or `html`-branded value mounts as nodes |
|
|
194
|
+
| `name={expr}` | Attribute/prop bound to an expression |
|
|
195
|
+
| `name="a {expr} b"` | Interpolated attribute — a literal `{` in a quoted value always interpolates (write `{` for a literal brace) |
|
|
196
|
+
| `{...expr}` | Spread — props onto a component, attributes onto a native element (rejected on `<template>`) |
|
|
197
|
+
| `on<event>={fn}` | Event listener (`onclick`, `onsubmit`, …); on a component it is a checked callback prop |
|
|
198
|
+
| `bind:value={cell}` | Two-way input/select/textarea binding. `<input type="number"/"range">` writes back a number; `<select>` re-applies against late-mounting options and `<select multiple>` binds an array of selected values |
|
|
199
|
+
| `bind:value={{ get, set }}` | Writable-computed binding: read via `get()`, write via `set(next)` |
|
|
200
|
+
| `bind:checked={cell}` / `bind:group={cell}` | Checkbox boolean / radio-group value (SSR emits boolean attributes bare — `checked`, `open`, `selected` on the matching option) |
|
|
201
|
+
| `class:name={cond}` | Toggles a class; merges with a reactive `class` base in one effect |
|
|
202
|
+
| `style:property={value}` | Sets one style property; merges with a reactive `style` base |
|
|
203
|
+
| `attach={fn}` | Runs `fn(element)` at build time; an optional returned teardown runs on dispose |
|
|
204
|
+
|
|
205
|
+
Control flow is mustache blocks (`{#…}` open, `{:…}` branch, `{/…}` close —
|
|
206
|
+
the close must name its block, and a branch outside its block is a parse
|
|
207
|
+
error):
|
|
208
|
+
|
|
209
|
+
| Block | Spec |
|
|
163
210
|
| --- | --- |
|
|
164
|
-
|
|
|
165
|
-
|
|
|
166
|
-
|
|
|
167
|
-
|
|
|
168
|
-
|
|
|
169
|
-
|
|
|
170
|
-
| Snippet | `{#snippet name(args)}…{/snippet}`, called `{name(args)}` |
|
|
171
|
-
|
|
172
|
-
A capitalised tag is a child component; nested content renders where the child
|
|
173
|
-
calls `{children()}` — the single slot, with `{#if children}…{:else}…{/if}` as
|
|
174
|
-
the fallback form. No named slots.
|
|
211
|
+
| `{#if cond}…{:else if cond}…{:else}…{/if}` | Conditional chain (the branch keyword is `{:else if}`, with a space) |
|
|
212
|
+
| `{#for item, i of list by key}…{:catch e}…{/for}` | Keyed list; `, i` index and `by` key optional; `{#for await item of asyncIterable}` renders rows as they arrive (its `{:catch}` shows the stream error) |
|
|
213
|
+
| `{#await p}…{:then v}…{:catch e}…{:finally}…{/await}` | Async block. The branch form streams: SSR flushes the shell and streams the fragment out of order. The head form `{#await p then v}` is blocking — rendered inline (depth-first, serial) during the SSR pass |
|
|
214
|
+
| `{#switch subject}{:case match}…{:default}…{/switch}` | Multi-branch on a subject; only branches render — stray content is a compile error |
|
|
215
|
+
| `{#try}…{:catch e}…{:finally}…{/try}` | Synchronous error boundary around a build/reactive throw |
|
|
216
|
+
| `{#snippet name(args)}…{/snippet}` | Declares a reusable builder, called as an interpolation: `{name(args)}`; a snippet value passes through props like any other value |
|
|
175
217
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
218
|
+
Components are capitalised tags (`<Panel prop={x}>…</Panel>`); nested content
|
|
219
|
+
renders where the component calls `{children()}` — the single fill point
|
|
220
|
+
(`{#if children}{children()}{:else}…{/if}` for a fallback; there are no named
|
|
221
|
+
slots and no `<slot>` element). A layout's `{children()}` is the route outlet.
|
|
180
222
|
|
|
181
|
-
|
|
223
|
+
`<script>` and `<style>` are **not component-root-only**: either may sit
|
|
224
|
+
inside a control-flow branch, scoped to that branch. A nested `<script>`
|
|
225
|
+
declares branch-local `state` / `state.computed` / `state.linked` the same
|
|
226
|
+
imported way (re-seeded per mount; static `import` statements are illegal
|
|
227
|
+
there — imports live in the leading `<script>`). A **root** `<style>` is
|
|
228
|
+
component-scoped; a nested `<style>` scopes to its sibling subtree only.
|
|
182
229
|
|
|
183
|
-
|
|
230
|
+
Removed forms throw migration errors at parse time: the `<slot>` element (use
|
|
231
|
+
`{children()}`), `<template name>` snippets (use `{#snippet}`), and all
|
|
232
|
+
`<template if/each/await/switch/…>` control flow (use `{#…}` blocks).
|
|
184
233
|
|
|
185
|
-
|
|
186
|
-
- `abide/server/POST` — create/mutate RPC helper; accepts `outbox` for durable replay.
|
|
187
|
-
- `abide/server/PUT` — replace RPC helper (mutating).
|
|
188
|
-
- `abide/server/PATCH` — partial-update RPC helper (mutating).
|
|
189
|
-
- `abide/server/DELETE` — delete RPC helper (mutating).
|
|
190
|
-
- `abide/server/HEAD` — read RPC helper, no body (auto-exposes to MCP like GET).
|
|
234
|
+
## Server surface — `abide/server/*`
|
|
191
235
|
|
|
192
|
-
###
|
|
236
|
+
### RPC — `@documentation rpc`
|
|
193
237
|
|
|
194
|
-
-
|
|
238
|
+
- `@abide/abide/server/GET` — GET rpc helper: `export const x = GET(handler, opts?)` inside `src/server/rpc/`; the bundler rewrites it to the server dispatcher or the browser proxy — calling it outside an rpc module throws.
|
|
239
|
+
- `@abide/abide/server/POST` — POST rpc helper (mutating: accepts `outbox`, JSON/FormData body).
|
|
240
|
+
- `@abide/abide/server/PUT` — PUT rpc helper (mutating).
|
|
241
|
+
- `@abide/abide/server/PATCH` — PATCH rpc helper (mutating).
|
|
242
|
+
- `@abide/abide/server/DELETE` — DELETE rpc helper (mutating; args travel in the query string).
|
|
243
|
+
- `@abide/abide/server/HEAD` — HEAD rpc helper (read-only).
|
|
195
244
|
|
|
196
|
-
###
|
|
245
|
+
### Responses — `@documentation response`
|
|
197
246
|
|
|
198
|
-
-
|
|
199
|
-
-
|
|
200
|
-
-
|
|
201
|
-
-
|
|
202
|
-
-
|
|
247
|
+
- `@abide/abide/server/json` — `json(data, init?)`: JSON response with `Cache-Control: no-store` default; `json(undefined)` emits 204 and round-trips back to `undefined`; carries the value type so the rpc's `Return` infers.
|
|
248
|
+
- `@abide/abide/server/jsonl` — `jsonl(asyncIterable, init?)`: JSON Lines streaming response; consumer cancel flows into the generator's `return`; a generator throw becomes a final `{"$error": message}` line.
|
|
249
|
+
- `@abide/abide/server/sse` — `sse(asyncIterable, init?)`: Server-Sent Events response with a 15s keepalive comment; errors emit an `event: error` frame carrying only the message.
|
|
250
|
+
- `@abide/abide/server/error` — `error(status, message?, init?)`: plain-text error response (message defaults to the reason phrase); the caller's await throws `HttpError`. Member `error.typed(name, status, schema?)` declares a reusable typed-error constructor the handler returns (see Authoring contracts).
|
|
251
|
+
- `@abide/abide/server/redirect` — `redirect(url, status = 302, init?)`: redirect response accepting relative URLs; 301/302/303/307/308.
|
|
203
252
|
|
|
204
|
-
### Request scope —
|
|
253
|
+
### Request scope — `@documentation request-scope`
|
|
205
254
|
|
|
206
|
-
-
|
|
207
|
-
-
|
|
208
|
-
-
|
|
255
|
+
- `@abide/abide/server/request` — `request()`: the inbound `Request` for the in-flight SSR/rpc pass (AsyncLocalStorage); throws outside a request scope.
|
|
256
|
+
- `@abide/abide/server/cookies` — `cookies()`: the request's cookie jar (Bun `CookieMap`) — reads parse the inbound header; `set`/`delete` flush as `Set-Cookie` when the handler returns.
|
|
257
|
+
- `@abide/abide/server/server` — `server()`: the active `Bun.serve` instance; a no-op stand-in during in-process dispatch (CLI/MCP/tests); throws before boot.
|
|
209
258
|
|
|
210
|
-
### Configuration —
|
|
259
|
+
### Configuration — `@documentation configuration`
|
|
211
260
|
|
|
212
|
-
-
|
|
261
|
+
- `@abide/abide/server/env` — `env(schema)`: validates `Bun.env` against a Standard Schema at module top level (synchronous; every issue reported at once) and returns the typed config; the schema also projects the bundle's first-run setup form.
|
|
213
262
|
|
|
214
|
-
###
|
|
263
|
+
### Sockets — `@documentation sockets`
|
|
215
264
|
|
|
216
|
-
-
|
|
265
|
+
- `@abide/abide/server/socket` — `socket<T>(opts?)` / `socket({ schema, tail, ttl, clientPublish, clients })`: declares the broadcast topic inside `src/server/sockets/<name>.ts`; see Authoring contracts for the full `Socket<T>` member surface.
|
|
217
266
|
|
|
218
|
-
### Agent —
|
|
267
|
+
### Agent — `@documentation agent`
|
|
219
268
|
|
|
220
|
-
-
|
|
269
|
+
- `@abide/abide/server/agent` — `agent(engine, messages)`: runs a provider engine (an `@abide/<provider>` package) against the app's own MCP surface inside an rpc's request scope and returns its `AgentFrame` stream; the handler picks the transport (`jsonl(agent(…))` / `sse(agent(…))`). The module also exports the neutral contract types: `NeutralMessage` (user/assistant/tool turns), `AgentFrame` (`text` deltas, `tool_use`, `tool_result`, `done` with a stop reason), `AgentSurface` (the gated tool/prompt/resource surface), and `AgentEngine` (surface + messages + origin in, frames out).
|
|
221
270
|
|
|
222
|
-
### Server plumbing —
|
|
271
|
+
### Server plumbing — `@documentation plumbing`
|
|
223
272
|
|
|
224
|
-
-
|
|
225
|
-
-
|
|
226
|
-
-
|
|
227
|
-
-
|
|
228
|
-
-
|
|
229
|
-
-
|
|
273
|
+
- `@abide/abide/server/AppModule` — the type of `src/app.ts`'s optional hooks (`init`, `handle`, `handleError`, `health`, `forwardHeaders`).
|
|
274
|
+
- `@abide/abide/server/InspectorContext` — the capability object core injects into `@abide/inspector` (`loadSurface`, `cacheSnapshot`, `inFlightSnapshot`, `onRecord`, app identity); keeps the inspector a pure consumer.
|
|
275
|
+
- `@abide/abide/server/rpc/defineRpc` — `defineRpc(method, url, handler, opts?)`: the server-side construction the bundler rewrites rpc helper calls into — validation, timeout composition, client-flag resolution, registry entry.
|
|
276
|
+
- `@abide/abide/server/sockets/defineSocket` — `defineSocket(name, opts?)`: server-side socket construction (retained-tail buffer with lazy TTL eviction, per-subscriber queues, `server.publish` fan-out).
|
|
277
|
+
- `@abide/abide/server/prompts/definePrompt` — `definePrompt(name, opts)`: registers an MCP prompt; the resolver plugin generates one call per `src/mcp/prompts/<name>.md`.
|
|
278
|
+
- `@abide/abide/server/prompts/renderPromptTemplate` — `renderPromptTemplate(template, args)`: substitutes `{{name}}` placeholders in a prompt body (missing args collapse to empty).
|
|
230
279
|
|
|
231
|
-
## Isomorphic surface — abide/shared
|
|
280
|
+
## Isomorphic surface — `abide/shared/*`
|
|
232
281
|
|
|
233
|
-
### Cache —
|
|
282
|
+
### Cache mutators — `@documentation cache`
|
|
234
283
|
|
|
235
|
-
-
|
|
284
|
+
- `@abide/abide/shared/refresh` — `refresh(selector?, args?)`: refetch every cached read matching the selector, keeping the stale value visible until the fresh one swaps in. Selector grammar: `(fn, args)` exact call, `(fn)` every args-variant, `({ tags })` a tagged group, `()` everything. `fn.refresh(args?)` is the pre-bound sugar.
|
|
285
|
+
- `@abide/abide/shared/patch` — `patch(fn, args?, updater)` / `patch({ tags }, updater)`: mutate the retained value(s) in place — reactive, no network; the optimistic-update / socket-frame primitive. `fn.patch(…)` is the sugar.
|
|
236
286
|
|
|
237
|
-
###
|
|
287
|
+
### Probes — `@documentation probes`
|
|
238
288
|
|
|
239
|
-
|
|
240
|
-
- `abide/shared/ValidationErrorData` — the `data` payload (`kind: 'validation'`, status 422) of a validation failure: raw `issues` + form-friendly `fields`.
|
|
289
|
+
Probes report, never act — reading one opens no fetch and no stream.
|
|
241
290
|
|
|
242
|
-
|
|
291
|
+
- `@abide/abide/shared/pending` — `pending(selector?, args?)`: reactive "no value yet" probe over calls and streams (global, per-rpc, per-call, tagged, per-subscribable; a durable rpc's parked writes count too).
|
|
292
|
+
- `@abide/abide/shared/refreshing` — `refreshing(selector?, args?)`: "holding a value while a fresher one is in flight" — the SWR reload / stream-reconnect badge.
|
|
293
|
+
- `@abide/abide/shared/peek` — `peek(fn, args?)` / `peek(socket)`: the retained value (or latest frame), synchronously, `T | undefined`; reactive inside a tracking scope.
|
|
294
|
+
- `@abide/abide/shared/done` — `done(subscribable)`: true once a stream closed (stream-only; a cache read's "done" is `!pending && !refreshing`).
|
|
295
|
+
- `@abide/abide/shared/online` — `online()`: reactive connectivity probe — browser `online`/`offline` events; server-side it reflects the *calling client's* reported connectivity (always true during SSR and outside a scope).
|
|
243
296
|
|
|
244
|
-
|
|
297
|
+
### Errors — `@documentation response`
|
|
245
298
|
|
|
246
|
-
|
|
299
|
+
- `@abide/abide/shared/HttpError` — thrown by rpc calls on non-2xx; carries `status`, `statusText`, the raw `response`, and — for typed/validation/queued errors — `kind` + `data`.
|
|
300
|
+
- `@abide/abide/shared/ValidationErrorData` — the `data` shape of a `kind: 'validation'` failure: the raw Standard Schema `issues` plus a `fields` (field → first message) map.
|
|
247
301
|
|
|
248
|
-
|
|
302
|
+
### Schema projection — `@documentation rpc`
|
|
249
303
|
|
|
250
|
-
|
|
304
|
+
- `@abide/abide/shared/withJsonSchema` — `withJsonSchema(schema, toJsonSchema)`: attaches the `toJSONSchema()` projection to a Standard Schema whose library lacks one, feeding OpenAPI, MCP, CLI help, and the bundle setup form.
|
|
251
305
|
|
|
252
|
-
|
|
253
|
-
- `abide/shared/refreshing` — reactive revalidation probe (holding a value while a fresher one loads); same selector grammar as `pending`.
|
|
254
|
-
- `abide/shared/online` — reactive network-connectivity probe (`navigator.onLine`, offline-reliable).
|
|
306
|
+
### Observability — `@documentation observability`
|
|
255
307
|
|
|
256
|
-
|
|
308
|
+
- `@abide/abide/shared/health` — `health()`: reactive backend health — `{ reachable, abide, name, version, …app health-hook fields }`, polled from `/__abide/health` only while a tracking scope reads it; SSR-seeded so hydration starts warm; constant `{ reachable: true }` on the server. The `AppHealth`/`AppHealthMap` types augment from the generated `health.d.ts`.
|
|
309
|
+
- `@abide/abide/shared/reachable` — `await reachable(host?)`: outbound reachability, same callable both sides. The first call probes (HEAD) and starts a TTL background poll; later calls answer instantly off the warm value. Any completed HTTP response counts as reachable. No host asks about the app's own backend: constant true on the server and on a loopback origin (dev, desktop bundle — works offline); a deployed origin probes like any host. The browser probes no-cors and composes `navigator.onLine` in at read time (loopback exempt). Tuned by `ABIDE_REACHABLE_TTL` / `ABIDE_REACHABLE_TIMEOUT` (server env; the browser runs the defaults).
|
|
310
|
+
- `@abide/abide/shared/log` — the unified logger: `log(...)` / `.warn` / `.error` / `.trace` on the app's always-on channel, every record carrying request-scope context (short trace id, +elapsed, method+path); member `log.channel(name)` returns the same shape on a DEBUG-gated diagnostic channel. Renders tsv (default) or JSON per `ABIDE_LOG_FORMAT`.
|
|
311
|
+
- `@abide/abide/shared/trace` — `trace()`: the current request's W3C `traceparent` (client-side: the trace of the request that rendered the page), or undefined outside any scope.
|
|
257
312
|
|
|
258
|
-
|
|
313
|
+
### Page — `@documentation page`
|
|
259
314
|
|
|
260
|
-
|
|
315
|
+
- `@abide/abide/shared/page` — the reactive page proxy: `page.route`, `page.params`, `page.url` (browser-space on both sides, mount base included), `page.navigating`; isomorphic, re-runs readers across navigations.
|
|
261
316
|
|
|
262
|
-
|
|
317
|
+
### URL — `@documentation url`
|
|
263
318
|
|
|
264
|
-
|
|
319
|
+
- `@abide/abide/shared/url` — `url(path, params?/args?)`: resolves any in-app URL to its base-correct form — a page route literal interpolates its `[name]` / `[[name]]` / `[...rest]` params (typed via `PathParams`; an absent optional drops its segment), a GET rpc path serializes typed args to the query, anything else is base-prefixed. Also exports the augmentable `RpcRoutes` / `PageRoutes` / `PublicAssets` maps and the `PathParams<P>` type.
|
|
265
320
|
|
|
266
|
-
|
|
267
|
-
- `abide/shared/log` — unified logger carrying request-scope context; `log`/`.warn`/`.error`/`.trace` on the app channel, `log.channel(name)` for DEBUG-gated channels.
|
|
268
|
-
- `abide/shared/trace` — the current request's W3C `traceparent`, or undefined outside a request scope; isomorphic.
|
|
321
|
+
### Templating — `@documentation templating`
|
|
269
322
|
|
|
270
|
-
|
|
323
|
+
- `@abide/abide/shared/snippet` — `snippet(payload)`: brands a snippet payload so a `{expr}` interpolation mounts it (client: a DOM builder; server: the rendered string); the compiler wraps `{#snippet}` bodies in this. Also exports the `Snippet<P>` type and `snippetPayload(value)` (the payload, or undefined for plain values).
|
|
271
324
|
|
|
272
|
-
|
|
325
|
+
### Shared plumbing — `@documentation plumbing`
|
|
273
326
|
|
|
274
|
-
|
|
327
|
+
- `@abide/abide/shared/createSubscriber` — `createSubscriber(start)`: open-on-first-tracked-read / close-on-last-reader resource lifecycle grounded in the signal core; the substrate under `health()`, `online()`, and the tail probes.
|
|
275
328
|
|
|
276
|
-
|
|
329
|
+
## UI surface — `abide/ui/*` (client-only)
|
|
277
330
|
|
|
278
|
-
|
|
331
|
+
### Reactive state — `@documentation reactive-state`
|
|
279
332
|
|
|
280
|
-
|
|
333
|
+
- `@abide/abide/ui/state` — the `state` primitive: `state(initial, transform?)` writable cell, `state.computed(fn)` read-only derived, `state.linked(fn, transform?)` writable-reseeded, `state.share(key, value)` / `state.shared(key)` ambient context. In `.abide` files the compiler lowers reads/writes to plain variable syntax; in `.ts` the cell is read/written through `.value`.
|
|
334
|
+
- `@abide/abide/ui/watch` — `watch(source, handler)`: the single reaction primitive over a thunk, cell, cell array, socket/stream, or rpc (see the grammar table). Client-only; the compiler strips author calls from SSR, and the `socket.watch` / `fn.watch` instance sugar is SSR-inert.
|
|
281
335
|
|
|
282
|
-
|
|
336
|
+
### Templating — `@documentation templating`
|
|
283
337
|
|
|
284
|
-
|
|
338
|
+
- `@abide/abide/ui/html` — `html(string)` / `` html`…` ``: brands trusted raw HTML for unescaped interpolation; the tag does not escape its interpolations — only feed it values you trust.
|
|
285
339
|
|
|
286
|
-
|
|
340
|
+
### Navigate — `@documentation navigate`
|
|
287
341
|
|
|
288
|
-
|
|
342
|
+
- `@abide/abide/ui/navigate` — `navigate(path, params?, options?)`: typed programmatic navigation off the route map; params interpolate through `url()` (base-correct). Options `{ replace, keepScroll }`. The module also exports `navigatePath(path, options?)` (already-resolved paths — the router's own entry, no re-basing) and the `NavigateOptions` type.
|
|
289
343
|
|
|
290
|
-
|
|
344
|
+
### Outbox — `@documentation ui`
|
|
291
345
|
|
|
292
|
-
|
|
346
|
+
- `@abide/abide/ui/outbox` — the global reactive outbox: `outbox()` lists every durable rpc's undelivered entries (each tagged with its `rpc`), member `outbox.retry()` drains every queue. Empty list server-side. Types `GlobalOutbox`, `GlobalOutboxEntry`.
|
|
293
347
|
|
|
294
|
-
|
|
348
|
+
### UI plumbing — `@documentation plumbing`
|
|
295
349
|
|
|
296
|
-
|
|
350
|
+
Compiler/runtime machinery — published so generated code, the type shadow, and
|
|
351
|
+
tests can import it, not for app code.
|
|
297
352
|
|
|
298
|
-
-
|
|
299
|
-
-
|
|
300
|
-
-
|
|
301
|
-
-
|
|
302
|
-
-
|
|
303
|
-
-
|
|
304
|
-
-
|
|
305
|
-
-
|
|
306
|
-
-
|
|
307
|
-
-
|
|
308
|
-
-
|
|
309
|
-
-
|
|
310
|
-
-
|
|
311
|
-
-
|
|
312
|
-
-
|
|
313
|
-
-
|
|
314
|
-
-
|
|
315
|
-
-
|
|
316
|
-
-
|
|
317
|
-
-
|
|
318
|
-
-
|
|
319
|
-
-
|
|
320
|
-
-
|
|
321
|
-
-
|
|
322
|
-
-
|
|
323
|
-
-
|
|
324
|
-
-
|
|
325
|
-
-
|
|
326
|
-
-
|
|
327
|
-
-
|
|
328
|
-
-
|
|
329
|
-
-
|
|
330
|
-
-
|
|
331
|
-
-
|
|
332
|
-
-
|
|
333
|
-
-
|
|
334
|
-
-
|
|
335
|
-
-
|
|
336
|
-
-
|
|
337
|
-
-
|
|
353
|
+
- `@abide/abide/ui/effect` — `effect(fn)`: the raw auto-tracked effect the compiler emits for bindings; authors use `watch`. Returns a disposer; SSR strips author calls.
|
|
354
|
+
- `@abide/abide/ui/currentScope` — `scope()`: the ambient lexical scope — the internal lowering host for `state`/`effect` (`derive`/`linked`/`effect`/`share` land here).
|
|
355
|
+
- `@abide/abide/ui/enterRenderScope` — `enterScope()`: opens an isolated scope for an SSR render; returns the previous scope to restore.
|
|
356
|
+
- `@abide/abide/ui/exitRenderScope` — `exitScope(previous)`: restores the scope `enterScope` saved.
|
|
357
|
+
- `@abide/abide/ui/router` — `router(...)`: the client router — fills layout/page chains into comment-marker outlet boundaries, intercepts in-app links, buckets/restores scroll per history entry.
|
|
358
|
+
- `@abide/abide/ui/startClient` — `startClient(...)`: the client entry — reads every `__SSR__` field into its shared slot (cache seed, health seed, client timeout, resume manifest), hydrates the chain, starts the router.
|
|
359
|
+
- `@abide/abide/ui/renderToStream` — `renderToStream(render)`: out-of-order SSR streaming — shell first, then one `<abide-resolve>` fragment per streaming await block in completion order; blocking (`then`-head) awaits render inline.
|
|
360
|
+
- `@abide/abide/ui/remoteProxy` — `remoteProxy(method, url, opts?)`: the browser-side rpc stub the bundler emits (fetch, decode, HttpError, outbox parking, streaming); the `DurableOptions` type rides along.
|
|
361
|
+
- `@abide/abide/ui/socketProxy` — `socketProxy(name)`: the browser-side socket stub — the identical `Socket<T>` shape over the page's lazily-opened multiplexed ws channel.
|
|
362
|
+
- `@abide/abide/ui/runtime/escapeKey` — JSON-Pointer-escapes one reactive-doc path key (`~`→`~0`, `/`→`~1`).
|
|
363
|
+
- `@abide/abide/ui/runtime/nextBlockId` — the next await/try block id in the current render pass (document order, shared across inlined children).
|
|
364
|
+
- `@abide/abide/ui/runtime/enterRenderPass` — marks entry into a render/mount; the outermost resets the block-id counter.
|
|
365
|
+
- `@abide/abide/ui/runtime/exitRenderPass` — unwinds `enterRenderPass`'s depth.
|
|
366
|
+
- `@abide/abide/ui/dom/mount` — mounts a top-level page/layout into a host under an ownership scope; returns the unmount.
|
|
367
|
+
- `@abide/abide/ui/dom/mountChild` — mounts a nested child component as a comment-marker range (dev builds also register it with the hot bridge).
|
|
368
|
+
- `@abide/abide/ui/dom/mountSlot` — mounts a component's passed-children content as a marker-bounded range.
|
|
369
|
+
- `@abide/abide/ui/dom/outlet` — a layout's outlet: an empty `<!--abide:outlet-->…<!--/abide:outlet-->` boundary the router fills.
|
|
370
|
+
- `@abide/abide/ui/dom/hydrate` — adopts server-rendered DOM instead of rebuilding: runs the build with a claim cursor over the existing nodes.
|
|
371
|
+
- `@abide/abide/ui/dom/skeleton` — the parsed-once static-structure clone path every bound element builds through; element holes by path, blocks by anchor comments.
|
|
372
|
+
- `@abide/abide/ui/dom/anchorCursor` — positions a skeleton-anchored block/slot at its `<!--a-->` anchor, in clone and hydrate modes alike.
|
|
373
|
+
- `@abide/abide/ui/dom/cloneStatic` — appends a fully-static subtree (no bindings, control flow, or listeners) by cloning.
|
|
374
|
+
- `@abide/abide/ui/dom/appendStatic` — a static text node: created (create mode) or claimed from server-rendered text (hydrate mode).
|
|
375
|
+
- `@abide/abide/ui/dom/appendText` — a reactive `{expr}` text node under a parent.
|
|
376
|
+
- `@abide/abide/ui/dom/appendTextAt` — a reactive text node mounted at a skeleton anchor (text interleaved with element siblings).
|
|
377
|
+
- `@abide/abide/ui/dom/appendSnippet` — mounts a `{snippet(args)}` interpolation's builder into a marker-bounded range.
|
|
378
|
+
- `@abide/abide/ui/dom/text` — a text node whose content tracks a reactive read.
|
|
379
|
+
- `@abide/abide/ui/dom/attr` — binds an element attribute to a read (boolean true → bare attribute, false/nullish → removed).
|
|
380
|
+
- `@abide/abide/ui/dom/on` — attaches an event listener whose removal is registered with the ownership scope.
|
|
381
|
+
- `@abide/abide/ui/dom/attach` — runs an `attach={fn}` attachment and registers its optional teardown.
|
|
382
|
+
- `@abide/abide/ui/dom/bindSelectValue` — two-way `<select>` binding that re-applies the selection when the option set changes (late-mounting `{#for}`/async options; `multiple` binds an array).
|
|
383
|
+
- `@abide/abide/ui/dom/each` — keyed `{#for}` runtime: marker-bounded rows reconciled by key.
|
|
384
|
+
- `@abide/abide/ui/dom/eachAsync` — `{#for await}` runtime: rows append/reconcile as the AsyncIterable yields.
|
|
385
|
+
- `@abide/abide/ui/dom/when` — `{#if}` runtime (single-branch swap in a marker-bounded range).
|
|
386
|
+
- `@abide/abide/ui/dom/switchBlock` — `{#switch}` runtime (also `{#if}` chains with `{:else if}` branches).
|
|
387
|
+
- `@abide/abide/ui/dom/awaitBlock` — `{#await}` runtime: pending → resolved/error branch swap, teardown-generation guarded.
|
|
388
|
+
- `@abide/abide/ui/dom/tryBlock` — `{#try}` runtime: synchronous error boundary around a subtree build.
|
|
389
|
+
- `@abide/abide/ui/dom/applyResolved` — consumes a streamed SSR `<abide-resolve>` chunk, swapping it into its await boundary (the bundle-side counterpart of the doc stream's inline scripts).
|
|
390
|
+
- `@abide/abide/ui/dom/mergeProps` — composes a child's props from explicit thunk runs, spread layers, and the trailing children layer.
|
|
391
|
+
- `@abide/abide/ui/dom/spreadProps` — wraps a `{...source}` spread layer so every key resolves to a live value thunk.
|
|
392
|
+
- `@abide/abide/ui/dom/restProps` — the live unconsumed-props object behind `const { …, ...rest } = props()`.
|
|
393
|
+
- `@abide/abide/ui/dom/spreadAttrs` — spreads an object's keys onto a native element (`<div {...rest}>`), keys enumerated once.
|
|
394
|
+
- `@abide/abide/ui/dom/readCall` — guarded method call on a reactive-doc read (the `model.draft.trim()` lowering).
|
|
338
395
|
|
|
339
396
|
## Build / tooling
|
|
340
397
|
|
|
341
|
-
### Building —
|
|
398
|
+
### Building — `@documentation building`
|
|
342
399
|
|
|
343
|
-
-
|
|
344
|
-
-
|
|
400
|
+
- `@abide/abide/build` — `build({ cwd, … })`: builds the client bundle into `dist/_app` (`.abide` loader, virtual-module resolver, optional Tailwind); production builds also emit `.gz` siblings; staged and atomically swapped so a live dev server never sees a half-built dist.
|
|
401
|
+
- `@abide/abide/compile` — `compile({ cwd, target?, outfile? })`: produces a standalone server executable (runs the client build first and embeds the compressed assets); returns the binary path.
|
|
345
402
|
|
|
346
|
-
###
|
|
403
|
+
### Tooling plumbing — `@documentation plumbing`
|
|
347
404
|
|
|
348
|
-
-
|
|
349
|
-
-
|
|
350
|
-
-
|
|
351
|
-
-
|
|
405
|
+
- `@abide/abide/preload` — the Bun preload installing the `.abide` loader, the virtual-module resolver, and a `.css` no-op loader — the same runtime for the server, scripts (`abide run`), and `bun test`.
|
|
406
|
+
- `@abide/abide/resolver-plugin` — the resolver plugin itself: `$`-alias + virtual-module (`abide:*`) resolution, rpc/socket module rewriting, side-crossing guards.
|
|
407
|
+
- `@abide/abide/ui-plugin` — the Bun plugin that compiles `.abide` single-file components to ES modules (layouts flagged by filename; scoped styles bundled into the entry stylesheet).
|
|
408
|
+
- `@abide/abide/tsconfig` — the base tsconfig apps extend (`bundler` resolution, strict, `types: ["bun"]`, erasable syntax only).
|
|
352
409
|
|
|
353
|
-
## Desktop bundle
|
|
410
|
+
## Desktop bundle — `@documentation bundle`
|
|
354
411
|
|
|
355
|
-
|
|
412
|
+
- `@abide/abide/bundle/BundleWindow` — the type of `src/bundle/window.ts`'s default export: window title/size plus custom `menu` entries inserted between the standard Edit and Window menus.
|
|
413
|
+
- `@abide/abide/bundle/BundleMenu` — one top-level custom menu (`label` + `items`).
|
|
414
|
+
- `@abide/abide/bundle/BundleMenuItem` — one menu entry: a divider, an `emit` item dispatching an `abide:menu` CustomEvent into the page (optional Cmd `shortcut`), or a `navigate` item repointing the window itself.
|
|
415
|
+
- `@abide/abide/bundle/onMenu` — `onMenu(handler)` / `onMenu(name, handler)`: subscribes to bundle menu clicks; returns an unsubscribe; inert during SSR and in plain browser tabs.
|
|
416
|
+
- `@abide/abide/bundle/bundled` — `bundled()`: true inside the desktop bundle (client: webview init flag; server: launcher-spawned process), false in a plain browser tab or on a remote server.
|
|
417
|
+
- `@abide/abide/server/appDataDir` — `appDataDir()`: the running bundle's per-user data dir, keyed by the bundler-injected program name; pure path computation, cwd-independent (`ABIDE_DATA_DIR` overrides).
|
|
356
418
|
|
|
357
|
-
|
|
358
|
-
- `abide/bundle/BundleWindow` — type of the default-exported `src/bundle/window.ts` window config (title/size/menus).
|
|
359
|
-
- `abide/bundle/BundleMenu` — a top-level macOS menu (`label` + `items`).
|
|
360
|
-
- `abide/bundle/BundleMenuItem` — a single menu entry (divider or a click that dispatches an `abide:menu` event).
|
|
361
|
-
- `abide/bundle/onMenu` — subscribe to bundle menu clicks (catch-all or filtered); returns an unsubscribe.
|
|
362
|
-
- `abide/bundle/bundled` — true when running inside the desktop bundle rather than a plain browser (isomorphic).
|
|
419
|
+
## MCP — `@documentation mcp`
|
|
363
420
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
### MCP — @documentation mcp
|
|
367
|
-
|
|
368
|
-
- `abide/mcp/createMcpServer` — construct the MCP server bound to the RPC registry (tools from `clients.mcp` RPCs + prompts + resources); `handle(request)` backs `/__abide/mcp`. Framework-internal.
|
|
421
|
+
- `@abide/abide/mcp/createMcpServer` — `createMcpServer(opts?)`: the MCP server behind `/__abide/mcp` — tools derived from every `clients.mcp` rpc and socket (a `<name>-tail` read tool, plus `<name>-publish` under `clientPublish`), prompts from `src/mcp/prompts/`, auth inherited from the inbound request, optional `authorize` hook. Framework-constructed; there is no user-authored server module.
|
|
369
422
|
|
|
370
423
|
## Testing
|
|
371
424
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
-
|
|
375
|
-
|
|
376
|
-
### Testing plumbing — @documentation plumbing
|
|
377
|
-
|
|
378
|
-
- `abide/test/createScriptedSurface` — a scripted MCP surface for driving an `AgentEngine` in tests.
|
|
379
|
-
- `abide/test/assertAgentFrameConformance` — assert an engine's frame stream satisfies the neutral `AgentFrame` contract.
|
|
425
|
+
- `@abide/abide/test/createTestApp` — `@documentation testing` — boots the app in-process for `bun test`: typed `app.rpc.<name>` / `app.sockets.<name>` clients (typed via the generated `testRpc.d.ts` / `testSockets.d.ts`), request scope included, no network.
|
|
426
|
+
- `@abide/abide/test/createScriptedSurface` — `@documentation plumbing` — a scripted `AgentSurface` for engine tests: declarative tool stubs in, an MCP surface out, every dispatched call recorded for assertions.
|
|
427
|
+
- `@abide/abide/test/assertAgentFrameConformance` — `@documentation plumbing` — collects an engine's frame stream and asserts the neutral `AgentFrame` contract (exactly one terminal `done`, paired `tool_use`/`tool_result`, string deltas); returns the frames for provider-specific assertions.
|
|
380
428
|
|
|
381
429
|
## Generated machine surfaces
|
|
382
430
|
|
|
383
|
-
Runtime routes the framework serves (the internal `/__abide/config|dev|reload|…`
|
|
384
|
-
routes are deliberate plumbing and not listed):
|
|
385
|
-
|
|
386
431
|
| Route | Serves |
|
|
387
432
|
| --- | --- |
|
|
388
|
-
| `/openapi.json` | OpenAPI
|
|
389
|
-
| `/__abide/mcp` | MCP endpoint (
|
|
390
|
-
| `/__abide/health` |
|
|
391
|
-
| `/__abide/
|
|
392
|
-
| `/__abide/
|
|
393
|
-
| `/__abide/
|
|
394
|
-
| `/__abide/
|
|
395
|
-
| `/__abide/inspector` |
|
|
433
|
+
| `/openapi.json` | The OpenAPI document projected from every rpc's method, URL, and schemas |
|
|
434
|
+
| `/__abide/mcp` | The MCP endpoint (tools from rpcs/sockets, prompts, resources); auth flows from the inbound request |
|
|
435
|
+
| `/__abide/health` | Liveness + identity JSON: framework version, app name/version, plus the app `health(request)` hook's fields; answered ahead of `app.handle` |
|
|
436
|
+
| `/__abide/identity` | Compatibility alias for the same payload with the legacy `abide: true` marker |
|
|
437
|
+
| `/__abide/sockets` | The single multiplexed WebSocket every client socket rides |
|
|
438
|
+
| `/__abide/sockets/<name>` | A socket's HTTP face: `GET` = retained tail as JSON (SSE stream under `Accept: text/event-stream`; `?tail=N` caps/seeds), `POST` = publish gated by `clientPublish`; 404 unless the socket is exposed to mcp/cli |
|
|
439
|
+
| `/__abide/cli` | `GET` = shell install script; `/__abide/cli/<platform>` streams the thin-CLI tarball (cli + server binaries, `.env` baked with `ABIDE_APP_URL`/`ABIDE_APP_TOKEN`) |
|
|
440
|
+
| `/__abide/inspector` | The `@abide/inspector` UI, mounted only under `ABIDE_ENABLE_INSPECTOR=true` |
|
|
441
|
+
| `/__abide/hot/<moduleId>` | Dev-only component hot-module endpoint backing `.abide` HMR |
|
|
396
442
|
|
|
397
443
|
## Environment variables
|
|
398
444
|
|
|
399
445
|
| Variable | Effect |
|
|
400
446
|
| --- | --- |
|
|
401
|
-
| `PORT` |
|
|
402
|
-
| `APP_URL` |
|
|
403
|
-
| `ABIDE_APP_URL` |
|
|
404
|
-
| `ABIDE_APP_TOKEN` | Bearer token the CLI
|
|
405
|
-
| `ABIDE_CLIENT_TIMEOUT` | ms
|
|
406
|
-
| `
|
|
407
|
-
| `
|
|
408
|
-
| `
|
|
409
|
-
| `
|
|
410
|
-
| `
|
|
411
|
-
| `
|
|
412
|
-
| `
|
|
413
|
-
| `
|
|
414
|
-
| `DEBUG` |
|
|
447
|
+
| `PORT` | Binds that exact port (a collision fails loudly); unset, the server finds an open port from the default |
|
|
448
|
+
| `APP_URL` | The app's public origin and optional mount base path (a bare `/v2` is tolerated); drives `url()` base-prefixing |
|
|
449
|
+
| `ABIDE_APP_URL` | The remote server a thin CLI binary talks to (baked into its downloaded `.env`) |
|
|
450
|
+
| `ABIDE_APP_TOKEN` | Bearer token the thin CLI sends; baked into the downloaded `.env` when the download request was authenticated |
|
|
451
|
+
| `ABIDE_CLIENT_TIMEOUT` | Default browser-side rpc timeout in ms — read at server boot, shipped to the client via the SSR payload |
|
|
452
|
+
| `ABIDE_DATA_DIR` | Overrides the per-user data directory on every platform |
|
|
453
|
+
| `ABIDE_ENABLE_INSPECTOR` | `true` mounts `@abide/inspector` at `/__abide/inspector` (the package must be installed) |
|
|
454
|
+
| `ABIDE_IDLE_TIMEOUT` | Bun per-connection idle timeout in seconds (default 10) |
|
|
455
|
+
| `ABIDE_INSPECT` | Enables right-click → Inspect in the desktop bundle's webview |
|
|
456
|
+
| `ABIDE_LOG_FORMAT` | `json` renders one JSON object per log line (default: tab-separated tsv) |
|
|
457
|
+
| `ABIDE_MAX_REQUEST_BODY_SIZE` | Server-wide max request body bytes (a per-rpc `maxBodySize` refines it) |
|
|
458
|
+
| `ABIDE_REACHABLE_TTL` | `reachable()` poll cadence / freshness in ms (default 30000) |
|
|
459
|
+
| `ABIDE_REACHABLE_TIMEOUT` | `reachable()` per-probe bound in ms (default 3000) |
|
|
460
|
+
| `DEBUG` | Channel-gated diagnostics (`DEBUG=abide:rpc`, `abide:sockets`, `abide:build`, …); `DEBUG=-abide` silences the framework's own channel |
|
|
415
461
|
|
|
416
462
|
---
|
|
417
463
|
|
|
418
|
-
|
|
419
|
-
`bun run packages/abide/scripts/readmeSurfaces.ts`
|
|
420
|
-
export to catch any untagged export and re-derive the slug grouping.
|
|
464
|
+
This file mirrors `package.json`'s `exports`; after adding or renaming an
|
|
465
|
+
export, run `bun run packages/abide/scripts/readmeSurfaces.ts` and regenerate.
|