@popmelt.com/core 0.1.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/LICENSE ADDED
@@ -0,0 +1,126 @@
1
+ # Polyform Shield License 1.0.0
2
+
3
+ <https://polyformproject.org/licenses/shield/1.0.0>
4
+
5
+ ## Acceptance
6
+
7
+ In order to get any license under these terms, you must agree to
8
+ them as both strict obligations and conditions to all your licenses.
9
+
10
+ ## Copyright License
11
+
12
+ The licensor grants you a copyright license for the software to do
13
+ everything you might do with the software that would otherwise
14
+ infringe the licensor's copyright in it for any permitted purpose.
15
+ However, you may only distribute the software according to
16
+ [Distribution License](#distribution-license) and make changes or
17
+ new works based on the software according to [Changes and New Works
18
+ License](#changes-and-new-works-license).
19
+
20
+ ## Distribution License
21
+
22
+ The licensor grants you an additional copyright license to distribute
23
+ copies of the software. Your license to distribute covers
24
+ distributing the software with changes and new works permitted by
25
+ [Changes and New Works License](#changes-and-new-works-license).
26
+
27
+ ## Notices
28
+
29
+ You must ensure that anyone who gets a copy of any part of the
30
+ software from you also gets a copy of these terms or the URL above,
31
+ as well as copies of any plain-text lines beginning with
32
+ `Required Notice:` that the licensor provided with the software.
33
+ For example:
34
+
35
+ **Required Notice: Copyright Popmelt ([https://popmelt.com](https://popmelt.com))**
36
+
37
+ ## Changes and New Works License
38
+
39
+ The licensor grants you an additional copyright license to make
40
+ changes and new works based on the software for any permitted
41
+ purpose.
42
+
43
+ ## Patent License
44
+
45
+ The licensor grants you a patent license for the software that
46
+ covers patent claims the licensor can license, or becomes able to
47
+ license, that you would infringe by using the software.
48
+
49
+ ## Noncompete
50
+
51
+ Any purpose is a permitted purpose, except for providing any product
52
+ that competes with the licensor's product. If you are not sure
53
+ whether your use qualifies, contact the licensor.
54
+
55
+ **Licensor's Product: Agentic Design Collaboration Tools ([https://popmelt.com](https://popmelt.com))**
56
+
57
+ ## Personal Uses
58
+
59
+ Personal use for research, experiment, and testing for the benefit
60
+ of public knowledge, personal study, private entertainment, hobby
61
+ projects, amateur pursuits, or religious observance, without any
62
+ anticipated commercial application, is always a permitted purpose.
63
+
64
+ ## Noncommercial Organizations
65
+
66
+ Use by any charitable organization, educational institution,
67
+ public research organization, public safety or health organization,
68
+ environmental protection organization, or government institution
69
+ is always a permitted purpose regardless of the source of funding or
70
+ obligations resulting from the funding.
71
+
72
+ ## Fair Use
73
+
74
+ You may have "fair use" rights for the software under the law.
75
+ These terms do not limit them.
76
+
77
+ ## No Other Rights
78
+
79
+ These terms do not allow you to sublicense or transfer any of your
80
+ licenses to anyone else, or prevent the licensor from granting
81
+ licenses to anyone else. These terms do not imply any other
82
+ licenses.
83
+
84
+ ## Patent Defense
85
+
86
+ If you make any written claim that the software infringes or
87
+ contributes to infringement of any patent, your patent license for
88
+ the software granted under these terms ends immediately. If your
89
+ company makes such a claim, your patent license ends immediately for
90
+ work on behalf of your company.
91
+
92
+ ## Violations
93
+
94
+ The first time you are notified in writing that you have violated
95
+ any of these terms, or any agreement made under them, you can keep
96
+ your licenses by taking all practical steps to comply within 30 days
97
+ after the notice. If you do not do so, your licenses end immediately.
98
+
99
+ ## No Liability
100
+
101
+ ***As far as the law allows, the software comes as is, without any
102
+ warranty or condition, and the licensor will not be liable to you for
103
+ any damages arising out of these terms or the use or nature of the
104
+ software, under any kind of legal claim.***
105
+
106
+ ## Definitions
107
+
108
+ The **licensor** is the entity offering these terms, and the
109
+ **software** is the software the licensor makes available under these
110
+ terms.
111
+
112
+ **You** refers to the individual or entity agreeing to these terms.
113
+
114
+ **Your company** is any legal entity, sole proprietorship, or other
115
+ kind of organization that you work for, plus all organizations that
116
+ have control over, are under the control of, or are under common
117
+ control with that organization. **Control** means ownership of
118
+ substantially all the assets of an entity, or the power to direct
119
+ its management and policies by vote, contract, or otherwise. Control
120
+ can be direct or indirect.
121
+
122
+ **Your licenses** are all the licenses granted to you for the
123
+ software under these terms.
124
+
125
+ **Use** means anything you do with the software requiring one of
126
+ your licenses.
package/README.md ADDED
@@ -0,0 +1,176 @@
1
+ <p align="center">
2
+ <img src="src/assets/bar - popmelt.png" alt="Comment and zhuzh, then hand off." width="360" style="border-radius: 12px;" />
3
+ </p>
4
+
5
+ # Popmelt
6
+
7
+ ## What is it?
8
+
9
+ Popmelt is a design collaboration layer for AI models like Codex or Claude Code. It combines the best parts of collaborative design tools like Figma with the best way to design products today: in code, with AI, right in your browser.
10
+
11
+ It's a good fit for anyone involved in UI Design and Engineering for the web: it doesn't require deep technical expertise to use, and it won't get in your way if you *do* have that knowledge and want to use it.
12
+
13
+ Drop it into any React codebase and get a full design-feedback loop: draw on your running UI, pin feedback to elements, adjust style and layout directly, and give your AI the visual and technical context it needs to execute your vision in a keystroke.
14
+
15
+ <p align="center">
16
+ <img src="src/assets/annotations.jpg" alt="Popmelt annotations on a running app" width="720" style="border-radius: 6px;" />
17
+ </p>
18
+
19
+ **Popmelt is free to use and completely local**. It runs inside your codebase, with your existing AI CLI tools ([Claude Code](https://code.claude.com/docs/en/cli-reference), [Codex](https://developers.openai.com/codex/cli/)) handling code changes behind the scenes. You don't need an account to use it and we never see your data.
20
+
21
+ ## Why does it exist?
22
+
23
+ We're experienced product engineers and early adopters of AI coding models. We know their strengths, we know their weaknesses, and we've learned how to squeeze the best performance out of each generation. Popmelt was built to streamline our way of working, and we're proud to make it available to the design and engineering community.
24
+
25
+
26
+ ## How do I set it up?
27
+
28
+ If you're a human, we recommend asking your AI to handle installation for you. We cover the basics below, but your AI should be able to integrate it into whatever setup you throw at it as long as it supports Node and React.
29
+
30
+ ```bash
31
+ npm install @popmelt.com/core
32
+ ```
33
+
34
+ Peer dependencies: `react >=18`, `react-dom >=18`, `lucide-react >=0.400` (toolbar icons).
35
+
36
+
37
+ ### Frontend
38
+
39
+ Wrap your app in `PopmeltProvider`. In development, double-tap Cmd/Ctrl to open the toolbar.
40
+
41
+ ```tsx
42
+ import { PopmeltProvider } from '@popmelt.com/core';
43
+
44
+ export default function App() {
45
+ return (
46
+ <PopmeltProvider>
47
+ {/* your app */}
48
+ </PopmeltProvider>
49
+ );
50
+ }
51
+ ```
52
+
53
+ ### Backend
54
+
55
+ Start the bridge server so Popmelt can talk to Claude/Codex. In Next.js, `instrumentation.ts` is the cleanest place:
56
+
57
+ ```ts
58
+ // instrumentation.ts (Next.js)
59
+ export async function register() {
60
+ if (process.env.NODE_ENV === 'development' && process.env.NEXT_RUNTIME === 'nodejs') {
61
+ const { startPopmelt } = await import('@popmelt.com/core/server');
62
+ await startPopmelt({ port: 1111 });
63
+ }
64
+ }
65
+ ```
66
+
67
+ For other frameworks, call `startPopmelt()` anywhere in your dev server startup.
68
+
69
+ ### That's it
70
+
71
+ Open your app in the browser and double-tap Cmd (or Ctrl) to toggle the toolbar. Draw, type, point at things, hit Cmd+Enter. Your AI sees your annotated screenshot and code context and gets to work.
72
+
73
+ ## How do I use it?
74
+
75
+ ### Annotation tools
76
+
77
+ | Tool | Shortcut | What it does |
78
+ |------|----------|-------------|
79
+ | **Comment** | `C` | Click any element to pin a comment. Captures tag, classes, React component name, and ancestor context. |
80
+ | **Handle** | `H` | Drag padding, gap, border-radius, font-size, and line-height handles directly on elements. Shift to snap to a scale. |
81
+ | **Rectangle** | `R` | Draw a rectangle to highlight a region. Auto-prompts for a text label. |
82
+ | **Oval** | `O` | Draw an ellipse. |
83
+ | **Line** | `L` | Draw a straight line. |
84
+ | **Pen** | `P` | Freehand drawing. |
85
+ | **Text** | `T` | Click to place a text label anywhere. |
86
+
87
+ <p align="center">
88
+ <img src="src/assets/bar - comment.png" alt="Comment tool guidance" width="360" style="border-radius: 12px;" />
89
+ <img src="src/assets/bar - rectangle.png" alt="Rectangle tool guidance" width="360" style="border-radius: 12px;" />
90
+ <img src="src/assets/bar - text.png" alt="Text tool guidance" width="360" style="border-radius: 12px;" />
91
+ </p>
92
+
93
+ ### Handle tool
94
+
95
+ Switch to the Handle tool (`H`) and hover any element to see draggable handles for its spatial properties:
96
+
97
+ - **Padding** — drag the inner edges of any element to adjust padding per-side. Hold Shift to snap to a scale (0, 2, 4, 8, 12, 16, 20, 24, 32).
98
+ - **Gap** — drag between flex or grid children to adjust row/column gap.
99
+ - **Border radius** — drag element corners to round them.
100
+ - **Font size** — drag the right edge of a text element to resize.
101
+ - **Line height** — drag below a text element to adjust leading.
102
+
103
+ All changes apply as inline styles instantly. Hold Cmd/Alt and swipe on a flex container to cycle `justify-content` or `flex-direction`; hold Shift and swipe to cycle `align-items`. Cmd+Z / Cmd+Shift+Z to undo/redo any change.
104
+
105
+ <p align="center">
106
+ <img src="src/assets/bar - handle.png" alt="Handle tool guidance" width="360" style="border-radius: 12px;" />
107
+ </p>
108
+
109
+ ### Style panel
110
+
111
+ Right-click any element with the Comment tool to open the style panel. Edit layout (flex/grid direction, alignment, gap, sizing), typography (size, weight, line-height, letter-spacing, color), backgrounds, borders, and effects. Every modification is tracked and included in the feedback sent to your AI.
112
+
113
+ ### AI Collaboration
114
+
115
+ Cmd+Enter captures a full-page screenshot with your annotations baked in, bundles it with structured feedback (element selectors, style diffs, annotation text), and sends it to Claude or Codex via a local bridge server. Your AI reads the screenshot, sees exactly what you marked up, and edits your code. Cmd+C copies the screenshot to your clipboard instead.
116
+
117
+ - **Threaded conversations** — follow-up annotations on the same element continue the existing thread. Your AI sees prior context without re-explaining.
118
+ - **Questions** — if your AI needs clarification, it asks. A badge appears on the annotation; reply inline and the conversation continues.
119
+ - **Multi-task plans** — prefix your annotation with `/plan` and your AI decomposes the work into spatial tasks, each pinned to a region of the UI. Approve and they execute in sequence.
120
+ - **Provider switching** — toggle between Claude (Opus/Sonnet) and Codex at any time. Popmelt handles both.
121
+
122
+ <p align="center">
123
+ <img src="src/assets/bar - model.png" alt="Model switcher guidance" width="360" style="border-radius: 12px;" />
124
+ </p>
125
+
126
+ ### Persistence
127
+
128
+ Annotations and style modifications save to localStorage automatically. Cmd+Backspace clears unsent annotations and modifications.
129
+
130
+ Thread history persists to `.popmelt/threads.json` in your project root for cross-session continuity.
131
+
132
+ ## API
133
+
134
+ ### `PopmeltProvider`
135
+
136
+ ```tsx
137
+ <PopmeltProvider
138
+ enabled={true} // default: process.env.NODE_ENV === 'development'
139
+ bridgeUrl="http://localhost:1111" // default
140
+ >
141
+ ```
142
+
143
+ ### `startPopmelt(options?)`
144
+
145
+ ```ts
146
+ await startPopmelt({
147
+ port: 1111, // bridge server port (default: 1111)
148
+ projectRoot: '.', // working directory for your AI
149
+ claudePath: 'claude', // path to Claude CLI binary
150
+ maxTurns: 10, // max turns per job
151
+ });
152
+ ```
153
+
154
+ Returns `{ port: number, close: () => Promise<void> }`.
155
+
156
+ ### `usePopmelt()`
157
+
158
+ ```ts
159
+ const { isEnabled } = usePopmelt();
160
+ ```
161
+
162
+ ## Requirements
163
+
164
+ - React 18+
165
+ - Node.js 18+ (server)
166
+ - Claude CLI or Codex CLI installed for AI integration
167
+
168
+ ## License
169
+
170
+ [PolyForm Shield 1.0.0](./LICENSE)
171
+
172
+ **tl;dr** you can use and extend this software freely for yourself and your team. You may not sell it, offer it as a managed service, or take our code and create a competing AI design collaboration product/service with it. The software is offered as-is, and you're responsible for its use in your projects.
173
+
174
+ **If you need a custom license** for your use case, contact [reb@popmelt.com](mailto:reb@popmelt.com) with a brief outline of your desired terms.
175
+
176
+ <img src="src/assets/popmelt-logo.svg" alt="Comment and zhuzh, then hand off." width="64" />
@@ -0,0 +1,109 @@
1
+ import * as react from 'react';
2
+ import { PropsWithChildren } from 'react';
3
+
4
+ type PopmeltContextValue = {
5
+ isEnabled: boolean;
6
+ };
7
+ type PopmeltProviderProps = PropsWithChildren<{
8
+ enabled?: boolean;
9
+ bridgeUrl?: string;
10
+ }>;
11
+ declare function PopmeltProvider({ children, enabled, bridgeUrl, }: PopmeltProviderProps): react.JSX.Element;
12
+ declare function usePopmelt(): PopmeltContextValue;
13
+
14
+ type AnnotationLifecycleStatus = 'pending' | 'in_flight' | 'resolved' | 'needs_review' | 'dismissed' | 'waiting_input';
15
+ type ToolType = 'freehand' | 'line' | 'rectangle' | 'circle' | 'text' | 'inspector' | 'hand';
16
+ type Point = {
17
+ x: number;
18
+ y: number;
19
+ };
20
+ type ElementInfo = {
21
+ selector: string;
22
+ tagName: string;
23
+ id?: string;
24
+ className?: string;
25
+ textContent?: string;
26
+ dataAttributes?: Record<string, string>;
27
+ reactComponent?: string;
28
+ context?: string;
29
+ };
30
+ type StyleChange = {
31
+ property: string;
32
+ original: string;
33
+ modified: string;
34
+ };
35
+ type StyleModification = {
36
+ selector: string;
37
+ durableSelector?: string;
38
+ element: ElementInfo;
39
+ changes: StyleChange[];
40
+ captured?: boolean;
41
+ };
42
+ type Annotation = {
43
+ id: string;
44
+ type: ToolType;
45
+ points: Point[];
46
+ color: string;
47
+ strokeWidth: number;
48
+ text?: string;
49
+ fontSize?: number;
50
+ timestamp: number;
51
+ groupId?: string;
52
+ captured?: boolean;
53
+ status?: AnnotationLifecycleStatus;
54
+ question?: string;
55
+ resolutionSummary?: string;
56
+ replyCount?: number;
57
+ threadId?: string;
58
+ elements?: ElementInfo[];
59
+ linkedSelector?: string;
60
+ linkedAnchor?: 'top-left' | 'bottom-left';
61
+ planId?: string;
62
+ planTaskId?: string;
63
+ };
64
+ type BridgeStatus = {
65
+ ok: boolean;
66
+ activeJob: {
67
+ id: string;
68
+ status: string;
69
+ } | null;
70
+ queueDepth: number;
71
+ sessionId: string | null;
72
+ };
73
+ type BridgeEvent = {
74
+ type: 'job_started' | 'delta' | 'tool_use' | 'done' | 'error';
75
+ data: Record<string, unknown>;
76
+ timestamp: number;
77
+ };
78
+ type ClaudeResponse = {
79
+ jobId: string;
80
+ sessionId?: string;
81
+ text: string;
82
+ success: boolean;
83
+ toolsUsed: string[];
84
+ };
85
+
86
+ type AnnotationData = {
87
+ id: string;
88
+ type: string;
89
+ instruction?: string;
90
+ linkedSelector?: string;
91
+ elements: ElementInfo[];
92
+ };
93
+ type FeedbackData = {
94
+ timestamp: string;
95
+ url: string;
96
+ viewport: {
97
+ width: number;
98
+ height: number;
99
+ };
100
+ scrollPosition: {
101
+ x: number;
102
+ y: number;
103
+ };
104
+ annotations: AnnotationData[];
105
+ styleModifications: StyleModification[];
106
+ inspectedElement?: ElementInfo;
107
+ };
108
+
109
+ export { type Annotation, type BridgeEvent, type BridgeStatus, type ClaudeResponse, type ElementInfo, type FeedbackData, type Point, PopmeltProvider, type StyleChange, type StyleModification, type ToolType, usePopmelt };