@popmelt.com/core 0.20.3 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +191 -4
- package/codex-plugin/.codex-plugin/plugin.json +1 -1
- package/dist/bridge-entry.mjs +75 -67
- package/dist/browser-runtime-EKYE44AB.mjs +2 -0
- package/dist/browser.d.mts +15 -0
- package/dist/browser.mjs +2 -0
- package/dist/{chunk-MEDUDCL6.mjs → chunk-DXJOWLYC.mjs} +1 -1
- package/dist/chunk-N4KO6CBX.mjs +1 -0
- package/dist/chunk-XXU4ARPL.mjs +448 -0
- package/dist/cli.mjs +110 -97
- package/dist/index.d.mts +10 -71
- package/dist/index.mjs +1 -447
- package/dist/media.d.mts +2 -2
- package/dist/options-5yRxW1AX.d.mts +66 -0
- package/dist/plugin-astro.d.mts +24 -7
- package/dist/plugin-astro.mjs +31 -1
- package/dist/plugin-nuxt.d.mts +8 -0
- package/dist/plugin-nuxt.mjs +29 -0
- package/dist/plugin-vite.d.mts +3 -1
- package/dist/plugin-vite.mjs +1 -1
- package/dist/server-AAS6LONR.mjs +222 -0
- package/dist/server.mjs +76 -68
- package/dist/{video-adapter-C5qDzl4Q.d.mts → video-adapter-CCLbp86L.d.mts} +1 -1
- package/dist/vite-client.d.ts +5 -0
- package/package.json +25 -1
- package/dist/server-H3GPTDBD.mjs +0 -214
package/README.md
CHANGED
|
@@ -36,6 +36,169 @@ To add local object recognition to an existing Popmelt project, use:
|
|
|
36
36
|
The integration installs See and adds it to the existing Core provider's
|
|
37
37
|
`extensions` array without replacing Core.
|
|
38
38
|
|
|
39
|
+
### Experimental standalone browser entry
|
|
40
|
+
|
|
41
|
+
The first framework-independent integration is available at `@popmelt.com/core/browser`.
|
|
42
|
+
It mounts Popmelt beside the host application, without JSX or a React provider in
|
|
43
|
+
your application code. React still renders Popmelt internally; the package's
|
|
44
|
+
existing React, React DOM, and Lucide React peer dependencies are still required.
|
|
45
|
+
This is an experimental DOM integration, not a claim of Vue/Svelte/Angular feature
|
|
46
|
+
parity. React-specific component hierarchy and library previews are not supplied
|
|
47
|
+
for other frameworks yet.
|
|
48
|
+
|
|
49
|
+
For a Vite host, keep the existing `@popmelt.com/core/vite` bridge plugin, then use
|
|
50
|
+
this in your browser entry:
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
if (import.meta.env.DEV) {
|
|
54
|
+
const { mountPopmelt } = await import('@popmelt.com/core/browser');
|
|
55
|
+
const popmelt = await mountPopmelt({ enabled: true });
|
|
56
|
+
import.meta.hot?.dispose(() => popmelt.unmount());
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Enablement is explicit: omitted/false `enabled` or a server-side call is a no-op
|
|
61
|
+
and does not load the renderer. `unmount()` removes the UI and releases its
|
|
62
|
+
subscriptions without deleting saved annotations or cancelling bridge jobs.
|
|
63
|
+
Call it before mounting again; simultaneous integrations on one page are rejected.
|
|
64
|
+
Use either this entry or `PopmeltProvider`, not both. Pass `bridgeUrl`, `projectId`,
|
|
65
|
+
or a host-router `navigate` callback when these are not supplied by your integration.
|
|
66
|
+
Explicit bridge/project options take effect before startup and restore prior
|
|
67
|
+
host bindings when unmounted; no manual browser-global assignment is needed.
|
|
68
|
+
|
|
69
|
+
For Vue, mount your app normally and mount Popmelt alongside it, not inside the
|
|
70
|
+
Vue component tree. Keep your Vue Vite plugin and add `popmelt()` to that same
|
|
71
|
+
plugin list. Connect the returned `unmount()` to your app's teardown (for example,
|
|
72
|
+
`app.onUnmount(() => popmelt.unmount())` in Vue 3.5+). With Vue Router, pass
|
|
73
|
+
`navigate: (url) => router.push(url)`; no router dependency is required by Core.
|
|
74
|
+
|
|
75
|
+
The plain HTML/JS fixture at `e2e/fixtures/browser` and Vue fixture at
|
|
76
|
+
`e2e/fixtures/vue` share a browser workflow: author and recover an annotation
|
|
77
|
+
draft through target replacement and page reload, submit it, receive streamed
|
|
78
|
+
and final replies, and continue the same thread after another target replacement.
|
|
79
|
+
Both verify durable thread history, stage a Steer edit, select Chat through the
|
|
80
|
+
toolbar, and recover the exact edited style and completed thread after reload.
|
|
81
|
+
Vanilla replacement creates a fresh DOM node without copying Popmelt attributes
|
|
82
|
+
or inline styles; Vue uses keyed rerenders. Both verify teardown/remount releases
|
|
83
|
+
Popmelt's UI and connection while preserving the host DOM and input state.
|
|
84
|
+
|
|
85
|
+
Vue additionally exercises real Vite SFC template/script hot updates and Vue
|
|
86
|
+
Router navigation/back. Hot updates must retain the same Popmelt renderer and
|
|
87
|
+
bridge connection, without a full-page reload. The tests edit temporary fixture
|
|
88
|
+
copies, not repository files.
|
|
89
|
+
Only the external provider process is controlled; HTTP, SSE, queue dispatch, and
|
|
90
|
+
durable thread storage use the real bridge. It does not run your installed agent.
|
|
91
|
+
Run both fixtures after building:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
pnpm run build
|
|
95
|
+
pnpm exec vitest run --config vitest.browser.config.ts e2e/browser-mount.browser.ts
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
For a fresh tarball installation with the real Vite bridge plugin, run
|
|
99
|
+
`pnpm run vue:smoke`. This opt-in check needs npm registry access and Chrome
|
|
100
|
+
(`CHROME_PATH` can override its location). It installs into a temporary Vue app,
|
|
101
|
+
verifies bridge startup/shutdown and the toolbar, and checks that the
|
|
102
|
+
development-only import is absent from production output. It does not publish
|
|
103
|
+
or replace the separate package-size release gate.
|
|
104
|
+
|
|
105
|
+
The plain HTML/JS fixture still uses Vite and installed npm peers; this does not
|
|
106
|
+
validate a bundler-free script tag or arbitrary static-server integration.
|
|
107
|
+
The journeys use stable target IDs and Chrome, not a cross-browser or arbitrary
|
|
108
|
+
DOM-identity matrix. They validate the client-side DOM boundary, not Vue component
|
|
109
|
+
metadata. Router guards, nested routes, and hash-history mode are
|
|
110
|
+
not yet covered. Vue and its test tooling are development dependencies only;
|
|
111
|
+
they do not add a second Popmelt UI implementation or become runtime dependencies.
|
|
112
|
+
|
|
113
|
+
### Experimental Nuxt integration
|
|
114
|
+
|
|
115
|
+
For Nuxt 4.5.2, install Popmelt and its internal renderer peers as development
|
|
116
|
+
dependencies, then add the module:
|
|
117
|
+
|
|
118
|
+
```sh
|
|
119
|
+
npm install -D @popmelt.com/core react react-dom lucide-react
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
// nuxt.config.ts
|
|
124
|
+
export default defineNuxtConfig({
|
|
125
|
+
modules: ['@popmelt.com/core/nuxt'],
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
No separate Vite plugin, React provider, or manual browser mount is needed.
|
|
130
|
+
The module starts the local bridge in development and mounts Popmelt after Nuxt
|
|
131
|
+
has mounted the client app. It uses Nuxt's router for navigation and releases
|
|
132
|
+
its bridge lease on graceful shutdown. When Nuxt's CLI exits immediately, the
|
|
133
|
+
existing lease-expiry cleanup stops an idle bridge within about a minute.
|
|
134
|
+
Production builds do not register the client
|
|
135
|
+
plugin or start the bridge. Optional `popmelt` settings are `port`, `projectRoot`,
|
|
136
|
+
and `bridge` (set `bridge: false` to disable automatic bridge startup).
|
|
137
|
+
|
|
138
|
+
Run `pnpm run nuxt:smoke` with a Nuxt-compatible Node version (22.19+, 24.11+,
|
|
139
|
+
or 26+) to check a fresh tarball installation. It requires npm registry access
|
|
140
|
+
and Chrome, like the Vue smoke check. The isolated fixture checks SSR/hydration,
|
|
141
|
+
thread recovery through navigation/back and template/script HMR, and production
|
|
142
|
+
exclusion. It also exercises annotation submission, streaming replies, same-thread
|
|
143
|
+
follow-ups, and staged style recovery through routing and reload. Provider responses
|
|
144
|
+
are controlled in that journey; it never launches your coding agent.
|
|
145
|
+
Nuxt 3, component metadata, and advanced router configurations are not yet tested.
|
|
146
|
+
|
|
147
|
+
### Experimental Svelte and SvelteKit
|
|
148
|
+
|
|
149
|
+
Tested with Svelte 5.57.0, SvelteKit 2.70.3, and Vite 8.2.2. Install the same
|
|
150
|
+
development dependencies used by the standalone entry:
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
npm install -D @popmelt.com/core react react-dom lucide-react
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Keep your existing Vite configuration and add `popmelt()` alongside `sveltekit()`
|
|
157
|
+
(or `svelte()` for a plain Svelte app):
|
|
158
|
+
|
|
159
|
+
```js
|
|
160
|
+
import { sveltekit } from '@sveltejs/kit/vite';
|
|
161
|
+
import { popmelt } from '@popmelt.com/core/vite';
|
|
162
|
+
|
|
163
|
+
export default { plugins: [sveltekit(), popmelt()] };
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Mount once in your root `+layout.svelte`, without replacing its existing content:
|
|
167
|
+
|
|
168
|
+
```svelte
|
|
169
|
+
<script>
|
|
170
|
+
import { onMount } from 'svelte';
|
|
171
|
+
import { goto } from '$app/navigation';
|
|
172
|
+
import { bridgeUrl, projectId } from 'virtual:popmelt/bridge';
|
|
173
|
+
|
|
174
|
+
onMount(() => {
|
|
175
|
+
if (!import.meta.env.DEV || !bridgeUrl || !projectId) return;
|
|
176
|
+
let disposed = false;
|
|
177
|
+
const pending = import('@popmelt.com/core/browser').then(({ mountPopmelt }) => {
|
|
178
|
+
if (!disposed) return mountPopmelt({ enabled: true, bridgeUrl, projectId, navigate: goto });
|
|
179
|
+
});
|
|
180
|
+
void pending.catch(console.error);
|
|
181
|
+
return () => {
|
|
182
|
+
disposed = true;
|
|
183
|
+
void pending.then((handle) => handle?.unmount()).catch(() => {});
|
|
184
|
+
};
|
|
185
|
+
});
|
|
186
|
+
</script>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
For plain Svelte, place this in `App.svelte` and omit the `goto` import and
|
|
190
|
+
`navigate` option, or supply your own router callback. TypeScript projects can
|
|
191
|
+
add `/// <reference types="@popmelt.com/core/vite/client" />` to their app's
|
|
192
|
+
ambient declarations for the virtual module types.
|
|
193
|
+
|
|
194
|
+
This setup is development-only, including during SSR. It does not provide
|
|
195
|
+
Svelte component metadata or framework-specific library previews. Advanced
|
|
196
|
+
Kit routing, form actions, and deployment adapters beyond Node are not yet tested.
|
|
197
|
+
Run `pnpm run svelte:smoke` with Node 24.11+, npm registry access, and Chrome
|
|
198
|
+
to check fresh Svelte and SvelteKit installs; it does not launch your coding agent.
|
|
199
|
+
The SvelteKit check also runs the shared annotation/reply/style-edit journey,
|
|
200
|
+
including same-thread continuation and recovery after navigation and reload.
|
|
201
|
+
|
|
39
202
|
## Use Popmelt
|
|
40
203
|
|
|
41
204
|
1. Run your project locally and open it in a browser
|
|
@@ -83,11 +246,14 @@ Imprint opens the project's shared understanding. Use its filters to review grou
|
|
|
83
246
|
- Press Escape to close the open thread
|
|
84
247
|
- Press Backspace or Delete with a thread open, or with one of its historical annotations selected, to archive that thread
|
|
85
248
|
- Right-click a draft comment or staged Steer change in its annotation rail to remove only that draft item
|
|
249
|
+
- Right-click a replied rail to dismiss it from the canvas without deleting its history or reverting applied edits. Press **Command/Control+Z** outside a text editor to restore it before reloading. Rails with fresh drafts or active runs are protected.
|
|
86
250
|
- When a reply is queued, use its pencil or trash button to edit or delete that individual message before it starts. Save an edit with the checkmark or Command/Control+Enter; Escape cancels the edit
|
|
87
|
-
- Codex permission requests appear in the thread as a compact action card
|
|
251
|
+
- Codex permission requests appear chronologically in the thread as a compact action card, while the canvas and toolbar show **Approval needed**. Expand the card to inspect the exact command or file changes, then choose **Allow once** or **Deny**. Answered requests become an inline tool icon and label, retained in the thread history. Chat text is not a permission grant; Popmelt does not create remembered approvals. Your existing Codex permission rules still apply, so previously allowed commands may run without a new card. After 10 seconds without a response, a run waiting solely on approval yields to other queued jobs. Approving it while parked moves it to the front of the waiting queue, without interrupting active work. The exact action resumes only after reacquiring a slot; unanswered requests expire on resumption (or at 10 seconds if the run cannot safely yield). Same-thread follow-ups cannot overtake a parked run, and disconnected runs cannot be approved.
|
|
88
252
|
|
|
89
253
|
Interactive approvals require a Codex CLI that supports the app-server human-approval protocol (verified with 0.153.3). Popmelt checks the effective sandbox and reviewer before starting a coding turn; it does not fall back to unrestricted execution. Background memory review remains read-only and noninteractive. Network-specific and session-wide permission grants are not supported by this first version.
|
|
90
254
|
|
|
255
|
+
For an opt-in automatic-review trial, start the bridge or wrapped dev server with `POPMELT_CODEX_APPROVALS_REVIEWER=auto_review`. Eligible Codex approvals go to its native reviewer rather than a human; the sandbox and existing permission rules remain in place. This adds model usage and may still deny an action. The default remains human review (`user`); restarting without the variable restores it. Other providers are unchanged.
|
|
256
|
+
|
|
91
257
|
Archiving hides a thread from the active canvas without deleting its stored conversation. Delete shortcuts are disabled while a text field is focused.
|
|
92
258
|
|
|
93
259
|
### Pointer gestures
|
|
@@ -121,6 +287,8 @@ Ambient capture stays out of toolbar-owned runs, so opening a thread from the in
|
|
|
121
287
|
|
|
122
288
|
With your app running and the Popmelt canvas active, point at an element and ask Codex, “What am I pointing at?” You can also ask it to inspect a comment or explain what was discussed in an existing thread, without pointing at that item first.
|
|
123
289
|
|
|
290
|
+
The prompt hook also supplies a small, timestamped snapshot of bridge-managed runs in the conversation's primary and mounted stores: running, awaiting approval, and queued. This conversation is identified separately; other externally hosted conversations are not counted. Reads are bounded to 500 ms and unavailable bridges are reported as unavailable, not idle. This context is advisory—agents must check live status before restarting or interrupting a bridge.
|
|
291
|
+
|
|
124
292
|
Popmelt supplies the canvas target and lets Codex read saved threads, unsent drafts, and staged changes as separate kinds of context. A small animated eye appears beside the target or its visible annotation rail during targeted tool access—even if the element itself is offscreen. It indicates access to that item, not the full time the agent spends thinking about it. Reading context does not submit your drafts or start another agent run.
|
|
125
293
|
|
|
126
294
|
When several copies of the app are open, recent canvas interaction helps select the intended page. If the target is still ambiguous, Codex can ask which page you mean instead of guessing. Focus is a timestamped snapshot, so keep the intended target selected or point again when needed.
|
|
@@ -248,9 +416,14 @@ export default defineConfig({
|
|
|
248
416
|
});
|
|
249
417
|
```
|
|
250
418
|
|
|
251
|
-
### Astro
|
|
419
|
+
### Experimental Astro integration
|
|
252
420
|
|
|
253
|
-
|
|
421
|
+
For Astro 7.3.1, install Popmelt and its internal renderer peers as development
|
|
422
|
+
dependencies, then add the Astro integration:
|
|
423
|
+
|
|
424
|
+
```sh
|
|
425
|
+
npm install -D @popmelt.com/core react react-dom lucide-react
|
|
426
|
+
```
|
|
254
427
|
|
|
255
428
|
```js
|
|
256
429
|
// astro.config.mjs
|
|
@@ -262,6 +435,20 @@ export default defineConfig({
|
|
|
262
435
|
});
|
|
263
436
|
```
|
|
264
437
|
|
|
438
|
+
The integration starts the bridge and mounts Popmelt automatically in development;
|
|
439
|
+
no React island or provider is needed. It supports DOM annotations and style edits,
|
|
440
|
+
with thread recovery through reloads and Astro ClientRouter navigation. Production
|
|
441
|
+
builds and previews do not mount Popmelt or start its bridge.
|
|
442
|
+
|
|
443
|
+
If your project already mounts a Popmelt provider, use `popmelt({ client: false })`
|
|
444
|
+
to keep that provider in charge of the UI. The existing `port`, `projectRoot`,
|
|
445
|
+
`basePath`, and `bridge` options remain available.
|
|
446
|
+
|
|
447
|
+
Run `pnpm run astro:smoke` with Node 24.11+, npm registry access, and Chrome for
|
|
448
|
+
the fresh-install browser journey. Provider responses are controlled; it does not
|
|
449
|
+
launch your coding agent. Astro component metadata, framework-specific island
|
|
450
|
+
previews, and deployment adapters are not yet covered.
|
|
451
|
+
|
|
265
452
|
### Other development servers
|
|
266
453
|
|
|
267
454
|
The wrapper can start Popmelt alongside another development command:
|
|
@@ -439,7 +626,7 @@ Popmelt is designed for local development. As with any AI-assisted coding, your
|
|
|
439
626
|
| `I` | Enter Imprint mode |
|
|
440
627
|
| Command/Control+Enter | Send all pending work |
|
|
441
628
|
| Command/Control+C | Capture a screenshot for pending work when no text is selected |
|
|
442
|
-
| Command/Control+Z | Undo a pending change
|
|
629
|
+
| Command/Control+Z | Undo a pending change or thread dismissal |
|
|
443
630
|
| Command/Control+Shift+Z | Redo a pending change |
|
|
444
631
|
| Backspace/Delete | Archive the open or selected historical thread |
|
|
445
632
|
| Command/Control+Backspace/Delete | Clear all annotations and pending changes |
|