Skip to content

Commit 02c23fd

Browse files
antfubotopencode
andcommitted
revert(devframe): keep devframe/adapters/embedded
Restore the `devframe/adapters/embedded` entry point (`createEmbedded`) that the 0.9 surface reduction had removed — kept as a named, discoverable adapter alongside cac/dev/build/mcp. Re-adds the export map / tsdown / alias plumbing, the source, the docs page + nav + adapter tables, the SKILL row, and the tsnapi snapshot, and drops the corresponding migration-0.9 note. Co-authored-by: opencode <noreply@opencode.ai>
1 parent 89bfb29 commit 02c23fd

14 files changed

Lines changed: 76 additions & 28 deletions

File tree

alias.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export const alias = {
3636
'devframe/adapters/dev': r('devframe/src/adapters/dev.ts'),
3737
'devframe/adapters/build': r('devframe/src/adapters/build.ts'),
3838
'devframe/helpers/vite': r('devframe/src/helpers/vite.ts'),
39+
'devframe/adapters/embedded': r('devframe/src/adapters/embedded.ts'),
3940
'devframe/initiate': r('devframe/src/adapters/initiate.ts'),
4041
'devframe/adapters/mcp': r('devframe/src/adapters/mcp/index.ts'),
4142
'@devframes/hub/client': r('hub/src/client/index.ts'),

docs/.vitepress/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ function adaptersItems(prefix: string) {
4747
{ text: 'Initiate (middleware)', link: `${prefix}/adapters/initiate` },
4848
{ text: 'Build', link: `${prefix}/adapters/build` },
4949
{ text: 'Vite', link: `${prefix}/adapters/vite` },
50+
{ text: 'Embedded', link: `${prefix}/adapters/embedded` },
5051
{ text: 'MCP', link: `${prefix}/adapters/mcp` },
5152
] satisfies DefaultTheme.NavItemWithLink[]
5253
}

docs/adapters/embedded.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
outline: deep
3+
---
4+
5+
# Embedded
6+
7+
Register a devframe into an already-running context at runtime. Mirrors the [`vite`](./vite) adapter's plugin-scan, but for callers that need dynamic, post-startup registration. The host decides the mount path; `embedded` is a hosted adapter and inherits the `/__<id>/` default when one is needed.
8+
9+
```ts
10+
import { createEmbedded } from 'devframe/adapters/embedded'
11+
import devframe from './devframe'
12+
13+
await createEmbedded(devframe, { ctx: existingCtx })
14+
```
15+
16+
| Option | Required | Description |
17+
|--------|----------|-------------|
18+
| `ctx` || Target `DevframeNodeContext` the devframe is registered into. |
19+
20+
Useful when a host loads devframes based on runtime conditions (feature flags, user opt-in, dynamic discovery) rather than static config.

docs/adapters/index.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ outline: deep
44

55
# Adapters
66

7-
An adapter takes a `DevframeDefinition` and deploys it into a specific runtime — a standalone CLI, a Vite plugin, a static snapshot, or an MCP server. Each adapter ships at its own entry point (`devframe/adapters/<name>`); the bundler pulls in only the ones you use. To register a definition into an already-running host, call its `setup` directly: `await def.setup(ctx)`.
7+
An adapter takes a `DevframeDefinition` and deploys it into a specific runtime — a standalone CLI, a Vite plugin, a static snapshot, an embedded host, or an MCP server. Each adapter ships at its own entry point (`devframe/adapters/<name>`); the bundler pulls in only the ones you use.
88

