@popmelt.com/core 0.8.17 → 0.10.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 +99 -162
- package/codex-plugin/.codex-plugin/plugin.json +43 -0
- package/codex-plugin/.mcp.json +12 -0
- package/codex-plugin/assets/popmelt-logo.svg +4 -0
- package/codex-plugin/hooks/hooks.json +41 -0
- package/codex-plugin/scripts/hook.mjs +19 -0
- package/codex-plugin/scripts/locate-cli.mjs +41 -0
- package/codex-plugin/scripts/mcp.mjs +15 -0
- package/codex-plugin/skills/popmelt-core/SKILL.md +23 -0
- package/dist/bridge-entry.mjs +74 -57
- package/dist/{chunk-5K5DWSWA.mjs → chunk-4RGL22V3.mjs} +1 -1
- package/dist/cli.mjs +108 -69
- package/dist/index.mjs +97 -42
- package/dist/memory-legacy.d.mts +5 -1
- package/dist/memory-legacy.mjs +1 -1
- package/dist/memory-store.d.mts +13 -1
- package/dist/memory-store.mjs +3 -3
- package/dist/memory.d.mts +5 -1
- package/dist/memory.mjs +1 -1
- package/dist/plugin-astro.mjs +1 -1
- package/dist/plugin-vite.mjs +1 -1
- package/dist/server-FHMR7WJR.mjs +238 -0
- package/dist/server.d.mts +28 -1
- package/dist/server.mjs +86 -69
- package/package.json +2 -1
- package/dist/server-MVQ4XBH3.mjs +0 -221
package/README.md
CHANGED
|
@@ -1,30 +1,86 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="src/assets/
|
|
2
|
+
<img src="https://raw.githubusercontent.com/popmelt/core/main/src/assets/popmelt-logo.svg" alt="Popmelt" width="72" />
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
# Popmelt
|
|
6
6
|
|
|
7
|
-
Popmelt is a design collaboration layer
|
|
7
|
+
Popmelt is a design collaboration layer that lives inside your local app projects. When your app is running locally, Popmelt appears as a toolbar in the browser.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Point to any part of your UI, describe what you have in mind, and work through it with Codex or Claude Code in a thread right on the page. You can stack as many threads as you want, so different ideas can move forward without losing their context.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
As you collaborate, Popmelt builds an **Imprint**: a living project memory of your intent, preferences, and design decisions. Later threads can use that shared understanding instead of starting from scratch.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Popmelt is local-first. Its annotations, screenshots, threads, and Imprint live with your project under `.popmelt/`.
|
|
14
|
+
|
|
15
|
+
## What you need
|
|
16
|
+
|
|
17
|
+
- A local React project
|
|
18
|
+
- Node.js 18 or newer
|
|
19
|
+
- React 18 or newer
|
|
20
|
+
- The Codex CLI or Claude Code CLI installed, available in your terminal, and signed in
|
|
21
|
+
|
|
22
|
+
The Codex and Claude Code desktop apps work too. Open your local app in their built-in browser and use Popmelt there just as you would in any other browser. The corresponding CLI still needs to be installed and signed in because it runs the threads.
|
|
23
|
+
|
|
24
|
+
## Install with your coding agent
|
|
25
|
+
|
|
26
|
+
From inside your project, give your coding agent this prompt:
|
|
27
|
+
|
|
28
|
+
> Let's install `@popmelt.com/core` in this project
|
|
29
|
+
|
|
30
|
+
Your agent can detect the framework, add the provider and integration, and preserve your existing development command. Restart the development server when it is finished.
|
|
31
|
+
|
|
32
|
+
## Use Popmelt
|
|
33
|
+
|
|
34
|
+
1. Run your project locally and open it in a browser
|
|
35
|
+
2. Double-tap Command on macOS or Control on Windows and Linux to open the Popmelt toolbar
|
|
36
|
+
3. Select part of the UI and leave a note about what should change
|
|
37
|
+
4. Press Command+Enter on macOS or Control+Enter on Windows and Linux to send the thread to your coding agent. Review the result and keep iterating from the same thread
|
|
38
|
+
5. To edit text directly, double-tap a text element. Popmelt marks the change so you can send it like any other annotation
|
|
39
|
+
|
|
40
|
+
Each annotation owns its thread. Status stays attached to the relevant part of the page while work is queued or running, and you can reopen any thread from its badge. Tool and Imprint receipts show what helped the agent reach its result.
|
|
41
|
+
|
|
42
|
+
## Ambient Popmelt in Codex
|
|
43
|
+
|
|
44
|
+
Popmelt can also pair ordinary project-bound Codex conversations with the same local project memory. Install the bundled Codex plugin once:
|
|
14
45
|
|
|
15
46
|
```bash
|
|
16
|
-
|
|
47
|
+
npx @popmelt.com/core codex install
|
|
17
48
|
```
|
|
18
49
|
|
|
19
|
-
|
|
50
|
+
Restart Codex completely, then begin a new conversation in the project. Popmelt will orient the conversation automatically when one store applies. If multiple stores apply, Codex will ask you to choose one writable primary store and any read-only mounted stores; it never infers write authority from directory nesting, recency, or store size.
|
|
51
|
+
|
|
52
|
+
Ambient capture stays out of toolbar-owned runs, so opening a thread from the in-page toolbar still produces exactly one toolbar job. Popmelt tools remain available for intentional context expansion, decision review, and Imprint grounding.
|
|
53
|
+
|
|
54
|
+
Useful diagnostics:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npx @popmelt.com/core codex status
|
|
58
|
+
npx @popmelt.com/core codex doctor
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Imprint
|
|
62
|
+
|
|
63
|
+
As you work, Popmelt recognizes choices that may be useful beyond the current thread and proposes an Imprint update:
|
|
20
64
|
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
65
|
+
- **Yes** adds the learning to the project's shared understanding
|
|
66
|
+
- **This time** keeps it local to the current situation
|
|
67
|
+
- **No** leaves the Imprint unchanged and gives you room to explain what Popmelt misunderstood
|
|
68
|
+
|
|
69
|
+
Confirmed Imprint knowledge is available to future threads when it is relevant. Popmelt can also search the project's collaboration history when a question depends on earlier discussions, feedback, or the evolution of a part of the UI.
|
|
70
|
+
|
|
71
|
+
Open the Imprint panel with `I` to inspect the project's current understanding, supporting evidence, relationships, and exceptions.
|
|
72
|
+
|
|
73
|
+
## Manual setup
|
|
74
|
+
|
|
75
|
+
Install Popmelt and its icon peer dependency:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npm install @popmelt.com/core lucide-react
|
|
79
|
+
```
|
|
24
80
|
|
|
25
81
|
### Add the provider
|
|
26
82
|
|
|
27
|
-
Wrap your
|
|
83
|
+
Wrap your app with `PopmeltProvider`. In Next.js, the component that calls `useRouter()` must be a client component.
|
|
28
84
|
|
|
29
85
|
```tsx
|
|
30
86
|
'use client';
|
|
@@ -40,13 +96,13 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
|
|
40
96
|
}
|
|
41
97
|
```
|
|
42
98
|
|
|
43
|
-
`navigate` is optional for single-page use. Pass your router's navigation function to
|
|
99
|
+
`navigate` is optional for single-page use. Pass your router's navigation function when Popmelt needs to restore annotations across routes.
|
|
44
100
|
|
|
45
101
|
### Next.js
|
|
46
102
|
|
|
47
|
-
|
|
103
|
+
Next.js needs both the command wrapper and the config wrapper.
|
|
48
104
|
|
|
49
|
-
|
|
105
|
+
Update the existing development script while preserving any flags already in use:
|
|
50
106
|
|
|
51
107
|
```json
|
|
52
108
|
{
|
|
@@ -56,13 +112,7 @@ For Next.js, both steps below are required.
|
|
|
56
112
|
}
|
|
57
113
|
```
|
|
58
114
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
```json
|
|
62
|
-
"dev": "popmelt wrap -- next dev --turbopack"
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
2. Wrap the Next config:
|
|
115
|
+
Then wrap the Next config:
|
|
66
116
|
|
|
67
117
|
```ts
|
|
68
118
|
// next.config.ts
|
|
@@ -73,11 +123,11 @@ const nextConfig = {};
|
|
|
73
123
|
export default withPopmelt(nextConfig);
|
|
74
124
|
```
|
|
75
125
|
|
|
76
|
-
The command wrapper starts the bridge
|
|
126
|
+
The command wrapper starts the project bridge. The config wrapper connects the browser toolbar to it. Using only one is not a complete setup.
|
|
77
127
|
|
|
78
128
|
### Vite
|
|
79
129
|
|
|
80
|
-
Add the Vite plugin
|
|
130
|
+
Add the Vite plugin:
|
|
81
131
|
|
|
82
132
|
```ts
|
|
83
133
|
// vite.config.ts
|
|
@@ -92,7 +142,7 @@ export default defineConfig({
|
|
|
92
142
|
|
|
93
143
|
### Astro
|
|
94
144
|
|
|
95
|
-
Add the Astro integration
|
|
145
|
+
Add the Astro integration:
|
|
96
146
|
|
|
97
147
|
```js
|
|
98
148
|
// astro.config.mjs
|
|
@@ -106,7 +156,7 @@ export default defineConfig({
|
|
|
106
156
|
|
|
107
157
|
### Other development servers
|
|
108
158
|
|
|
109
|
-
The wrapper
|
|
159
|
+
The wrapper can start Popmelt alongside another development command:
|
|
110
160
|
|
|
111
161
|
```json
|
|
112
162
|
{
|
|
@@ -116,137 +166,46 @@ The wrapper works with any dev command:
|
|
|
116
166
|
}
|
|
117
167
|
```
|
|
118
168
|
|
|
119
|
-
You can also start the bridge from custom server startup code:
|
|
120
|
-
|
|
121
|
-
```ts
|
|
122
|
-
import { startPopmelt } from '@popmelt.com/core/server';
|
|
123
|
-
|
|
124
|
-
await startPopmelt();
|
|
125
|
-
```
|
|
126
|
-
|
|
127
169
|
## Verify the installation
|
|
128
170
|
|
|
129
|
-
Start the app
|
|
171
|
+
Start the app normally:
|
|
130
172
|
|
|
131
173
|
```bash
|
|
132
174
|
npm run dev
|
|
133
175
|
```
|
|
134
176
|
|
|
135
|
-
|
|
177
|
+
Open the local app in a browser and double-tap Command or Control. The Popmelt toolbar should appear.
|
|
136
178
|
|
|
137
179
|
If the toolbar opens but cannot reach an AI, check that:
|
|
138
180
|
|
|
139
|
-
- The
|
|
140
|
-
-
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
-
|
|
144
|
-
## Installing with an AI
|
|
145
|
-
|
|
146
|
-
You can hand the following checklist to an AI coding agent:
|
|
147
|
-
|
|
148
|
-
> Install `@popmelt.com/core` and `lucide-react`. Add `PopmeltProvider` at the application root. Preserve the existing dev command, but for Next.js prefix it with `popmelt wrap --` and wrap `next.config` with `withPopmelt`. For Vite or Astro, add the corresponding Popmelt plugin. Start the app and verify that the toolbar opens after double-tapping Cmd/Ctrl and that the bridge belongs to this project.
|
|
181
|
+
- The selected AI CLI is installed and signed in
|
|
182
|
+
- A Next.js development script includes `popmelt wrap`
|
|
183
|
+
- The framework plugin or config wrapper is installed
|
|
184
|
+
- The development server was restarted after installation
|
|
149
185
|
|
|
150
|
-
|
|
186
|
+
## Data and privacy
|
|
151
187
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
Double-tap Cmd/Ctrl to open or collapse the toolbar. Hover any toolbar control to see its guidance panel.
|
|
155
|
-
|
|
156
|
-
| Tool | Shortcut | Use it to |
|
|
157
|
-
| --------- | -------- | ------------------------------------------------------------------------------------- |
|
|
158
|
-
| Comment | `C` | Pin feedback to a specific element and start a conversation with your AI. |
|
|
159
|
-
| Handle | `H` | Adjust layout, spacing, typography, color, borders, and effects directly on the page. |
|
|
160
|
-
| Rectangle | `R` | Mark a rectangular region. |
|
|
161
|
-
| Oval | `O` | Mark an oval region. |
|
|
162
|
-
| Line | `L` | Point at or connect parts of the UI. |
|
|
163
|
-
| Pen | `P` | Draw a freehand annotation. |
|
|
164
|
-
| Text | `T` | Add a label or edit existing page text inline. |
|
|
165
|
-
| Model | `M` | Review project patterns, components, and design-model suggestions. |
|
|
166
|
-
|
|
167
|
-
### Hand off work
|
|
168
|
-
|
|
169
|
-
Create one or more annotations, then press Cmd/Ctrl+Enter. Popmelt sends the visual state, element context, requested edits, and relevant project history to the selected AI.
|
|
170
|
-
|
|
171
|
-
The conversation opens in a thread beside the page. You can continue working while jobs run, reopen threads from their status badges, answer questions, and send follow-up guidance. Messages sent while an active thread is working are staged and delivered together on its next run.
|
|
172
|
-
|
|
173
|
-
### Comment on elements
|
|
174
|
-
|
|
175
|
-
Select Comment and click an element. Type what should change, then hand it off with Cmd/Ctrl+Enter. The annotation remains attached to that element as the page scrolls and across supported route changes.
|
|
176
|
-
|
|
177
|
-
If the AI needs clarification, the annotation shows a Question badge. Open the thread, answer it, and send the reply.
|
|
178
|
-
|
|
179
|
-
### Adjust UI directly
|
|
180
|
-
|
|
181
|
-
Select Handle and hover an element. Depending on the element, you can adjust:
|
|
182
|
-
|
|
183
|
-
- Width, height, padding, and gap
|
|
184
|
-
- Flex and grid alignment
|
|
185
|
-
- Font family, weight, size, line height, letter spacing, and alignment
|
|
186
|
-
- Text and background colors
|
|
187
|
-
- Opacity, radius, borders, and effects
|
|
188
|
-
- Raw CSS for properties not represented by a dedicated control
|
|
189
|
-
|
|
190
|
-
Right-click the focused element to open the full Handle panel. Values inherited from the page appear as placeholders until you explicitly change them. Hover and scrub numeric field icons to tune values; use modifier keys shown in the panel guidance for snapping and finer control.
|
|
191
|
-
|
|
192
|
-
Handle changes are previews. They are recorded with the annotation so the AI can implement the corresponding source-code changes.
|
|
193
|
-
|
|
194
|
-
You can also drag supported elements to propose a new position, and use Cmd/Ctrl+C and Cmd/Ctrl+V in Handle mode to duplicate supported page structures as visual guidance.
|
|
195
|
-
|
|
196
|
-
### Edit text inline
|
|
197
|
-
|
|
198
|
-
Select Text and hover page copy. Recognized text elements receive a bounding box. Click to edit the actual visible text in place, then finish the edit to retain it as a pending change.
|
|
199
|
-
|
|
200
|
-
Clicking outside editable page copy still creates a free-positioned text annotation.
|
|
201
|
-
|
|
202
|
-
### Draw visual guidance
|
|
203
|
-
|
|
204
|
-
Rectangle, Oval, Line, and Pen annotations are useful when the desired result is easier to show than describe. Add labels where useful, then submit them with the rest of the page context.
|
|
205
|
-
|
|
206
|
-
### Work across routes
|
|
207
|
-
|
|
208
|
-
Pass `navigate` to `PopmeltProvider` to enable route-aware annotations and multi-page capture. Annotation and status badges appear only on their relevant routes. When a handoff includes multiple routes, Popmelt captures each route and sends them together.
|
|
188
|
+
Popmelt stores its annotations, screenshots, threads, UI preferences, and Imprint locally under `.popmelt/`. Unsent annotation drafts and preview state also use browser storage.
|
|
209
189
|
|
|
210
|
-
|
|
190
|
+
When you send a thread, the context needed to complete that work is passed to your selected AI provider and is subject to that provider's privacy policy.
|
|
211
191
|
|
|
212
|
-
Popmelt
|
|
213
|
-
|
|
214
|
-
When supported by the selected model, the model guidance panel also exposes:
|
|
215
|
-
|
|
216
|
-
- Thinking or reasoning effort
|
|
217
|
-
- Standard or faster service tiers
|
|
218
|
-
|
|
219
|
-
These settings persist per provider and model and apply to annotations, replies, and model work.
|
|
220
|
-
|
|
221
|
-
## Threads and job status
|
|
222
|
-
|
|
223
|
-
Each handoff creates or continues a conversation thread. Status badges stay available while work is queued or running and return you to the associated element and conversation.
|
|
224
|
-
|
|
225
|
-
Use Cancel in the thread to stop the active job associated with that conversation. Closing a thread does not delete it. Delete its annotation to remove that thread, or use Cmd/Ctrl+Backspace to clear all local annotations and pending preview changes.
|
|
226
|
-
|
|
227
|
-
## Decisions and the project model
|
|
228
|
-
|
|
229
|
-
Completed annotation threads leave a decision history in the project. Popmelt uses that evidence to identify reusable design patterns rather than treating every edit as an isolated instruction.
|
|
230
|
-
|
|
231
|
-
When Popmelt finds a model opportunity, it places the proposal in the relevant annotation thread. Expand the proposal to inspect the exact changes, select only the entries you agree with, and apply or dismiss them. Applied changes contribute to the local project model.
|
|
232
|
-
|
|
233
|
-
Use the Model panel to inspect captured patterns and components or to synthesize model guidance from accumulated project history.
|
|
192
|
+
Popmelt is designed for local development. As with any AI-assisted coding, your agent may edit files or run commands, so review its work, use version control, and run your project tests before you ship.
|
|
234
193
|
|
|
235
194
|
## Useful shortcuts
|
|
236
195
|
|
|
237
|
-
| Shortcut
|
|
238
|
-
|
|
|
239
|
-
| Double-tap
|
|
240
|
-
|
|
|
241
|
-
|
|
|
242
|
-
|
|
|
243
|
-
|
|
|
244
|
-
|
|
|
245
|
-
| Backspace/Delete
|
|
246
|
-
|
|
|
247
|
-
| Escape
|
|
196
|
+
| Shortcut | Action |
|
|
197
|
+
| -------------------------------- | --------------------------------------------------------- |
|
|
198
|
+
| Double-tap Command or Control | Open or collapse Popmelt |
|
|
199
|
+
| `C` | Enter Comment mode |
|
|
200
|
+
| `I` | Enter Imprint mode |
|
|
201
|
+
| Command/Control+Enter | Send pending work |
|
|
202
|
+
| Command/Control+Z | Undo a pending change |
|
|
203
|
+
| Command/Control+Shift+Z | Redo a pending change |
|
|
204
|
+
| Backspace/Delete | Delete the selected annotation |
|
|
205
|
+
| Command/Control+Backspace/Delete | Clear all annotations and pending changes |
|
|
206
|
+
| Escape | Cancel the active edit or deselect the current annotation |
|
|
248
207
|
|
|
249
|
-
##
|
|
208
|
+
## Bridge commands
|
|
250
209
|
|
|
251
210
|
Run a bridge without wrapping another command:
|
|
252
211
|
|
|
@@ -254,38 +213,16 @@ Run a bridge without wrapping another command:
|
|
|
254
213
|
npx @popmelt.com/core bridge
|
|
255
214
|
```
|
|
256
215
|
|
|
257
|
-
Stop
|
|
216
|
+
Stop the bridge for the current project:
|
|
258
217
|
|
|
259
218
|
```bash
|
|
260
219
|
npx @popmelt.com/core stop
|
|
261
220
|
```
|
|
262
221
|
|
|
263
|
-
Start a configured bridge in server code:
|
|
264
|
-
|
|
265
|
-
```ts
|
|
266
|
-
await startPopmelt({
|
|
267
|
-
port: 1111,
|
|
268
|
-
projectRoot: '.',
|
|
269
|
-
devOrigin: 'http://localhost:3000',
|
|
270
|
-
provider: 'codex',
|
|
271
|
-
timeoutMs: undefined,
|
|
272
|
-
});
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
`startPopmelt()` returns the selected port, the stable project ID, and a `close()` function.
|
|
276
|
-
|
|
277
|
-
## Local project data
|
|
278
|
-
|
|
279
|
-
Popmelt writes project history under `.popmelt/`. Keep this directory when you want decisions, threads, and the local model to survive across sessions. The browser also uses local storage for unsent annotations and preview edits.
|
|
280
|
-
|
|
281
222
|
## License
|
|
282
223
|
|
|
283
224
|
[PolyForm Shield 1.0.0](./LICENSE)
|
|
284
225
|
|
|
285
226
|
You may use and extend Popmelt for yourself and your team. You may not sell it, offer it as a managed service, or use the code to create a competing product or service. The software is provided as-is.
|
|
286
227
|
|
|
287
|
-
For custom licensing, contact
|
|
288
|
-
|
|
289
|
-
<p align="center">
|
|
290
|
-
<img src="src/assets/popmelt-logo.svg" alt="Popmelt" width="64" />
|
|
291
|
-
</p>
|
|
228
|
+
For custom licensing, contact **reb@popmelt.com**.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "popmelt-core",
|
|
3
|
+
"version": "0.10.0",
|
|
4
|
+
"description": "Ambient project memory and shared understanding for Codex",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Popmelt",
|
|
7
|
+
"email": "reb@popmelt.com",
|
|
8
|
+
"url": "https://popmelt.com"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://popmelt.com",
|
|
11
|
+
"repository": "https://github.com/popmelt/core",
|
|
12
|
+
"license": "PolyForm-Shield-1.0.0",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"codex",
|
|
15
|
+
"memory",
|
|
16
|
+
"design",
|
|
17
|
+
"collaboration",
|
|
18
|
+
"knowledge"
|
|
19
|
+
],
|
|
20
|
+
"skills": "./skills/",
|
|
21
|
+
"mcpServers": "./.mcp.json",
|
|
22
|
+
"interface": {
|
|
23
|
+
"displayName": "Popmelt Core",
|
|
24
|
+
"shortDescription": "Ambient project memory for Codex",
|
|
25
|
+
"longDescription": "Pairs Codex conversations with Popmelt threads, retrieves accepted product truth and provisional explanations, records implementation evidence, and preserves explicit human authority over decisions and grounding.",
|
|
26
|
+
"developerName": "Popmelt",
|
|
27
|
+
"category": "Developer Tools",
|
|
28
|
+
"capabilities": [
|
|
29
|
+
"Read",
|
|
30
|
+
"Write"
|
|
31
|
+
],
|
|
32
|
+
"websiteURL": "https://popmelt.com",
|
|
33
|
+
"defaultPrompt": [
|
|
34
|
+
"Show the Popmelt context relevant to this task.",
|
|
35
|
+
"Inspect the current Popmelt thread.",
|
|
36
|
+
"Help me review the surfaced product decision."
|
|
37
|
+
],
|
|
38
|
+
"brandColor": "#111111",
|
|
39
|
+
"composerIcon": "./assets/popmelt-logo.svg",
|
|
40
|
+
"logo": "./assets/popmelt-logo.svg",
|
|
41
|
+
"logoDark": "./assets/popmelt-logo.svg"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"popmelt-core": {
|
|
4
|
+
"command": "node",
|
|
5
|
+
"args": ["./scripts/mcp.mjs"],
|
|
6
|
+
"cwd": ".",
|
|
7
|
+
"env_vars": ["POPMELT_CODEX_ORIENTATION_DIR", "POPMELT_CODEX_SESSION_DIR", "POPMELT_EXECUTION_OWNER", "POPMELT_PARENT_JOB_ID"],
|
|
8
|
+
"startup_timeout_sec": 40,
|
|
9
|
+
"tool_timeout_sec": 60
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="256" height="256" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect width="40" height="40" fill="#F1F1F1"/>
|
|
3
|
+
<path d="M11.1406 31.2559C11.2407 31.3875 11.351 31.5132 11.4697 31.6338L3.10449 40H2.39746L11.1406 31.2559ZM8.05371 40H7.34668L14.5498 32.7959C14.8554 32.7706 15.1541 32.7063 15.4414 32.6113L8.05371 40ZM18.2197 34.0762C18.3788 34.1569 18.5445 34.2272 18.7168 34.2861L13.0039 40H12.2969L18.2197 34.0762ZM17.9531 40H17.2461L26.1338 31.1113C26.438 31.0829 26.7427 31.0148 27.0439 30.9082L17.9531 40ZM40 22.9023L22.9033 40H22.1963L40 22.1953V22.9023ZM40 27.8525L27.8525 40H27.1455L40 27.1455V27.8525ZM40 32.8027L32.8027 40H32.0957L40 32.0957V32.8027ZM40 37.752L37.752 40H37.0449L40 37.0449V37.752ZM9.06543 28.3809C9.25255 28.4332 9.45183 28.4715 9.66504 28.4883L0 38.1543V37.4473L9.06543 28.3809ZM6.59375 25.9023C6.65822 26.0626 6.73171 26.2263 6.81445 26.3896L0 33.2041V32.4971L6.59375 25.9023ZM20.25 8.00293H20.249C21.5098 8.0286 22.7219 8.25094 23.8584 8.63672L23.8604 8.63574C23.8961 8.64787 23.9312 8.66145 23.9668 8.67383C24.0611 8.70686 24.1548 8.74106 24.248 8.77637C24.2915 8.79273 24.3357 8.80727 24.3789 8.82422L24.376 8.82617C27.6145 10.0955 30.1646 12.7301 31.3213 16.0234L31.3232 16.0225C31.3327 16.0493 31.3404 16.0766 31.3496 16.1035C31.7691 17.3256 32 18.6356 32 20C32 20.8726 31.9366 21.6706 31.7598 22.4902L31.7197 22.6328C31.6412 23.0066 31.5136 23.6108 31.3408 24.2217L31.3398 24.2246C31.2967 24.377 31.251 24.5299 31.2021 24.6797C30.9215 25.5403 30.5473 26.2998 30.0879 26.2998C29.7613 26.2996 29.5995 25.9674 29.4316 25.6221C29.2501 25.2487 29.0614 24.8605 28.6484 24.8604C27.8532 24.8604 27.2081 25.5046 27.208 26.2998V27.0771C27.2079 27.6079 26.9661 28.112 26.5205 28.4004C25.9146 28.7925 25.2357 28.6462 24.7959 28.2061L24.7949 28.208C24.7897 28.2028 24.7854 28.1967 24.7803 28.1914C24.7654 28.1761 24.7507 28.1606 24.7363 28.1445C24.7105 28.1156 24.6858 28.0857 24.6621 28.0547C24.6461 28.0339 24.6302 28.013 24.6152 27.9912C24.5931 27.9591 24.5726 27.9257 24.5527 27.8916C24.5392 27.8685 24.5261 27.8452 24.5137 27.8213C24.5093 27.8128 24.5043 27.8045 24.5 27.7959L24.501 27.7939C24.3932 27.5763 24.3282 27.3276 24.3281 27.0576V26.2998C24.328 25.5993 23.8278 25.0158 23.165 24.8867V24.8877C23.0752 24.8702 22.9826 24.8604 22.8877 24.8604C22.8446 24.8604 22.8019 24.8624 22.7598 24.8662C22.0247 24.9312 21.4483 25.5479 21.4482 26.2998C21.4482 26.9127 21.4608 27.5305 21.4736 28.1494L21.4951 29.3135C21.5 29.7013 21.5015 30.089 21.4971 30.4756C21.4874 31.3103 20.8426 32 20.0078 32C19.1732 31.9998 18.5292 31.3102 18.5195 30.4756C18.5159 30.1613 18.5176 29.8464 18.5205 29.5312V29.5322C18.5212 29.4593 18.5206 29.3864 18.5215 29.3135L18.5303 28.8154V28.8145C18.5343 28.5927 18.5384 28.371 18.543 28.1494C18.5558 27.5305 18.5684 28.1129 18.5684 27.5C18.5684 26.7047 17.9232 26.0596 17.1279 26.0596C16.907 26.0596 16.6978 26.1103 16.5107 26.1992C16.2161 26.3393 15.9767 26.5769 15.834 26.8701C15.8269 26.8846 15.8201 26.8993 15.8135 26.9141C15.7821 26.9845 15.7562 27.0579 15.7363 27.1338C15.7243 27.1798 15.7155 27.2267 15.708 27.2744C15.7012 27.3175 15.6953 27.361 15.6924 27.4053C15.6903 27.4366 15.6885 27.4681 15.6885 27.5V28.7383C15.6883 29.9234 14.4911 30.7248 13.4961 30.0811C13.0505 29.7926 12.8086 29.2886 12.8086 28.7578V26.2998C12.8086 25.9737 12.6984 25.674 12.5156 25.4326C12.4437 25.3381 12.3612 25.2521 12.2686 25.1777V25.1768C12.0219 24.9788 11.709 24.8604 11.3682 24.8604C10.9892 24.8604 10.8622 24.8872 10.7295 25.2295C10.5837 25.6055 10.4302 26 9.92773 26C9.33081 25.9996 8.95963 25.2403 8.71484 24.3799C8.5591 23.8325 8.45907 23.571 8.3623 23.0107C8.3501 22.9401 8.33284 22.8403 8.31738 22.7529C8.12812 21.9466 8.02043 21.1089 8.00293 20.249V20.25L8 20C8 19.8617 8.00317 19.724 8.00781 19.5869C8.00837 19.5703 8.00816 19.5537 8.00879 19.5371L8.00977 19.5352C8.0998 17.1716 8.87444 14.9844 10.1396 13.1631C10.1488 13.1499 10.1587 13.1372 10.168 13.124C12.255 10.1453 15.6582 8.15745 19.5352 8.00977L19.5371 8.00879C19.5537 8.00816 19.5703 8.00837 19.5869 8.00781C19.724 8.00317 19.8617 8 20 8L20.25 8.00293ZM5.72266 22.5303L0 28.2539V27.5469L5.62793 21.918C5.6553 22.1234 5.6868 22.3275 5.72266 22.5303ZM16.2637 26.8398L16.2617 26.8408C16.2784 26.8013 16.2954 26.7627 16.3135 26.7256C16.3203 26.7116 16.3275 26.6982 16.334 26.6855C16.3125 26.7277 16.289 26.7808 16.2637 26.8398ZM40 17.9531L33.9854 23.9668C34.051 23.6832 34.1043 23.4321 34.1445 23.2412L34.1641 23.1748L34.1865 23.0967L34.1963 23.0488L40 17.2461V17.9531ZM5.87012 16.7266C5.80321 17.0165 5.74649 17.3101 5.69727 17.6064L0 23.3047V22.5977L5.87012 16.7266ZM40 13.0039L34.4297 18.5732C34.409 18.3615 34.3832 18.1513 34.3535 17.9424L40 12.2969V13.0039ZM0 18.3555V17.6484L17.6484 0H18.3555L0 18.3555ZM40 8.05371L33.458 14.5947C33.3909 14.4277 33.3202 14.2625 33.2471 14.0986L40 7.34668V8.05371ZM0 13.4053V12.6982L12.6992 0H13.4062L0 13.4053ZM40 3.10352L31.6865 11.416C31.5868 11.2805 31.4851 11.1465 31.3809 11.0146L40 2.39648V3.10352ZM29.2881 8.86523C29.1595 8.75783 29.0288 8.65278 28.8965 8.5498L37.4473 0H38.1543L29.2881 8.86523ZM0 8.45508V7.74805L7.74805 0H8.45508L0 8.45508ZM26.2783 6.92578C26.1183 6.84878 25.9562 6.77534 25.793 6.7041L32.498 0H33.2051L26.2783 6.92578ZM17.6064 5.69727C17.3101 5.74649 17.0165 5.80321 16.7266 5.87012L22.5977 0H23.3047L17.6064 5.69727ZM22.5322 5.7207C22.3295 5.685 22.1254 5.65316 21.9199 5.62598L27.5469 0H28.2539L22.5322 5.7207ZM0 3.50586V2.79883L2.79883 0H3.50586L0 3.50586Z" fill="black"/>
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Ambient Popmelt Core turn lifecycle",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"UserPromptSubmit": [
|
|
5
|
+
{
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "node \"${PLUGIN_ROOT}/scripts/hook.mjs\"",
|
|
10
|
+
"timeout": 40,
|
|
11
|
+
"statusMessage": "Loading Popmelt context",
|
|
12
|
+
"additionalContextLimit": 12000
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"PostToolUse": [
|
|
18
|
+
{
|
|
19
|
+
"hooks": [
|
|
20
|
+
{
|
|
21
|
+
"type": "command",
|
|
22
|
+
"command": "node \"${PLUGIN_ROOT}/scripts/hook.mjs\"",
|
|
23
|
+
"timeout": 10
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"Stop": [
|
|
29
|
+
{
|
|
30
|
+
"hooks": [
|
|
31
|
+
{
|
|
32
|
+
"type": "command",
|
|
33
|
+
"command": "node \"${PLUGIN_ROOT}/scripts/hook.mjs\"",
|
|
34
|
+
"timeout": 15,
|
|
35
|
+
"statusMessage": "Recording the Popmelt turn"
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
|
|
4
|
+
import { locatePopmeltCli } from './locate-cli.mjs';
|
|
5
|
+
|
|
6
|
+
const input = readFileSync(0, 'utf8');
|
|
7
|
+
const cli = locatePopmeltCli();
|
|
8
|
+
const result = spawnSync(cli.command, [...cli.prefix, 'codex', 'hook'], {
|
|
9
|
+
cwd: process.cwd(),
|
|
10
|
+
env: process.env,
|
|
11
|
+
input,
|
|
12
|
+
encoding: 'utf8',
|
|
13
|
+
timeout: 45_000,
|
|
14
|
+
});
|
|
15
|
+
if (result.status === 0 && result.stdout?.trim()) {
|
|
16
|
+
process.stdout.write(result.stdout);
|
|
17
|
+
} else {
|
|
18
|
+
process.stdout.write('{}\n');
|
|
19
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join, parse, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
export function locatePopmeltCli(start = process.cwd()) {
|
|
6
|
+
try {
|
|
7
|
+
const runtimePath = join(dirname(fileURLToPath(import.meta.url)), '..', 'runtime.json');
|
|
8
|
+
const runtime = JSON.parse(readFileSync(runtimePath, 'utf8'));
|
|
9
|
+
if (typeof runtime.cliPath === 'string' && existsSync(runtime.cliPath)) {
|
|
10
|
+
return { command: process.execPath, prefix: [runtime.cliPath] };
|
|
11
|
+
}
|
|
12
|
+
} catch {
|
|
13
|
+
// Source checkouts do not have an installed-runtime pointer yet.
|
|
14
|
+
}
|
|
15
|
+
let current = resolve(start);
|
|
16
|
+
const root = parse(current).root;
|
|
17
|
+
while (true) {
|
|
18
|
+
const candidates = [
|
|
19
|
+
join(current, 'node_modules', '@popmelt.com', 'core', 'dist', 'cli.mjs'),
|
|
20
|
+
join(current, 'packages', 'popmelt', 'dist', 'cli.mjs'),
|
|
21
|
+
];
|
|
22
|
+
for (const candidate of candidates) {
|
|
23
|
+
if (existsSync(candidate)) return { command: process.execPath, prefix: [candidate] };
|
|
24
|
+
}
|
|
25
|
+
const packagePath = join(current, 'package.json');
|
|
26
|
+
if (existsSync(packagePath)) {
|
|
27
|
+
try {
|
|
28
|
+
const pkg = JSON.parse(readFileSync(packagePath, 'utf8'));
|
|
29
|
+
if (pkg.name === '@popmelt.com/core') {
|
|
30
|
+
const local = join(current, 'dist', 'cli.mjs');
|
|
31
|
+
if (existsSync(local)) return { command: process.execPath, prefix: [local] };
|
|
32
|
+
}
|
|
33
|
+
} catch {
|
|
34
|
+
// Ignore malformed package metadata and continue searching upward.
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (current === root) break;
|
|
38
|
+
current = dirname(current);
|
|
39
|
+
}
|
|
40
|
+
return { command: 'popmelt', prefix: [] };
|
|
41
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
|
|
3
|
+
import { locatePopmeltCli } from './locate-cli.mjs';
|
|
4
|
+
|
|
5
|
+
const cli = locatePopmeltCli();
|
|
6
|
+
const child = spawn(cli.command, [...cli.prefix, 'codex', 'mcp'], {
|
|
7
|
+
cwd: process.cwd(),
|
|
8
|
+
env: process.env,
|
|
9
|
+
stdio: 'inherit',
|
|
10
|
+
});
|
|
11
|
+
child.on('error', () => process.exit(1));
|
|
12
|
+
child.on('exit', (code, signal) => {
|
|
13
|
+
if (signal) process.kill(process.pid, signal);
|
|
14
|
+
else process.exit(code ?? 1);
|
|
15
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: popmelt-core
|
|
3
|
+
description: Use Popmelt Core when the user asks to inspect project memory, expand relevant product context, review a surfaced decision candidate, ground a surfaced Imprint explanation, or discuss the current Popmelt thread.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Popmelt Core
|
|
7
|
+
|
|
8
|
+
Popmelt pairs the current Codex conversation with a durable project thread. Ambient hooks already retrieve context and capture ordinary turns, so do not call tools merely to announce or duplicate that automatic work.
|
|
9
|
+
|
|
10
|
+
Use the tools deliberately:
|
|
11
|
+
|
|
12
|
+
- Pass the exact `tool session` ID supplied by the Ambient Popmelt Core context as `sessionId` on every tool call. This routes the call to the correct project even when the MCP process has a different working directory.
|
|
13
|
+
|
|
14
|
+
- Use `popmelt_orient_stores` only after the human explicitly chooses the writable primary store and any mounted read stores from an ambient orientation packet. Save that choice as the workspace default unless the human explicitly requests a session-only override. Store proximity, nesting, size, or recency never implies that choice.
|
|
15
|
+
- Use `popmelt_expand_context` when the automatically supplied packet is truncated or the user explicitly asks for broader history.
|
|
16
|
+
- Use `popmelt_inspect_thread` when the user asks to inspect the paired thread or its evidence.
|
|
17
|
+
- Use `popmelt_review_decision` only after the human explicitly resolves the exact surfaced candidate. Preserve the actions `accept`, `edit_and_accept`, `reject`, and `defer`. Never infer acceptance from implementation, praise, silence, or ambiguity.
|
|
18
|
+
- Use `popmelt_ground_imprint` only after the human explicitly answers a surfaced grounding question. Preserve the actions `yes`, `this_time`, and `no`.
|
|
19
|
+
- Use `popmelt_assess_turn` only when the current collaboration changed reusable shared understanding. Ordinary completion and tool evidence are captured automatically.
|
|
20
|
+
|
|
21
|
+
Accepted product decisions are authoritative within scope. Imprint explanations are provisional and advisory. The human remains the authority for both decision acceptance and Imprint grounding.
|
|
22
|
+
|
|
23
|
+
If Popmelt reports `already_managed_by_bridge`, stop calling Popmelt Core tools for that run; the toolbar bridge owns the turn lifecycle.
|