devframe 0.8.2 → 0.9.0-beta.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.
Files changed (103) hide show
  1. package/dist/_shared-CttmCMBi.mjs +70 -0
  2. package/dist/_shared-DmpWW-HH.d.mts +43 -0
  3. package/dist/adapters/build.d.mts +1 -1
  4. package/dist/adapters/build.mjs +6 -5
  5. package/dist/adapters/cac.d.mts +1 -1
  6. package/dist/adapters/cac.mjs +157 -1
  7. package/dist/adapters/dev.d.mts +20 -42
  8. package/dist/adapters/dev.mjs +2 -1
  9. package/dist/adapters/embedded.d.mts +1 -1
  10. package/dist/adapters/initiate.d.mts +223 -0
  11. package/dist/adapters/initiate.mjs +2 -0
  12. package/dist/adapters/mcp.d.mts +26 -2
  13. package/dist/adapters/mcp.mjs +2 -2
  14. package/dist/cli/main.mjs +2 -2
  15. package/dist/client/index.d.mts +70 -6
  16. package/dist/client/index.mjs +743 -408
  17. package/dist/constants.d.mts +19 -6
  18. package/dist/constants.mjs +19 -6
  19. package/dist/{context-CBg8iRbQ.mjs → context-C33rR7n0.mjs} +1 -1
  20. package/dist/{context-DoSozfvx.d.mts → context-CSCwoABx.d.mts} +1 -1
  21. package/dist/{host-h3-D2hYZvDK.mjs → context-Du11TLcO.mjs} +5 -255
  22. package/dist/dev-BEveeA5H.mjs +233 -0
  23. package/dist/{devframe-mQ4qZAuo.d.mts → devframe-Bdd9YXTy.d.mts} +88 -25
  24. package/dist/{diagnostics-D7wM2cwM.mjs → diagnostics-DLYH5oD3.mjs} +16 -0
  25. package/dist/dist-D8jAMwxU.mjs +227 -0
  26. package/dist/helpers/vite.d.mts +43 -39
  27. package/dist/helpers/vite.mjs +26 -38
  28. package/dist/host-agent-CpbAoqBx.mjs +230 -0
  29. package/dist/host-h3-CzCZwtuV.mjs +26 -0
  30. package/dist/{fetch-BKaD0Vb3.mjs → http-DLr_cJZ7.mjs} +42 -4
  31. package/dist/{index-b64Uuhy2.d.mts → index-CZRd2K1C.d.mts} +2 -2
  32. package/dist/{index-Dbw1p5ch.d.mts → index-DSCq4M4q.d.mts} +2 -31
  33. package/dist/index.d.mts +9 -4
  34. package/dist/index.mjs +8 -1
  35. package/dist/{instance-registry-BnnA2Eoh.mjs → instance-registry-BQqGoDO9.mjs} +9 -2
  36. package/dist/instance-shell-DBTXTSjN.d.mts +264 -0
  37. package/dist/instance-shell-KRdee1QF.mjs +485 -0
  38. package/dist/internal/index.d.mts +150 -0
  39. package/dist/internal/index.mjs +7 -0
  40. package/dist/node/auth.d.mts +2 -2
  41. package/dist/node/hub-internals.d.mts +2 -14
  42. package/dist/node/hub-internals.mjs +2 -2
  43. package/dist/node/index.d.mts +3 -267
  44. package/dist/node/index.mjs +3 -5
  45. package/dist/recipes/common-rpc-functions.d.mts +3 -3
  46. package/dist/recipes/interactive-auth.d.mts +3 -3
  47. package/dist/recipes/interactive-auth.mjs +6 -6
  48. package/dist/rolldown-runtime-JspESFgx.mjs +35 -0
  49. package/dist/rpc/dump.d.mts +77 -1
  50. package/dist/rpc/dump.mjs +1 -1
  51. package/dist/rpc/index.d.mts +2 -2
  52. package/dist/rpc/index.mjs +3 -17
  53. package/dist/rpc/transports/sse-client.d.mts +2 -0
  54. package/dist/rpc/transports/sse-client.mjs +142 -0
  55. package/dist/rpc/transports/sse-server.d.mts +61 -0
  56. package/dist/rpc/transports/sse-server.mjs +209 -0
  57. package/dist/rpc/transports/ws-bun.d.mts +35 -0
  58. package/dist/rpc/transports/ws-bun.mjs +31 -0
  59. package/dist/rpc/transports/ws-client.d.mts +1 -1
  60. package/dist/rpc/transports/ws-client.mjs +10 -18
  61. package/dist/rpc/transports/ws-server.d.mts +2 -2
  62. package/dist/rpc/transports/ws-server.mjs +2 -235
  63. package/dist/rpc-core-CGctXToO.d.mts +48 -0
  64. package/dist/rpc-core-CqcJkAu9.mjs +81 -0
  65. package/dist/{serialization-C8Mnw9hK.mjs → serialization-BHY8M5NQ.mjs} +1 -1
  66. package/dist/{shared-state-6kHolYZy.mjs → shared-state-fRRbRUtD.mjs} +1 -1
  67. package/dist/sse-client-BsIK3hMD.d.mts +37 -0
  68. package/dist/{dump-CgZShDRB.mjs → static-CvjkO8QE.mjs} +2 -265
  69. package/dist/{storage-CTNVbuFB.mjs → storage-BcmVEJRc.mjs} +2 -2
  70. package/dist/types/index.d.mts +3 -3
  71. package/dist/types/index.mjs +1 -6
  72. package/dist/utils/events.d.mts +1 -1
  73. package/dist/utils/launch-editor.mjs +1 -25
  74. package/dist/utils/open.mjs +1 -1
  75. package/dist/utils/serve-static.mjs +1 -1
  76. package/dist/utils/shared-state.d.mts +1 -1
  77. package/dist/utils/shared-state.mjs +1 -1
  78. package/dist/utils/simple-schema.d.mts +101 -1
  79. package/dist/utils/streaming-channel.d.mts +1 -1
  80. package/dist/validation-BiuDXTKW.mjs +266 -0
  81. package/dist/wire-codec-9VhIKnyp.mjs +58 -0
  82. package/dist/{ws-client-B6Tnr0ic.d.mts → ws-client-CdNuATYa.d.mts} +6 -1
  83. package/dist/ws-server-Bk1hOG3X.mjs +267 -0
  84. package/dist/{ws-server-uKQcClcJ.d.mts → ws-server-Ces08fjP.d.mts} +89 -8
  85. package/package.json +10 -9
  86. package/skills/devframe/SKILL.md +84 -85
  87. package/dist/_shared-bWRzeSa0.mjs +0 -19
  88. package/dist/adapters/cli.d.mts +0 -11
  89. package/dist/adapters/cli.mjs +0 -6
  90. package/dist/cac-D4_9ok0z.mjs +0 -157
  91. package/dist/dev-Bc49u3qg.mjs +0 -439
  92. package/dist/http-C4T68YV6.mjs +0 -38
  93. package/dist/index-vAX6bYuc.d.mts +0 -78
  94. package/dist/recipes/open-helpers.d.mts +0 -6
  95. package/dist/recipes/open-helpers.mjs +0 -6
  96. package/dist/server-CD8XmBXl.mjs +0 -167
  97. package/dist/server-UHWae43Q.d.mts +0 -149
  98. package/dist/simple-schema-BDzLeJDk.d.mts +0 -102
  99. package/dist/utils/promise.d.mts +0 -8
  100. package/dist/utils/promise.mjs +0 -15
  101. package/dist/utils/scope.d.mts +0 -11
  102. package/dist/utils/scope.mjs +0 -15
  103. package/dist/{open-Deb5xmIT.mjs → open-Dz4V4irZ.mjs} +1 -1