99
Every adapter factory has the shape `createXxx(devframeDef, options?)`. Some adapters draw on an optional peer dependency, installed only when you opt into that adapter: `cac` pulls in [`cac`](https://github.com/cacjs/cac), and `mcp` pulls in [`@modelcontextprotocol/server`](https://github.com/modelcontextprotocol/typescript-sdk).
1010

@@ -16,6 +16,7 @@ Every adapter factory has the shape `createXxx(devframeDef, options?)`. Some ada
1616
| [`dev`](./dev) | `devframe/adapters/dev` | `createDevServer(def, options?)` | Run the dev server programmatically — drive it from any CLI framework |
1717
| [`build`](./build) | `devframe/adapters/build` | `createBuild(def, options?)` | Offline reports, CI artifacts, deployable SPA snapshots |
1818
| [`vite`](./vite) | `@vitejs/devtools-kit/node` | `createPluginFromDevframe(def, options?)` | Mount the definition into Vite DevTools (or any compatible host) |
19+
| [`embedded`](./embedded) | `devframe/adapters/embedded` | `createEmbedded(def, { ctx })` | Runtime registration into an already-running host |
1920
| [`mcp`](./mcp) | `devframe/adapters/mcp` | `createMcpServer(def, options?)` | Exposing a devframe to coding agents |
2021

2122
## Mount paths
@@ -25,7 +26,7 @@ A devframe's SPA basePath depends on which adapter is running it:
2526
| Adapter kind | Default basePath | Reason |
2627
|--------------|------------------|--------|
2728
| `cli`, `spa`, `build` (standalone) | `/` | The devframe owns the origin. |
28-
| `vite`, embedding hosts (hosted) | `/__<id>/` | The devframe shares the origin with a host app and namespaces itself. |
29+
| `vite`, `embedded` (hosted) | `/__<id>/` | The devframe shares the origin with a host app and namespaces itself. |
2930

3031
Override either side explicitly with `DevframeDefinition.basePath`:
3132

docs/guide/index.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Devframe keeps its surface focused on one tool, so the same definition stays por
1515
- **One tool per definition.** A devframe describes a single integration. Deploy it through any adapter; host-level features that only matter when several tools share a UI (palettes, cross-tool toasts, unified terminals) come from whichever host you mount into — Vite DevTools is one example.
1616
- **Headless.** Hook into `onReady`, `cli.configure`, and friends to print your own startup banners and styling — Devframe stays out of the way.
1717
- **App-owned file watching.** Wire your own watcher (chokidar, fs.watch, …) and signal change via `ctx.rpc.sharedState.set(...)` or event-typed RPCs.
18-
- **Context-aware mount paths.** Standalone adapters (`cli`, `spa`, `build`) serve at `/` by default; hosted contexts (`vite`, or a host that calls `setup`) serve at `/.<id>/`. Override via `DevframeDefinition.basePath`.
18+
- **Context-aware mount paths.** Standalone adapters (`cli`, `spa`, `build`) serve at `/` by default; hosted adapters (`vite`, `embedded`) serve at `/.<id>/`. Override via `DevframeDefinition.basePath`.
1919
- **SPAs own their base at runtime.** Build with relative asset paths (`vite.base: './'`); `connectDevframe` discovers the effective base from the executing script's location.
2020
- **CLI flags compose.** The `cac` instance is exposed to both the devframe (`cli.configure`) and the caller of `createCac`, so capability flags and app flags merge cleanly.
2121

@@ -84,7 +84,7 @@ node ./my-devframe.js build # self-contained static deploy in dist-static/
8484
node ./my-devframe.js mcp # stdio MCP server (experimental)
8585
```
8686

87-
The CLI adapter serves the SPA at `/` by default. When the same devframe is embedded inside a host (`vite`, or a host that calls `setup`), the default becomes `/.my-devframe/`. Override either side via `defineDevframe({ basePath })`.
87+
The CLI adapter serves the SPA at `/` by default. When the same devframe is embedded inside a host (`vite`, `embedded`), the default becomes `/.my-devframe/`. Override either side via `defineDevframe({ basePath })`.
8888

8989
## Adapters at a glance
9090

@@ -95,10 +95,9 @@ Devframe deploys the same `DevframeDefinition` through one of these adapters:
9595
| `cli` | `createCac(d).parse()` | Standalone CLI with dev / build / mcp subcommands |
9696
| `vite` | `createPluginFromDevframe(d, opts?)` *(from `@vitejs/devtools-kit/node`)* | Mount the devframe into Vite DevTools (or another compatible host) |
9797
| `build` | `createBuild(d, opts?)` | Self-contained static deploy with baked RPC dumps |
98+
| `embedded` | `createEmbedded(d, { ctx })` | Runtime registration into an existing host |
9899
| `mcp` | `createMcpServer(d, opts)` | Model Context Protocol server |
99100

100-
To register a definition into an already-running host, call `await d.setup(ctx)` directly.
101-
102101
See [Adapters](/adapters/) for the full reference.
103102

104103
## Framework- and build-tool-agnostic

docs/guide/migration-0.9.md

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -114,24 +114,6 @@ import { defineDevframe, defineRpcFunction } from 'devframe'
114114

115115
`devframe/types` still resolves as the type-only subpath — useful for `declare module 'devframe/types'` augmentations — but `devframe` is the canonical import for both values and types.
116116

117-
## `devframe/adapters/embedded` is removed
118-
119-
`createEmbedded(def, { ctx })` was a one-line wrapper around the definition's own `setup`. Call `setup` directly to register a devframe into an already-running host context:
120-
121-
```ts
122-
// 0.8.x
123-
import { createEmbedded } from 'devframe/adapters/embedded'
124-
125-
await createEmbedded(def, { ctx })
126-
```
127-
128-
```ts
129-
// 0.9
130-
await def.setup(ctx)
131-
```
132-
133-
In a hub, `mountDevframe(ctx, def)` (from `@devframes/hub/node`) remains the way to register a devframe with the hub's dock/command wiring.
134-
135117
## `devframe/utils/{hash,promise,scope}` are removed
136118

137119
Three utility subpaths with no integration consumers are removed:

packages/devframe/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"./adapters/build": "./dist/adapters/build.mjs",
2424
"./adapters/cac": "./dist/adapters/cac.mjs",
2525
"./adapters/dev": "./dist/adapters/dev.mjs",
26+
"./adapters/embedded": "./dist/adapters/embedded.mjs",
2627
"./adapters/mcp": "./dist/adapters/mcp.mjs",
2728
"./client": "./dist/client/index.mjs",
2829
"./constants": "./dist/constants.mjs",
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import type { DevframeNodeContext } from '../types/context'
2+
import type { DevframeDefinition } from '../types/devframe'
3+
4+
export interface CreateEmbeddedOptions {
5+
/** Target context the devframe is registered into. Required. */
6+
ctx: DevframeNodeContext
7+
}
8+
9+
/**
10+
* Register a devframe into an already-running devframe/Kit context at
11+
* runtime. Mirrors what the Vite plugin scan does for devframes passed
12+
* as plugin options, but exposes the same flow to callers that need
13+
* dynamic, post-startup registration.
14+
*
15+
* The host owns the mount path; when a hosted mount is needed the
16+
* effective default follows the hosted rule of `def.basePath ?? '/__<id>/'`.
17+
*/
18+
export async function createEmbedded(d: DevframeDefinition, options: CreateEmbeddedOptions): Promise<void> {
19+
await d.setup(options.ctx)
20+
}

packages/devframe/tsdown.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ const serverEntries = {
102102
'adapters/cac': 'src/adapters/cac.ts',
103103
'adapters/dev': 'src/adapters/dev.ts',
104104
'adapters/build': 'src/adapters/build.ts',
105+
'adapters/embedded': 'src/adapters/embedded.ts',
105106
'adapters/initiate': 'src/adapters/initiate.ts',
106107
'adapters/mcp': 'src/adapters/mcp/index.ts',
107108
'cli/main': 'src/cli/main.ts',

plans/032-0.9-public-api-surface-reduction.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ guide).
6767
| `devframe/node/auth` | **Keep public** (low-level auth layer). |
6868
| `devframe/rpc/client` + `rpc/transports/ws-client` | **Keep both**, document as the low-level / test client. |
6969
| `devframe/rpc/server` + `rpc/transports/ws-server` | **Keep** (hand-rolled-server hosts use them). |
70-
| `devframe/adapters/embedded` | **Remove** (one-liner `d.setup(ctx)`). |
70+
| `devframe/adapters/embedded` | **Kept** (maintainer request — named, discoverable adapter for symmetry). |
7171
| `devframe/rpc/transports/ws-bun` | **Remove** (zero refs). |
7272
| `devframe/utils/hash`, `utils/promise`, `utils/scope` | **Remove** (zero refs). |
7373
| `devframe/utils/structured-clone` | **Keep**. |
@@ -90,9 +90,10 @@ consumer):
9090
hand-rolled-server host the ⚠️ note below anticipated. **Kept** (resolves the
9191
open question: keep it).
9292

93-
Net effect: dead-subpath removals are `embedded`, `utils/hash`, `utils/promise`,
93+
Net effect: dead-subpath removals are `utils/hash`, `utils/promise`, and
9494
`utils/scope` (not `ws-bun`); the `devframe/node` trim drops **9** internal
95-
exports, not 12.
95+
exports, not 12. `devframe/adapters/embedded` was initially removed but restored
96+
on maintainer request — it stays as a named, discoverable adapter.
9697

9798
### ⚠️ One item to confirm during review
9899

0 commit comments

Comments
 (0)