@popmelt.com/core 0.14.2 → 0.15.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/README.md +32 -29
- package/codex-plugin/.codex-plugin/plugin.json +1 -1
- package/dist/adapter-three.d.mts +66 -0
- package/dist/adapter-three.mjs +1 -0
- package/dist/bridge-entry.mjs +68 -67
- package/dist/{chunk-LCXDL4VE.mjs → chunk-H4AAYYUP.mjs} +1 -1
- package/dist/cli.mjs +85 -84
- package/dist/index.d.mts +73 -30
- package/dist/index.mjs +39 -39
- package/dist/plugin-astro.mjs +1 -1
- package/dist/plugin-vite.mjs +1 -1
- package/dist/server-GNK5OVVW.mjs +211 -0
- package/dist/server.d.mts +2 -1
- package/dist/server.mjs +69 -68
- package/package.json +12 -2
- package/dist/server-PHS6N6ZW.mjs +0 -210
package/README.md
CHANGED
|
@@ -50,13 +50,13 @@ Double-click visible text to edit it directly. Popmelt records the text change s
|
|
|
50
50
|
|
|
51
51
|
Steer previews code-native design changes directly on the page. Point to an element, choose a family, narrow to a property, and choose a value. Click the target or press Enter at the value level to stage the preview.
|
|
52
52
|
|
|
53
|
-
| Keys
|
|
54
|
-
|
|
|
55
|
-
| `P` / `M`
|
|
56
|
-
| `B` / `R`
|
|
57
|
-
| `F` / `G`
|
|
58
|
-
| `FO` / `BG` | Type / background color
|
|
59
|
-
| `T` / `O`
|
|
53
|
+
| Keys | Family |
|
|
54
|
+
| ----------- | ---------------------------------- |
|
|
55
|
+
| `P` / `M` | Padding / margin |
|
|
56
|
+
| `B` / `R` | Borders / radii |
|
|
57
|
+
| `F` / `G` | Flexbox / grid |
|
|
58
|
+
| `FO` / `BG` | Type / background color |
|
|
59
|
+
| `T` / `O` | Transform / opacity and blend mode |
|
|
60
60
|
|
|
61
61
|
The omnidial can be driven entirely from the keyboard: `Q` and `E` move between properties, `A` and `D` or the arrow keys move between values, `W` or Enter goes deeper or applies, and `S` or Escape goes back. Press Space to search families, properties, colors, and values by name.
|
|
62
62
|
|
|
@@ -79,15 +79,18 @@ Archiving hides a thread from the active canvas without deleting its stored conv
|
|
|
79
79
|
|
|
80
80
|
### Pointer gestures
|
|
81
81
|
|
|
82
|
-
| Gesture
|
|
83
|
-
|
|
|
84
|
-
| Shake the pointer quickly
|
|
85
|
-
| Hold Command/Control while pointing
|
|
86
|
-
| Double-click text in Chat
|
|
87
|
-
| Click the toolbar annotation counter
|
|
88
|
-
| Scroll the annotation counter
|
|
89
|
-
| Hold the annotation counter
|
|
90
|
-
| Right-click Popmelt's canvas
|
|
82
|
+
| Gesture | Action |
|
|
83
|
+
| -------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
84
|
+
| Shake the pointer quickly | Switch between Chat and Steer |
|
|
85
|
+
| Hold Command/Control while pointing | Pass through the default target to the deepest element under the pointer |
|
|
86
|
+
| Double-click text in Chat | Edit the text directly |
|
|
87
|
+
| Click the toolbar annotation counter | Cycle through annotation bundles, including other routes |
|
|
88
|
+
| Scroll the annotation counter | Change the active annotation color |
|
|
89
|
+
| Hold the annotation counter | Reset the active color |
|
|
90
|
+
| Right-click Popmelt's canvas | Enter persistent page passthrough while keeping Popmelt overlays visible |
|
|
91
|
+
| Drag, scroll, pinch, or right-click in passthrough | Interact with the page and open its native context menu |
|
|
92
|
+
| Click a valid target in passthrough | Apply the active Comment or Steer action without leaving passthrough |
|
|
93
|
+
| Press Escape or choose another tool | Exit passthrough |
|
|
91
94
|
|
|
92
95
|
## Ambient Popmelt in Codex
|
|
93
96
|
|
|
@@ -243,19 +246,19 @@ Popmelt is designed for local development. As with any AI-assisted coding, your
|
|
|
243
246
|
|
|
244
247
|
## Useful shortcuts
|
|
245
248
|
|
|
246
|
-
| Shortcut
|
|
247
|
-
|
|
|
248
|
-
| Double-tap Command or Control
|
|
249
|
-
| `C`
|
|
250
|
-
| `S`
|
|
251
|
-
| `I`
|
|
252
|
-
| Command/Control+Enter
|
|
253
|
-
| Command/Control+C
|
|
254
|
-
| Command/Control+Z
|
|
255
|
-
| Command/Control+Shift+Z
|
|
256
|
-
| Backspace/Delete
|
|
257
|
-
| Command/Control+Backspace/Delete | Clear all annotations and pending changes
|
|
258
|
-
| Escape
|
|
249
|
+
| Shortcut | Action |
|
|
250
|
+
| -------------------------------- | ------------------------------------------------------------------- |
|
|
251
|
+
| Double-tap Command or Control | Open or collapse Popmelt |
|
|
252
|
+
| `C` | Enter Chat mode |
|
|
253
|
+
| `S` | Enter Steer mode |
|
|
254
|
+
| `I` | Enter Imprint mode |
|
|
255
|
+
| Command/Control+Enter | Send all pending work |
|
|
256
|
+
| Command/Control+C | Capture a screenshot for pending work when no text is selected |
|
|
257
|
+
| Command/Control+Z | Undo a pending change |
|
|
258
|
+
| Command/Control+Shift+Z | Redo a pending change |
|
|
259
|
+
| Backspace/Delete | Archive the open or selected historical thread |
|
|
260
|
+
| Command/Control+Backspace/Delete | Clear all annotations and pending changes |
|
|
261
|
+
| Escape | Go back, cancel, close, discard, or deselect in the current context |
|
|
259
262
|
|
|
260
263
|
Steer additionally owns the unmodified letter, arrow, Enter, Escape, and Space keys described above while it is active. Popmelt leaves these shortcuts alone while you are typing in an input, textarea, or editable text surface.
|
|
261
264
|
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Camera, Object3D, Raycaster, WebGLRenderer } from 'three';
|
|
2
|
+
|
|
3
|
+
type PopmeltSubjectBounds = {
|
|
4
|
+
left: number;
|
|
5
|
+
top: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
};
|
|
9
|
+
type PopmeltSubject = {
|
|
10
|
+
key: string;
|
|
11
|
+
label: string;
|
|
12
|
+
bounds: PopmeltSubjectBounds;
|
|
13
|
+
context?: string;
|
|
14
|
+
data?: Record<string, string>;
|
|
15
|
+
};
|
|
16
|
+
type PopmeltSurfaceSnapshot = {
|
|
17
|
+
element: HTMLCanvasElement;
|
|
18
|
+
dataUrl: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Minimal renderer boundary for non-DOM subjects. The adapter owns hit testing,
|
|
22
|
+
* durable keys, and viewport projection; Popmelt owns annotations and threads.
|
|
23
|
+
*/
|
|
24
|
+
type PopmeltSubjectAdapter = {
|
|
25
|
+
id: string;
|
|
26
|
+
hitTest(clientPoint: {
|
|
27
|
+
x: number;
|
|
28
|
+
y: number;
|
|
29
|
+
}): PopmeltSubject | null;
|
|
30
|
+
resolve(key: string): PopmeltSubject | null;
|
|
31
|
+
/** Optional bitmap capture for renderer surfaces that DOM cloning cannot read. */
|
|
32
|
+
captureSurfaces?(): readonly PopmeltSurfaceSnapshot[] | Promise<readonly PopmeltSurfaceSnapshot[]>;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
type ThreeSubjectAdapterOptions = {
|
|
36
|
+
canvas: HTMLCanvasElement;
|
|
37
|
+
camera: Camera;
|
|
38
|
+
scene: Object3D;
|
|
39
|
+
raycaster?: Raycaster;
|
|
40
|
+
/** Select a meaningful parent from the raw intersected render object. */
|
|
41
|
+
select?: (object: Object3D) => Object3D | null;
|
|
42
|
+
/** Override durable identity. Explicit application IDs are preferred. */
|
|
43
|
+
key?: (object: Object3D) => string | null | undefined;
|
|
44
|
+
label?: (object: Object3D) => string;
|
|
45
|
+
/** Add application-specific provenance or source hints to the model context. */
|
|
46
|
+
describe?: (object: Object3D) => Record<string, string | undefined>;
|
|
47
|
+
/** Capture the renderer's current frame for DOM-cloned screenshots. */
|
|
48
|
+
captureFrame?: () => string | null | Promise<string | null>;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Read the renderer's visible frame without requiring preserveDrawingBuffer.
|
|
52
|
+
* Rendering and reading synchronously preserves the application's real output
|
|
53
|
+
* pipeline while the previous render target and XR state are restored afterward.
|
|
54
|
+
*/
|
|
55
|
+
declare function captureThreeRendererFrame(renderer: WebGLRenderer, scene: Object3D, camera: Camera): string | null;
|
|
56
|
+
/** Stable while the scene's semantic hierarchy remains stable across reloads. */
|
|
57
|
+
declare function threeObjectPath(object: Object3D): string;
|
|
58
|
+
/**
|
|
59
|
+
* Collapses glTF material primitives such as `Object649_normal_0` onto their
|
|
60
|
+
* named parent `Object649`. Apps opt into this policy through `select` so raw
|
|
61
|
+
* mesh targeting remains available when material-level annotation is useful.
|
|
62
|
+
*/
|
|
63
|
+
declare function selectThreeNamedPrimitiveParent(object: Object3D): Object3D;
|
|
64
|
+
declare function createThreeSubjectAdapter(options: ThreeSubjectAdapterOptions): PopmeltSubjectAdapter;
|
|
65
|
+
|
|
66
|
+
export { type ThreeSubjectAdapterOptions, captureThreeRendererFrame, createThreeSubjectAdapter, selectThreeNamedPrimitiveParent, threeObjectPath };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Box3 as y,Raycaster as x,Vector2 as O,Vector3 as j}from"three";function b(e){return[e.x,e.y,e.z].map(n=>Number(n.toFixed(4))).join(", ")}function h(e){let n=e.material;return n&&(Array.isArray(n)?n:[n]).map(r=>r.name?.trim()||r.type).filter(Boolean).join(", ")||void 0}function M(e,n,c){let s=e.domElement.width,r=e.domElement.height;if(s<=0||r<=0)return null;let l=e.getRenderTarget(),t=e.xr.enabled;try{return e.xr.enabled=!1,e.setRenderTarget(null),e.render(n,c),e.domElement.toDataURL("image/png")}catch{return null}finally{e.setRenderTarget(l),e.xr.enabled=t}}function D(e){let s=(e.parent?.children??[]).filter(t=>t.type===e.type&&t.name===e.name),r=Math.max(0,s.indexOf(e)),l=e.name.trim()||e.type;return`${encodeURIComponent(l)}[${r}]`}function f(e){let n=[],c=e;for(;c?.parent;)n.push(D(c)),c=c.parent;return n.reverse().join("/")}function v(e){let n=e.userData.popmeltId;return typeof n=="string"&&n.trim()?n.trim():f(e)}function T(e){let n=e.userData.popmeltLabel;return typeof n=="string"&&n.trim()?n.trim():e.name.trim()||e.type}function R(e){let n=e;for(;n.parent;){let c=n.name.trim(),s=c.match(/^(.*)_(?:alpha|normal|material)(?:_\d+)+$/i),r=n.parent;for(;r.parent&&!r.name.trim();)r=r.parent;let l=r.name.trim();if(!l||!c.startsWith(`${l}_`)&&!s)break;n=r}return n}function P(e,n,c){let s=new y().setFromObject(e,!0);if(s.isEmpty())return null;let r=c.getBoundingClientRect(),l=[];for(let p of[s.min.x,s.max.x])for(let d of[s.min.y,s.max.y])for(let g of[s.min.z,s.max.z])l.push(new j(p,d,g).project(n));let t=l.map(p=>r.left+(p.x+1)/2*r.width),a=l.map(p=>r.top+(1-p.y)/2*r.height),i=Math.max(r.left,Math.min(...t)),o=Math.min(r.right,Math.max(...t)),m=Math.max(r.top,Math.min(...a)),u=Math.min(r.bottom,Math.max(...a));return o<=i||u<=m?null:{left:i,top:m,width:o-i,height:u-m}}function C(e){let n=e.raycaster??new x,c=new O,s=t=>e.key?.(t)??v(t),r=(t,a)=>{let i=s(t);if(!i)return null;let o=P(t,e.camera,e.canvas);return o?{key:i,label:e.label?.(t)??T(t),bounds:o,context:f(t),data:{renderer:"Three.js",objectType:t.type,...t.name?{objectName:t.name}:{},scenePath:f(t),...a&&a!==t?{renderObjectName:a.name.trim()||a.type,renderObjectType:a.type,renderScenePath:f(a)}:{},position:b(t.position),rotation:b(t.rotation),scale:b(t.scale),visible:String(t.visible),...h(t)?{material:h(t)}:{},...Object.fromEntries(Object.entries(e.describe?.(t)??{}).filter(m=>typeof m[1]=="string"&&m[1].length>0))}}:null},l=t=>{let a=null;return e.scene.traverse(i=>{!a&&s(i)===t&&(a=i)}),a};return{id:"three",hitTest({x:t,y:a}){let i=e.canvas.getBoundingClientRect();if(t<i.left||t>i.right||a<i.top||a>i.bottom)return null;c.set((t-i.left)/i.width*2-1,-((a-i.top)/i.height)*2+1),n.setFromCamera(c,e.camera);for(let o of n.intersectObject(e.scene,!0)){let m=e.select?e.select(o.object):R(o.object);if(!m||!m.visible)continue;let u=r(m,o.object);if(u)return u}return null},resolve(t){let a=l(t);return a?r(a):null},...e.captureFrame?{async captureSurfaces(){let t=await e.captureFrame?.();return t?[{element:e.canvas,dataUrl:t}]:[]}}:{}}}export{M as captureThreeRendererFrame,C as createThreeSubjectAdapter,R as selectThreeNamedPrimitiveParent,f as threeObjectPath};
|