@@ -0,0 +1,264 @@
1
+ import { $ as DevframeRpcClientFunctions, G as DevframeNodeRpcSession, _ as ConnectionMeta, d as DevframeWsOptions, et as DevframeRpcServerFunctions, p as DevframeAuthHandler, u as DevframeSseOptions, x as DevframeNodeContext } from "./devframe-Bdd9YXTy.mjs";
2
+ import { d as DevframeRpcConnection, n as WsOriginRegistry, u as DevframeNodeRpcSessionMeta } from "./ws-server-Ces08fjP.mjs";
3
+ import "./index-CZRd2K1C.mjs";
4
+ import { BirpcGroup } from "birpc";
5
+ import { NodeAdapter } from "crossws/adapters/node";
6
+ import { Buffer } from "node:buffer";
7
+ import { IncomingMessage, Server, ServerResponse } from "node:http";
8
+ import { Duplex } from "node:stream";
9
+ import { H3 } from "h3";
10
+ //#region src/node/instance-registry.d.ts
11
+ /**
12
+ * One running devframe instance, as recorded in the instance registry.
13
+ * Records are self-describing JSON — additive fields are safe.
14
+ *
15
+ * @experimental The agent-native surface is experimental and may change
16
+ * without a major version bump until it stabilizes.
17
+ */
18
+ interface DevframeInstanceRecord {
19
+ /** Process id of the dev server. */
20
+ pid: number;
21
+ /** Listening port. */
22
+ port: number;
23
+ /** Dialable HTTP origin, e.g. `http://127.0.0.1:9876`. */
24
+ origin: string;
25
+ /** Base path the devframe is mounted at (trailing slash). */
26
+ basePath: string;
27
+ /** Definition id. */
28
+ id: string;
29
+ /** Definition display name. */
30
+ name?: string;
31
+ /** Working directory the instance was started from. */
32
+ rootDir: string;
33
+ /**
34
+ * Absolute URL path of the MCP Streamable-HTTP endpoint on `origin`, or
35
+ * `null` when the instance runs without an MCP route.
36
+ */
37
+ mcp: {
38
+ path: string;
39
+ } | null;
40
+ /** Epoch-ms timestamp of registration. */
41
+ startedAt: number;
42
+ }
43
+ /**
44
+ * Handle returned by {@link registerDevframeInstance}.
45
+ *
46
+ * @experimental
47
+ */
48
+ interface DevframeInstanceRegistration {
49
+ /** The registry file backing this registration. */
50
+ readonly file: string;
51
+ /** Remove the record (idempotent). Call on server close. */
52
+ unregister: () => void;
53
+ }
54
+ /**
55
+ * Record a running devframe instance in the global instance registry so
56
+ * discovery tooling (`devframe connect`, editor integrations) can find it
57
+ * without port guessing.
58
+ *
59
+ * `createDevServer` registers automatically; custom hosts that serve a
60
+ * devframe in-process (e.g. `@devframes/next`'s host inside a Next dev
61
+ * server) call this explicitly with the origin they are reachable at.
62
+ *
63
+ * The record is written atomically to `<dir>/<pid>-<port>.json` and removed
64
+ * by {@link DevframeInstanceRegistration.unregister}. Records surviving a
65
+ * crash are pruned by readers whose liveness probe fails. Registration never
66
+ * throws — a write failure degrades to a coded warning (`DF0045`), since a
67
+ * dev server must not die over discovery metadata.
68
+ *
69
+ * @experimental
70
+ */
71
+ declare function registerDevframeInstance(record: DevframeInstanceRecord, options?: {
72
+ instancesDir?: string;
73
+ }): DevframeInstanceRegistration;
74
+ /**
75
+ * Read the registry and split records into live and dead by probing each
76
+ * one's `__connection.json`, deleting dead records (prune-on-read). Live
77
+ * records carry the dialable origin the probe confirmed (a `localhost`
78
+ * record may come back as `127.0.0.1` / `[::1]`).
79
+ *
80
+ * A liveness probe only proves *something* answers on the record's port, so
81
+ * records left behind by killed processes shadow the server currently bound
82
+ * there: per `(port, basePath)` only the newest record survives, older
83
+ * ghosts are pruned with the dead.
84
+ *
85
+ * @experimental
86
+ */
87
+ declare function listLiveDevframeInstances(options?: {
88
+ instancesDir?: string;
89
+ timeoutMs?: number;
90
+ }): Promise<{
91
+ live: DevframeInstanceRecord[];
92
+ pruned: DevframeInstanceRecord[];
93
+ }>;
94
+ //#endregion
95
+ //#region src/node/instance-shell.d.ts
96
+ /**
97
+ * The live handle for a bound HTTP + WebSocket RPC server — what the
98
+ * side-car / shared-server tiers produce and what {@link createDevServer}
99
+ * re-exposes through its own return contract.
100
+ */
101
+ interface StartedServer {
102
+ /** Listening origin, e.g. `http://localhost:9999`. */
103
+ origin: string;
104
+ port: number;
105
+ app: H3;
106
+ /**
107
+ * The crossws node adapter driving the RPC socket (connected peers,
108
+ * pub/sub). Absent when the WebSocket transport is disabled (`ws: false`).
109
+ */
110
+ ws?: NodeAdapter;
111
+ rpcGroup: BirpcGroup<DevframeRpcClientFunctions, DevframeRpcServerFunctions, false>;
112
+ /**
113
+ * The {@link ConnectionMeta} descriptor for this server — the same shape a
114
+ * `__connection.json` route should serve so a devframe client's
115
+ * `resolveWsUrl` can dial back in.
116
+ */
117
+ connectionMeta: () => ConnectionMeta;
118
+ close: () => Promise<void>;
119
+ }
120
+ /**
121
+ * How the instance's RPC socket is bound:
122
+ *
123
+ * - `sidecar` — its own HTTP+WS server on a dedicated port (`ws.port` /
124
+ * `ws.sidecar`), advertised with that port.
125
+ * - `server` — a shared upgrade route on the host's `node:http` server.
126
+ * - `external` — no local transport: `ws.url` alone names a server that owns
127
+ * both the socket and its auth.
128
+ * - `unbound` — the transport exists but nothing is bound to it yet; the host
129
+ * drives it through {@link InstanceShell.handleUpgrade} /
130
+ * {@link InstanceShell.attach}.
131
+ * - `disabled` — `ws: false`: no WebSocket at all; clients connect over the
132
+ * SSE endpoint instead (`backend: 'sse'`).
133
+ */
134
+ type InstanceWsTier = 'sidecar' | 'server' | 'external' | 'unbound' | 'disabled';
135
+ /** The live shell surface an `init` / `mount` callback can reach. */
136
+ interface InstanceShellApi {
137
+ /** The normalized mount base, with leading and trailing slash. */
138
+ base: string;
139
+ /** The h3 app every route is mounted on. */
140
+ app: H3;
141
+ /** The public origin, once known (pinned, or derived from the first request). */
142
+ origin: () => string | undefined;
143
+ /** The connection meta, once the transport has resolved. */
144
+ connectionMeta: () => ConnectionMeta | undefined;
145
+ }
146
+ /** What an instance's own initialization contributes to the shell. */
147
+ interface InstanceShellInit<TContext extends DevframeNodeContext> {
148
+ /** The context every mounted surface shares. */
149
+ context: TContext;
150
+ /** The `mcp` entry to advertise, when an MCP route was mounted. */
151
+ mcp?: ConnectionMeta['mcp'];
152
+ /** Torn down before the transport on `close()` (e.g. MCP sessions). */
153
+ dispose?: () => Promise<void>;
154
+ }
155
+ interface CreateInstanceShellOptions<TContext extends DevframeNodeContext> {
156
+ /** Normalized mount base (leading and trailing slash). */
157
+ base: string;
158
+ /** h3 app to mount on. A fresh one is created when omitted. */
159
+ app?: H3;
160
+ /** Public origin, or a getter. Derived from the first request when omitted. */
161
+ origin?: string | (() => string);
162
+ /** Resolved auth intent: `undefined`/`true` gates, `false` opts out, a handler installs a scheme. */
163
+ auth?: boolean | DevframeAuthHandler;
164
+ /** Host `node:http` server to share the WS upgrade with. */
165
+ server?: Server;
166
+ /** Explicit WebSocket control — see {@link DevframeWsOptions}. `false` disables the socket (SSE-only). */
167
+ ws?: DevframeWsOptions | false;
168
+ /** SSE endpoint control — enabled by default; `false` disables, an object renames the route. */
169
+ sse?: boolean | DevframeSseOptions;
170
+ /** Bind host for a side-car WebSocket server. Default: `localhost`. */
171
+ host?: string;
172
+ /** Extra WS-upgrade origins beyond the loopback default; `false` disables the gate. */
173
+ allowedOrigins?: readonly string[] | WsOriginRegistry | false;
174
+ /** Destroy off-route upgrades on a shared `server`. */
175
+ destroyUnmatchedUpgrades?: boolean;
176
+ onPeerConnect?: (connection: DevframeRpcConnection, session: DevframeNodeRpcSession) => void;
177
+ onPeerDisconnect?: (connection: DevframeRpcConnection, meta: DevframeNodeRpcSessionMeta) => void;
178
+ /**
179
+ * Advertise the WS and SSE routes as base-absolute paths (`<base>__ws` /
180
+ * `<base>__sse`) instead of the base-relative default. A hub serves one
181
+ * meta document from several bases, so its clients need the absolute form
182
+ * to resolve the same endpoints.
183
+ */
184
+ absoluteWsPath?: boolean;
185
+ /** Pick the first port a `ws.sidecar` server tries. Default: a random free port. */
186
+ resolveSidecarPort?: (host: string) => Promise<number>;
187
+ /**
188
+ * Publish this instance in the global registry (`~/.devframe/instances/`)
189
+ * once its public origin is known — a dynamic import so the registry code
190
+ * stays out of instances that opt out. Omit to skip registration.
191
+ */
192
+ register?: InstanceRegisterConfig;
193
+ /** Create the context and mount everything that must precede the transport. */
194
+ init: (api: InstanceShellApi) => Promise<InstanceShellInit<TContext>>;
195
+ /** Mount the routes that describe the resolved transport (discovery, SPA). */
196
+ mount?: (context: TContext, meta: ConnectionMeta, api: InstanceShellApi) => void | Promise<void>;
197
+ /** Throw the instance's own diagnostic for `connectionMeta()` before readiness. */
198
+ onMetaUnavailable: () => never;
199
+ }
200
+ /**
201
+ * The identity a shell needs to publish itself in the global instance
202
+ * registry — the parts it can't derive on its own. The shell fills in
203
+ * `pid` / `origin` / `port` / `basePath` / `mcp` / `startedAt` once the
204
+ * origin resolves, then merges {@link InstanceRegisterConfig.overrides} last.
205
+ */
206
+ interface InstanceRegisterConfig {
207
+ /** Definition id (or a synthetic one for a hub). */
208
+ id: string;
209
+ /** Display name. */
210
+ name?: string;
211
+ /** Working directory the instance runs from. Default: `process.cwd()`. */
212
+ rootDir?: string;
213
+ /** Fields overriding the shell-derived record (from the public option's object form). */
214
+ overrides?: Partial<DevframeInstanceRecord>;
215
+ }
216
+ /**
217
+ * Translate the public `register?: boolean | Partial<DevframeInstanceRecord>`
218
+ * option into a shell {@link InstanceRegisterConfig}, or `undefined` when
219
+ * registration is opted out. The object form supplies record overrides on top
220
+ * of the caller-provided identity defaults.
221
+ */
222
+ declare function resolveInstanceRegister(option: boolean | Partial<DevframeInstanceRecord> | undefined, defaults: {
223
+ id: string;
224
+ name?: string;
225
+ rootDir?: string;
226
+ }): InstanceRegisterConfig | undefined;
227
+ /** Live internals the first-party adapters read off an instance. */
228
+ interface InstanceShellInternals {
229
+ readonly started?: StartedServer;
230
+ readonly authHandler?: DevframeAuthHandler;
231
+ }
232
+ interface InstanceShell<TContext extends DevframeNodeContext> {
233
+ base: string;
234
+ handler: (request: Request) => Promise<Response>;
235
+ nodeMiddleware: (req: IncomingMessage, res: ServerResponse, next?: (err?: unknown) => void) => void;
236
+ ready: Promise<void>;
237
+ context: Promise<TContext>;
238
+ connectionMeta: () => ConnectionMeta;
239
+ /** Complete a host server's `upgrade` event on the instance's socket. */
240
+ handleUpgrade: (req: IncomingMessage, socket: Duplex, head: Buffer) => void;
241
+ /** Route a host server's `upgrade` events to the instance's socket. */
242
+ attach: (server: Server) => () => void;
243
+ close: () => Promise<void>;
244
+ internals: InstanceShellInternals;
245
+ }
246
+ /** Compare two URL paths ignoring a trailing slash. */
247
+ declare function samePath(a: string, b: string): boolean;
248
+ /**
249
+ * The shared machinery behind `initDevframe` and `initHub`: one mount base,
250
+ * one h3 app, one lazily-derived public origin (and the auth banner that waits
251
+ * for it), one WebSocket binding, and the fetch / connect-middleware pair that
252
+ * serves them. Each factory supplies only what makes it itself — its context,
253
+ * its routes, its diagnostics — through `init` / `mount`.
254
+ *
255
+ * Nothing here listens on a port unless a side-car was explicitly requested:
256
+ * the default tier leaves the socket `unbound`, so a host chains it onto its
257
+ * own server through {@link InstanceShell.attach} /
258
+ * {@link InstanceShell.handleUpgrade}.
259
+ *
260
+ * @internal
261
+ */
262
+ declare function createInstanceShell<TContext extends DevframeNodeContext>(options: CreateInstanceShellOptions<TContext>): InstanceShell<TContext>;
263
+ //#endregion
264
+ export { InstanceShellInit as a, StartedServer as c, samePath as d, DevframeInstanceRecord as f, registerDevframeInstance as h, InstanceShellApi as i, createInstanceShell as l, listLiveDevframeInstances as m, InstanceRegisterConfig as n, InstanceShellInternals as o, DevframeInstanceRegistration as p, InstanceShell as r, InstanceWsTier as s, CreateInstanceShellOptions as t, resolveInstanceRegister as u };