@seed-ship/mcp-ui-solid 2.7.0 → 2.8.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 +61 -10
- package/dist/components/ScratchpadPanel.cjs +339 -0
- package/dist/components/ScratchpadPanel.cjs.map +1 -0
- package/dist/components/ScratchpadPanel.d.ts +22 -0
- package/dist/components/ScratchpadPanel.d.ts.map +1 -0
- package/dist/components/ScratchpadPanel.js +339 -0
- package/dist/components/ScratchpadPanel.js.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/types/chat-bus.d.ts +58 -0
- package/dist/types/chat-bus.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/ScratchpadPanel.tsx +298 -0
- package/src/index.ts +5 -0
- package/src/types/chat-bus.ts +49 -0
- package/tsconfig.tsbuildinfo +1 -1
package/README.md
CHANGED
|
@@ -5,16 +5,15 @@ SolidJS components + chat toolkit for MCP-generated UI. Part of the [MCP UI ecos
|
|
|
5
5
|
[](https://www.npmjs.com/package/@seed-ship/mcp-ui-solid)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
|
-
## What's New in v2.
|
|
9
|
-
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **Chat Bus** (`@experimental`) - Bidirectional event/command bus for agent interactions (
|
|
15
|
-
- **ChatPrompt** (`@experimental`) - Structured interactions above chat input (choice, confirm, form)
|
|
8
|
+
## What's New in v2.8.0
|
|
9
|
+
|
|
10
|
+
- **ScratchpadPanel** (`@experimental`) - HITL/AITL shared workspace: agent fills sections, human edits filters and validates. Sections: data, filter (chips), preview (live stats), message, action, steps
|
|
11
|
+
- **Dependent fields** (`dependsOn`) - Child field fetches options from API when parent changes (e.g. department → commune)
|
|
12
|
+
- **Live preview** - Form shows real-time stats as user fills fields (debounced POST to preview endpoint)
|
|
13
|
+
- **Multi-select + Autocomplete** - Dropdown checkboxes with chips, API fetch for large datasets (35K+ communes)
|
|
14
|
+
- **Chat Bus** (`@experimental`) - Bidirectional event/command bus for agent interactions (16 events, 10 commands)
|
|
15
|
+
- **ChatPrompt** (`@experimental`) - Structured interactions above chat input (choice, confirm, form, dismissLabel)
|
|
16
16
|
- **19 component renderers** - chart, table, metric, text, code, map, form, modal, image-gallery, video, iframe, image, link, action, action-group, grid, carousel, artifact, footer
|
|
17
|
-
- **Tiered iframe sandbox** - Trusted domains get `allow-same-origin`; untrusted get restrictive sandbox
|
|
18
17
|
|
|
19
18
|
## Installation
|
|
20
19
|
|
|
@@ -283,6 +282,57 @@ Three subtypes for common agent interaction patterns:
|
|
|
283
282
|
// → response.value = { commune: "34172" }
|
|
284
283
|
```
|
|
285
284
|
|
|
285
|
+
## ScratchpadPanel — HITL/AITL Shared Workspace (`@experimental`)
|
|
286
|
+
|
|
287
|
+
A shared workspace where agent and human collaborate in real-time. The agent fills sections (data, filters, preview), the human can edit filters and validate. Works for both HITL (human supervises agent) and AITL (agent supervises human/other agent).
|
|
288
|
+
|
|
289
|
+
```tsx
|
|
290
|
+
import { ScratchpadPanel } from '@seed-ship/mcp-ui-solid'
|
|
291
|
+
import type { ScratchpadState } from '@seed-ship/mcp-ui-solid'
|
|
292
|
+
|
|
293
|
+
function WorkspaceView() {
|
|
294
|
+
const [state, setState] = createSignal<ScratchpadState>(/* from SSE */)
|
|
295
|
+
|
|
296
|
+
// Listen for scratchpad SSE events
|
|
297
|
+
bus.events.on('onScratchpad', (event) => {
|
|
298
|
+
if (event.scratchpad.action === 'create') setState(event.scratchpad)
|
|
299
|
+
if (event.scratchpad.action === 'update') setState(prev => ({ ...prev, ...event.scratchpad }))
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
return (
|
|
303
|
+
<ScratchpadPanel
|
|
304
|
+
state={state()}
|
|
305
|
+
onFilterChange={(filters) => {
|
|
306
|
+
// Send updated filters to agent
|
|
307
|
+
fetch('/api/chat-stream/scratchpad-update', {
|
|
308
|
+
method: 'POST',
|
|
309
|
+
body: JSON.stringify({ id: state().id, filters })
|
|
310
|
+
})
|
|
311
|
+
}}
|
|
312
|
+
onAction={(action) => {
|
|
313
|
+
if (action === 'validate') bus.commands.exec('sendPrompt', 'Valider et synthetiser')
|
|
314
|
+
}}
|
|
315
|
+
/>
|
|
316
|
+
)
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Section Types
|
|
321
|
+
|
|
322
|
+
| Type | Renders | Editable | Use case |
|
|
323
|
+
|------|---------|:--------:|----------|
|
|
324
|
+
| `data` | Key-value pairs | No | Dataset info, column list |
|
|
325
|
+
| `filter` | Editable chips + remove | Yes | Active filters (dept, year) |
|
|
326
|
+
| `preview` | Count badge + summary + mini-table | No | Live result count |
|
|
327
|
+
| `message` | Agent bubble (info/question/warning) | No | Agent explanations |
|
|
328
|
+
| `action` | Buttons (primary/danger/default) | No | Validate, refine, change |
|
|
329
|
+
| `steps` | Stepper (done/active/pending) | No | Pipeline progress |
|
|
330
|
+
| `form` | Embedded form | Yes | Configuration |
|
|
331
|
+
|
|
332
|
+
### Status Badges
|
|
333
|
+
|
|
334
|
+
`loading` → `ready` → `waiting_human` (pulsing) → `processing` → `complete`
|
|
335
|
+
|
|
286
336
|
## Component Renderers (19 types)
|
|
287
337
|
|
|
288
338
|
| Type | Renderer | Features |
|
|
@@ -359,7 +409,7 @@ export default defineConfig({
|
|
|
359
409
|
// Components
|
|
360
410
|
import {
|
|
361
411
|
UIResourceRenderer, StreamingUIRenderer, GenerativeUIErrorBoundary,
|
|
362
|
-
ExpandableWrapper, ComponentToolbar, ChatPrompt,
|
|
412
|
+
ExpandableWrapper, ComponentToolbar, ChatPrompt, ScratchpadPanel,
|
|
363
413
|
} from '@seed-ship/mcp-ui-solid'
|
|
364
414
|
|
|
365
415
|
// Chat Bus
|
|
@@ -380,6 +430,7 @@ import type {
|
|
|
380
430
|
ChatBus, ChatEvents, ChatCommands,
|
|
381
431
|
ChatPromptConfig, ChatPromptResponse,
|
|
382
432
|
AgentContext, BriefingEvent,
|
|
433
|
+
ScratchpadState, ScratchpadSection, ScratchpadEvent,
|
|
383
434
|
UIComponent, UILayout, ComponentType,
|
|
384
435
|
} from '@seed-ship/mcp-ui-solid'
|
|
385
436
|
```
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const web = require("solid-js/web");
|
|
4
|
+
const solidJs = require("solid-js");
|
|
5
|
+
var _tmpl$ = /* @__PURE__ */ web.template(`<div class="px-4 py-3 border-t border-gray-100 dark:border-gray-700 space-y-2">`), _tmpl$2 = /* @__PURE__ */ web.template(`<div class="mt-2 overflow-x-auto"><table class="min-w-full text-xs"><thead><tr></tr></thead><tbody>`), _tmpl$3 = /* @__PURE__ */ web.template(`<div class="px-4 py-3 border-t border-gray-100 dark:border-gray-700"><div class="flex items-center gap-2 mb-2"><span class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">Preview</span><span class="px-1.5 py-0.5 text-xs font-bold bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 rounded"></span></div><p class="text-sm text-gray-700 dark:text-gray-300"></p><!$><!/>`), _tmpl$4 = /* @__PURE__ */ web.template(`<div class="w-full bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 shadow-lg overflow-visible"><div class="flex items-center justify-between px-4 py-3 border-b border-gray-100 dark:border-gray-700"><div class="flex items-center gap-2"><span class=text-base>📝</span><h3 class="text-sm font-semibold text-gray-900 dark:text-white"></h3></div><span></span></div><div class="divide-y divide-gray-100 dark:divide-gray-700"></div><!$><!/><!$><!/>`), _tmpl$5 = /* @__PURE__ */ web.template(`<div><span class="flex-shrink-0 mt-0.5"></span><p>`), _tmpl$6 = /* @__PURE__ */ web.template(`<th class="px-2 py-1 text-left font-medium text-gray-500 dark:text-gray-400">`), _tmpl$7 = /* @__PURE__ */ web.template(`<tr class="border-t border-gray-100 dark:border-gray-700">`), _tmpl$8 = /* @__PURE__ */ web.template(`<td class="px-2 py-1 text-gray-700 dark:text-gray-300">`), _tmpl$9 = /* @__PURE__ */ web.template(`<span class="text-[10px] text-blue-500 dark:text-blue-400">(editable)`), _tmpl$0 = /* @__PURE__ */ web.template(`<p class="text-sm text-gray-700 dark:text-gray-300">`), _tmpl$1 = /* @__PURE__ */ web.template(`<pre class="text-xs text-gray-500 dark:text-gray-400 overflow-auto">`), _tmpl$10 = /* @__PURE__ */ web.template(`<div class="px-4 py-3"><div class="flex items-center gap-2 mb-2"><h4 class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide"></h4><!$><!/></div><!$><!/>`), _tmpl$11 = /* @__PURE__ */ web.template(`<div class=space-y-1>`), _tmpl$12 = /* @__PURE__ */ web.template(`<div class="flex gap-2 text-sm"><span class="text-gray-500 dark:text-gray-400 font-mono text-xs min-w-[120px]"><!$><!/>:</span><span class="text-gray-900 dark:text-white text-xs">`), _tmpl$13 = /* @__PURE__ */ web.template(`<div class="flex flex-wrap gap-1.5">`), _tmpl$14 = /* @__PURE__ */ web.template(`<span class="inline-flex items-center gap-1 px-2.5 py-1 text-xs font-medium bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 rounded-full"><span class="text-blue-500 dark:text-blue-400"><!$><!/>:</span><!$><!/><button type=button class="ml-0.5 hover:text-blue-900 dark:hover:text-blue-100">×`), _tmpl$15 = /* @__PURE__ */ web.template(`<div class="flex flex-wrap gap-2">`), _tmpl$16 = /* @__PURE__ */ web.template(`<button type=button>`), _tmpl$17 = /* @__PURE__ */ web.template(`<div class="flex items-center gap-1">`), _tmpl$18 = /* @__PURE__ */ web.template(`<div>`), _tmpl$19 = /* @__PURE__ */ web.template(`<div><!$><!/><!$><!/>`);
|
|
6
|
+
const STATUS_BADGES = {
|
|
7
|
+
loading: {
|
|
8
|
+
label: "Loading...",
|
|
9
|
+
class: "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400"
|
|
10
|
+
},
|
|
11
|
+
ready: {
|
|
12
|
+
label: "Ready",
|
|
13
|
+
class: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400"
|
|
14
|
+
},
|
|
15
|
+
waiting_human: {
|
|
16
|
+
label: "Your turn",
|
|
17
|
+
class: "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400 animate-pulse"
|
|
18
|
+
},
|
|
19
|
+
processing: {
|
|
20
|
+
label: "Processing...",
|
|
21
|
+
class: "bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400"
|
|
22
|
+
},
|
|
23
|
+
complete: {
|
|
24
|
+
label: "Complete",
|
|
25
|
+
class: "bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-400"
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const ScratchpadPanel = (props) => {
|
|
29
|
+
const badge = () => STATUS_BADGES[props.state.status] || STATUS_BADGES.loading;
|
|
30
|
+
return (() => {
|
|
31
|
+
var _el$ = web.getNextElement(_tmpl$4), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling, _el$6 = _el$3.nextSibling, _el$7 = _el$2.nextSibling, _el$19 = _el$7.nextSibling, [_el$20, _co$2] = web.getNextMarker(_el$19.nextSibling), _el$21 = _el$20.nextSibling, [_el$22, _co$3] = web.getNextMarker(_el$21.nextSibling);
|
|
32
|
+
web.insert(_el$5, () => props.state.title);
|
|
33
|
+
web.insert(_el$6, () => badge().label);
|
|
34
|
+
web.insert(_el$7, web.createComponent(solidJs.For, {
|
|
35
|
+
get each() {
|
|
36
|
+
return props.state.sections;
|
|
37
|
+
},
|
|
38
|
+
children: (section) => web.createComponent(SectionRenderer, {
|
|
39
|
+
section,
|
|
40
|
+
get filters() {
|
|
41
|
+
return props.state.filters;
|
|
42
|
+
},
|
|
43
|
+
get onFilterChange() {
|
|
44
|
+
return props.onFilterChange;
|
|
45
|
+
},
|
|
46
|
+
get onAction() {
|
|
47
|
+
return props.onAction;
|
|
48
|
+
},
|
|
49
|
+
get onSectionEdit() {
|
|
50
|
+
return props.onSectionEdit;
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
}));
|
|
54
|
+
web.insert(_el$, web.createComponent(solidJs.Show, {
|
|
55
|
+
get when() {
|
|
56
|
+
return props.state.agentMessages.length > 0;
|
|
57
|
+
},
|
|
58
|
+
get children() {
|
|
59
|
+
var _el$8 = web.getNextElement(_tmpl$);
|
|
60
|
+
web.insert(_el$8, web.createComponent(solidJs.For, {
|
|
61
|
+
get each() {
|
|
62
|
+
return props.state.agentMessages;
|
|
63
|
+
},
|
|
64
|
+
children: (msg) => (() => {
|
|
65
|
+
var _el$23 = web.getNextElement(_tmpl$5), _el$24 = _el$23.firstChild, _el$25 = _el$24.nextSibling;
|
|
66
|
+
web.insert(_el$24, (() => {
|
|
67
|
+
var _c$ = web.memo(() => msg.type === "warning");
|
|
68
|
+
return () => _c$() ? "⚠️" : msg.type === "question" ? "💬" : "ℹ️";
|
|
69
|
+
})());
|
|
70
|
+
web.insert(_el$25, () => msg.text);
|
|
71
|
+
web.effect(() => web.className(_el$23, `flex items-start gap-2 text-sm ${msg.type === "warning" ? "text-amber-600 dark:text-amber-400" : msg.type === "question" ? "text-blue-600 dark:text-blue-400" : "text-gray-600 dark:text-gray-400"}`));
|
|
72
|
+
return _el$23;
|
|
73
|
+
})()
|
|
74
|
+
}));
|
|
75
|
+
return _el$8;
|
|
76
|
+
}
|
|
77
|
+
}), _el$20, _co$2);
|
|
78
|
+
web.insert(_el$, web.createComponent(solidJs.Show, {
|
|
79
|
+
get when() {
|
|
80
|
+
return props.state.preview;
|
|
81
|
+
},
|
|
82
|
+
get children() {
|
|
83
|
+
var _el$9 = web.getNextElement(_tmpl$3), _el$0 = _el$9.firstChild, _el$1 = _el$0.firstChild, _el$10 = _el$1.nextSibling, _el$11 = _el$0.nextSibling, _el$17 = _el$11.nextSibling, [_el$18, _co$] = web.getNextMarker(_el$17.nextSibling);
|
|
84
|
+
web.insert(_el$10, () => props.state.preview.count.toLocaleString());
|
|
85
|
+
web.insert(_el$11, () => props.state.preview.summary);
|
|
86
|
+
web.insert(_el$9, web.createComponent(solidJs.Show, {
|
|
87
|
+
get when() {
|
|
88
|
+
return web.memo(() => !!props.state.preview.rows)() && props.state.preview.rows.length > 0;
|
|
89
|
+
},
|
|
90
|
+
get children() {
|
|
91
|
+
var _el$12 = web.getNextElement(_tmpl$2), _el$13 = _el$12.firstChild, _el$14 = _el$13.firstChild, _el$15 = _el$14.firstChild, _el$16 = _el$14.nextSibling;
|
|
92
|
+
web.insert(_el$15, web.createComponent(solidJs.For, {
|
|
93
|
+
get each() {
|
|
94
|
+
return Object.keys(props.state.preview.rows[0]);
|
|
95
|
+
},
|
|
96
|
+
children: (key) => (() => {
|
|
97
|
+
var _el$26 = web.getNextElement(_tmpl$6);
|
|
98
|
+
web.insert(_el$26, key);
|
|
99
|
+
return _el$26;
|
|
100
|
+
})()
|
|
101
|
+
}));
|
|
102
|
+
web.insert(_el$16, web.createComponent(solidJs.For, {
|
|
103
|
+
get each() {
|
|
104
|
+
return props.state.preview.rows.slice(0, 5);
|
|
105
|
+
},
|
|
106
|
+
children: (row) => (() => {
|
|
107
|
+
var _el$27 = web.getNextElement(_tmpl$7);
|
|
108
|
+
web.insert(_el$27, web.createComponent(solidJs.For, {
|
|
109
|
+
get each() {
|
|
110
|
+
return Object.values(row);
|
|
111
|
+
},
|
|
112
|
+
children: (val) => (() => {
|
|
113
|
+
var _el$28 = web.getNextElement(_tmpl$8);
|
|
114
|
+
web.insert(_el$28, () => String(val));
|
|
115
|
+
return _el$28;
|
|
116
|
+
})()
|
|
117
|
+
}));
|
|
118
|
+
return _el$27;
|
|
119
|
+
})()
|
|
120
|
+
}));
|
|
121
|
+
return _el$12;
|
|
122
|
+
}
|
|
123
|
+
}), _el$18, _co$);
|
|
124
|
+
return _el$9;
|
|
125
|
+
}
|
|
126
|
+
}), _el$22, _co$3);
|
|
127
|
+
web.effect(() => web.className(_el$6, `px-2 py-0.5 text-xs font-medium rounded-full ${badge().class}`));
|
|
128
|
+
return _el$;
|
|
129
|
+
})();
|
|
130
|
+
};
|
|
131
|
+
const SectionRenderer = (props) => {
|
|
132
|
+
return (() => {
|
|
133
|
+
var _el$29 = web.getNextElement(_tmpl$10), _el$30 = _el$29.firstChild, _el$31 = _el$30.firstChild, _el$33 = _el$31.nextSibling, [_el$34, _co$4] = web.getNextMarker(_el$33.nextSibling), _el$37 = _el$30.nextSibling, [_el$38, _co$5] = web.getNextMarker(_el$37.nextSibling);
|
|
134
|
+
web.insert(_el$31, () => props.section.title);
|
|
135
|
+
web.insert(_el$30, web.createComponent(solidJs.Show, {
|
|
136
|
+
get when() {
|
|
137
|
+
return props.section.editable;
|
|
138
|
+
},
|
|
139
|
+
get children() {
|
|
140
|
+
return web.getNextElement(_tmpl$9);
|
|
141
|
+
}
|
|
142
|
+
}), _el$34, _co$4);
|
|
143
|
+
web.insert(_el$29, web.createComponent(solidJs.Switch, {
|
|
144
|
+
get children() {
|
|
145
|
+
return [web.createComponent(solidJs.Match, {
|
|
146
|
+
get when() {
|
|
147
|
+
return props.section.type === "data";
|
|
148
|
+
},
|
|
149
|
+
get children() {
|
|
150
|
+
return web.createComponent(DataSection, {
|
|
151
|
+
get content() {
|
|
152
|
+
return props.section.content;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}), web.createComponent(solidJs.Match, {
|
|
157
|
+
get when() {
|
|
158
|
+
return props.section.type === "filter";
|
|
159
|
+
},
|
|
160
|
+
get children() {
|
|
161
|
+
return web.createComponent(FilterSection, {
|
|
162
|
+
get filters() {
|
|
163
|
+
return props.filters;
|
|
164
|
+
},
|
|
165
|
+
get onFilterChange() {
|
|
166
|
+
return props.onFilterChange;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}), web.createComponent(solidJs.Match, {
|
|
171
|
+
get when() {
|
|
172
|
+
return props.section.type === "message";
|
|
173
|
+
},
|
|
174
|
+
get children() {
|
|
175
|
+
var _el$35 = web.getNextElement(_tmpl$0);
|
|
176
|
+
web.insert(_el$35, () => String(props.section.content));
|
|
177
|
+
return _el$35;
|
|
178
|
+
}
|
|
179
|
+
}), web.createComponent(solidJs.Match, {
|
|
180
|
+
get when() {
|
|
181
|
+
return props.section.type === "action";
|
|
182
|
+
},
|
|
183
|
+
get children() {
|
|
184
|
+
return web.createComponent(ActionSection, {
|
|
185
|
+
get content() {
|
|
186
|
+
return props.section.content;
|
|
187
|
+
},
|
|
188
|
+
get onAction() {
|
|
189
|
+
return props.onAction;
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}), web.createComponent(solidJs.Match, {
|
|
194
|
+
get when() {
|
|
195
|
+
return props.section.type === "steps";
|
|
196
|
+
},
|
|
197
|
+
get children() {
|
|
198
|
+
return web.createComponent(StepsSection, {
|
|
199
|
+
get content() {
|
|
200
|
+
return props.section.content;
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}), web.createComponent(solidJs.Match, {
|
|
205
|
+
when: true,
|
|
206
|
+
get children() {
|
|
207
|
+
var _el$36 = web.getNextElement(_tmpl$1);
|
|
208
|
+
web.insert(_el$36, () => JSON.stringify(props.section.content, null, 2));
|
|
209
|
+
return _el$36;
|
|
210
|
+
}
|
|
211
|
+
})];
|
|
212
|
+
}
|
|
213
|
+
}), _el$38, _co$5);
|
|
214
|
+
return _el$29;
|
|
215
|
+
})();
|
|
216
|
+
};
|
|
217
|
+
const DataSection = (props) => {
|
|
218
|
+
const entries = () => {
|
|
219
|
+
if (typeof props.content !== "object" || !props.content) return [];
|
|
220
|
+
return Object.entries(props.content);
|
|
221
|
+
};
|
|
222
|
+
return (() => {
|
|
223
|
+
var _el$39 = web.getNextElement(_tmpl$11);
|
|
224
|
+
web.insert(_el$39, web.createComponent(solidJs.For, {
|
|
225
|
+
get each() {
|
|
226
|
+
return entries();
|
|
227
|
+
},
|
|
228
|
+
children: ([key, value]) => (() => {
|
|
229
|
+
var _el$40 = web.getNextElement(_tmpl$12), _el$41 = _el$40.firstChild, _el$43 = _el$41.firstChild, [_el$44, _co$6] = web.getNextMarker(_el$43.nextSibling);
|
|
230
|
+
_el$44.nextSibling;
|
|
231
|
+
var _el$45 = _el$41.nextSibling;
|
|
232
|
+
web.insert(_el$41, key, _el$44, _co$6);
|
|
233
|
+
web.insert(_el$45, (() => {
|
|
234
|
+
var _c$2 = web.memo(() => !!Array.isArray(value));
|
|
235
|
+
return () => _c$2() ? value.join(", ") : String(value);
|
|
236
|
+
})());
|
|
237
|
+
return _el$40;
|
|
238
|
+
})()
|
|
239
|
+
}));
|
|
240
|
+
return _el$39;
|
|
241
|
+
})();
|
|
242
|
+
};
|
|
243
|
+
const FilterSection = (props) => {
|
|
244
|
+
const removeFilter = (key) => {
|
|
245
|
+
var _a;
|
|
246
|
+
const next = {
|
|
247
|
+
...props.filters
|
|
248
|
+
};
|
|
249
|
+
delete next[key];
|
|
250
|
+
(_a = props.onFilterChange) == null ? void 0 : _a.call(props, next);
|
|
251
|
+
};
|
|
252
|
+
const entries = () => Object.entries(props.filters);
|
|
253
|
+
return (() => {
|
|
254
|
+
var _el$46 = web.getNextElement(_tmpl$13);
|
|
255
|
+
web.insert(_el$46, web.createComponent(solidJs.For, {
|
|
256
|
+
get each() {
|
|
257
|
+
return entries();
|
|
258
|
+
},
|
|
259
|
+
children: ([key, value]) => (() => {
|
|
260
|
+
var _el$47 = web.getNextElement(_tmpl$14), _el$48 = _el$47.firstChild, _el$50 = _el$48.firstChild, [_el$51, _co$7] = web.getNextMarker(_el$50.nextSibling);
|
|
261
|
+
_el$51.nextSibling;
|
|
262
|
+
var _el$53 = _el$48.nextSibling, [_el$54, _co$8] = web.getNextMarker(_el$53.nextSibling), _el$52 = _el$54.nextSibling;
|
|
263
|
+
web.insert(_el$48, key, _el$51, _co$7);
|
|
264
|
+
web.insert(_el$47, (() => {
|
|
265
|
+
var _c$3 = web.memo(() => !!Array.isArray(value));
|
|
266
|
+
return () => _c$3() ? value.join(", ") : String(value);
|
|
267
|
+
})(), _el$54, _co$8);
|
|
268
|
+
_el$52.$$click = () => removeFilter(key);
|
|
269
|
+
web.setAttribute(_el$52, "aria-label", `Remove filter ${key}`);
|
|
270
|
+
web.runHydrationEvents();
|
|
271
|
+
return _el$47;
|
|
272
|
+
})()
|
|
273
|
+
}));
|
|
274
|
+
return _el$46;
|
|
275
|
+
})();
|
|
276
|
+
};
|
|
277
|
+
const ActionSection = (props) => {
|
|
278
|
+
const actions = () => {
|
|
279
|
+
if (Array.isArray(props.content)) return props.content;
|
|
280
|
+
return [];
|
|
281
|
+
};
|
|
282
|
+
return (() => {
|
|
283
|
+
var _el$55 = web.getNextElement(_tmpl$15);
|
|
284
|
+
web.insert(_el$55, web.createComponent(solidJs.For, {
|
|
285
|
+
get each() {
|
|
286
|
+
return actions();
|
|
287
|
+
},
|
|
288
|
+
children: (item) => (() => {
|
|
289
|
+
var _el$56 = web.getNextElement(_tmpl$16);
|
|
290
|
+
_el$56.$$click = () => {
|
|
291
|
+
var _a;
|
|
292
|
+
return (_a = props.onAction) == null ? void 0 : _a.call(props, item.action);
|
|
293
|
+
};
|
|
294
|
+
web.insert(_el$56, () => item.label);
|
|
295
|
+
web.effect(() => web.className(_el$56, `px-3 py-1.5 text-sm font-medium rounded-lg transition-colors ${item.variant === "primary" ? "bg-blue-600 text-white hover:bg-blue-700" : item.variant === "danger" ? "bg-red-600 text-white hover:bg-red-700" : "border border-gray-200 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"}`));
|
|
296
|
+
web.runHydrationEvents();
|
|
297
|
+
return _el$56;
|
|
298
|
+
})()
|
|
299
|
+
}));
|
|
300
|
+
return _el$55;
|
|
301
|
+
})();
|
|
302
|
+
};
|
|
303
|
+
const StepsSection = (props) => {
|
|
304
|
+
const steps = () => {
|
|
305
|
+
if (Array.isArray(props.content)) return props.content;
|
|
306
|
+
return [];
|
|
307
|
+
};
|
|
308
|
+
return (() => {
|
|
309
|
+
var _el$57 = web.getNextElement(_tmpl$17);
|
|
310
|
+
web.insert(_el$57, web.createComponent(solidJs.For, {
|
|
311
|
+
get each() {
|
|
312
|
+
return steps();
|
|
313
|
+
},
|
|
314
|
+
children: (step, i) => [web.createComponent(solidJs.Show, {
|
|
315
|
+
get when() {
|
|
316
|
+
return i() > 0;
|
|
317
|
+
},
|
|
318
|
+
get children() {
|
|
319
|
+
var _el$58 = web.getNextElement(_tmpl$18);
|
|
320
|
+
web.effect(() => web.className(_el$58, `w-6 h-px ${step.status === "pending" ? "bg-gray-300 dark:bg-gray-600" : "bg-blue-400"}`));
|
|
321
|
+
return _el$58;
|
|
322
|
+
}
|
|
323
|
+
}), (() => {
|
|
324
|
+
var _el$59 = web.getNextElement(_tmpl$19), _el$60 = _el$59.firstChild, [_el$61, _co$9] = web.getNextMarker(_el$60.nextSibling), _el$62 = _el$61.nextSibling, [_el$63, _co$0] = web.getNextMarker(_el$62.nextSibling);
|
|
325
|
+
web.insert(_el$59, (() => {
|
|
326
|
+
var _c$4 = web.memo(() => step.status === "done");
|
|
327
|
+
return () => _c$4() ? "✓" : step.status === "active" ? "●" : "○";
|
|
328
|
+
})(), _el$61, _co$9);
|
|
329
|
+
web.insert(_el$59, () => step.label, _el$63, _co$0);
|
|
330
|
+
web.effect(() => web.className(_el$59, `flex items-center gap-1.5 px-2 py-1 rounded text-xs font-medium ${step.status === "done" ? "text-green-600 dark:text-green-400" : step.status === "active" ? "text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20" : "text-gray-400"}`));
|
|
331
|
+
return _el$59;
|
|
332
|
+
})()]
|
|
333
|
+
}));
|
|
334
|
+
return _el$57;
|
|
335
|
+
})();
|
|
336
|
+
};
|
|
337
|
+
web.delegateEvents(["click"]);
|
|
338
|
+
exports.ScratchpadPanel = ScratchpadPanel;
|
|
339
|
+
//# sourceMappingURL=ScratchpadPanel.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScratchpadPanel.cjs","sources":["../../src/components/ScratchpadPanel.tsx"],"sourcesContent":["/**\n * ScratchpadPanel — HITL shared workspace between agent and human\n * v2.7.0: Renders scratchpad sections, editable filters, preview, agent messages\n *\n * @experimental — This component may change without major bump until v2.5.0 stabilization.\n */\n\nimport { Component, Show, For, Switch, Match, createSignal } from 'solid-js'\nimport type { ScratchpadState, ScratchpadSection } from '../types/chat-bus'\n\nexport interface ScratchpadPanelProps {\n state: ScratchpadState\n /** Called when human modifies filters */\n onFilterChange?: (filters: Record<string, string | string[]>) => void\n /** Called when human clicks an action button */\n onAction?: (action: string, data?: unknown) => void\n /** Called when human edits a section */\n onSectionEdit?: (sectionId: string, content: unknown) => void\n}\n\nconst STATUS_BADGES: Record<ScratchpadState['status'], { label: string; class: string }> = {\n loading: { label: 'Loading...', class: 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400' },\n ready: { label: 'Ready', class: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400' },\n waiting_human: { label: 'Your turn', class: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400 animate-pulse' },\n processing: { label: 'Processing...', class: 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400' },\n complete: { label: 'Complete', class: 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-400' },\n}\n\n/**\n * @experimental\n */\nexport const ScratchpadPanel: Component<ScratchpadPanelProps> = (props) => {\n const badge = () => STATUS_BADGES[props.state.status] || STATUS_BADGES.loading\n\n return (\n <div class=\"w-full bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 shadow-lg overflow-visible\">\n {/* Header */}\n <div class=\"flex items-center justify-between px-4 py-3 border-b border-gray-100 dark:border-gray-700\">\n <div class=\"flex items-center gap-2\">\n <span class=\"text-base\">📝</span>\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white\">{props.state.title}</h3>\n </div>\n <span class={`px-2 py-0.5 text-xs font-medium rounded-full ${badge().class}`}>\n {badge().label}\n </span>\n </div>\n\n {/* Sections */}\n <div class=\"divide-y divide-gray-100 dark:divide-gray-700\">\n <For each={props.state.sections}>\n {(section) => (\n <SectionRenderer\n section={section}\n filters={props.state.filters}\n onFilterChange={props.onFilterChange}\n onAction={props.onAction}\n onSectionEdit={props.onSectionEdit}\n />\n )}\n </For>\n </div>\n\n {/* Agent messages */}\n <Show when={props.state.agentMessages.length > 0}>\n <div class=\"px-4 py-3 border-t border-gray-100 dark:border-gray-700 space-y-2\">\n <For each={props.state.agentMessages}>\n {(msg) => (\n <div class={`flex items-start gap-2 text-sm ${\n msg.type === 'warning' ? 'text-amber-600 dark:text-amber-400'\n : msg.type === 'question' ? 'text-blue-600 dark:text-blue-400'\n : 'text-gray-600 dark:text-gray-400'\n }`}>\n <span class=\"flex-shrink-0 mt-0.5\">\n {msg.type === 'warning' ? '⚠️' : msg.type === 'question' ? '💬' : 'ℹ️'}\n </span>\n <p>{msg.text}</p>\n </div>\n )}\n </For>\n </div>\n </Show>\n\n {/* Preview */}\n <Show when={props.state.preview}>\n <div class=\"px-4 py-3 border-t border-gray-100 dark:border-gray-700\">\n <div class=\"flex items-center gap-2 mb-2\">\n <span class=\"text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide\">Preview</span>\n <span class=\"px-1.5 py-0.5 text-xs font-bold bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 rounded\">\n {props.state.preview!.count.toLocaleString()}\n </span>\n </div>\n <p class=\"text-sm text-gray-700 dark:text-gray-300\">{props.state.preview!.summary}</p>\n <Show when={props.state.preview!.rows && props.state.preview!.rows!.length > 0}>\n <div class=\"mt-2 overflow-x-auto\">\n <table class=\"min-w-full text-xs\">\n <thead>\n <tr>\n <For each={Object.keys(props.state.preview!.rows![0])}>\n {(key) => <th class=\"px-2 py-1 text-left font-medium text-gray-500 dark:text-gray-400\">{key}</th>}\n </For>\n </tr>\n </thead>\n <tbody>\n <For each={props.state.preview!.rows!.slice(0, 5)}>\n {(row) => (\n <tr class=\"border-t border-gray-100 dark:border-gray-700\">\n <For each={Object.values(row)}>\n {(val) => <td class=\"px-2 py-1 text-gray-700 dark:text-gray-300\">{String(val)}</td>}\n </For>\n </tr>\n )}\n </For>\n </tbody>\n </table>\n </div>\n </Show>\n </div>\n </Show>\n </div>\n )\n}\n\n// ─── Section Renderer ────────────────────────────────────────\n\nconst SectionRenderer: Component<{\n section: ScratchpadSection\n filters: Record<string, string | string[]>\n onFilterChange?: (filters: Record<string, string | string[]>) => void\n onAction?: (action: string, data?: unknown) => void\n onSectionEdit?: (sectionId: string, content: unknown) => void\n}> = (props) => {\n return (\n <div class=\"px-4 py-3\">\n <div class=\"flex items-center gap-2 mb-2\">\n <h4 class=\"text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide\">{props.section.title}</h4>\n <Show when={props.section.editable}>\n <span class=\"text-[10px] text-blue-500 dark:text-blue-400\">(editable)</span>\n </Show>\n </div>\n\n <Switch>\n {/* Data section — key-value or compact table */}\n <Match when={props.section.type === 'data'}>\n <DataSection content={props.section.content} />\n </Match>\n\n {/* Filter section — editable chips */}\n <Match when={props.section.type === 'filter'}>\n <FilterSection\n filters={props.filters}\n onFilterChange={props.onFilterChange}\n />\n </Match>\n\n {/* Message section */}\n <Match when={props.section.type === 'message'}>\n <p class=\"text-sm text-gray-700 dark:text-gray-300\">{String(props.section.content)}</p>\n </Match>\n\n {/* Action section — buttons */}\n <Match when={props.section.type === 'action'}>\n <ActionSection content={props.section.content} onAction={props.onAction} />\n </Match>\n\n {/* Steps section */}\n <Match when={props.section.type === 'steps'}>\n <StepsSection content={props.section.content} />\n </Match>\n\n {/* Fallback */}\n <Match when={true}>\n <pre class=\"text-xs text-gray-500 dark:text-gray-400 overflow-auto\">\n {JSON.stringify(props.section.content, null, 2)}\n </pre>\n </Match>\n </Switch>\n </div>\n )\n}\n\n// ─── Sub-components ──────────────────────────────────────────\n\nconst DataSection: Component<{ content: unknown }> = (props) => {\n const entries = () => {\n if (typeof props.content !== 'object' || !props.content) return []\n return Object.entries(props.content as Record<string, unknown>)\n }\n\n return (\n <div class=\"space-y-1\">\n <For each={entries()}>\n {([key, value]) => (\n <div class=\"flex gap-2 text-sm\">\n <span class=\"text-gray-500 dark:text-gray-400 font-mono text-xs min-w-[120px]\">{key}:</span>\n <span class=\"text-gray-900 dark:text-white text-xs\">\n {Array.isArray(value) ? value.join(', ') : String(value)}\n </span>\n </div>\n )}\n </For>\n </div>\n )\n}\n\nconst FilterSection: Component<{\n filters: Record<string, string | string[]>\n onFilterChange?: (filters: Record<string, string | string[]>) => void\n}> = (props) => {\n const removeFilter = (key: string) => {\n const next = { ...props.filters }\n delete next[key]\n props.onFilterChange?.(next)\n }\n\n const entries = () => Object.entries(props.filters)\n\n return (\n <div class=\"flex flex-wrap gap-1.5\">\n <For each={entries()}>\n {([key, value]) => (\n <span class=\"inline-flex items-center gap-1 px-2.5 py-1 text-xs font-medium bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 rounded-full\">\n <span class=\"text-blue-500 dark:text-blue-400\">{key}:</span>\n {Array.isArray(value) ? value.join(', ') : String(value)}\n <button\n type=\"button\"\n onClick={() => removeFilter(key)}\n class=\"ml-0.5 hover:text-blue-900 dark:hover:text-blue-100\"\n aria-label={`Remove filter ${key}`}\n >\n ×\n </button>\n </span>\n )}\n </For>\n </div>\n )\n}\n\nconst ActionSection: Component<{\n content: unknown\n onAction?: (action: string, data?: unknown) => void\n}> = (props) => {\n const actions = () => {\n if (Array.isArray(props.content)) return props.content as Array<{ label: string; action: string; variant?: string }>\n return []\n }\n\n return (\n <div class=\"flex flex-wrap gap-2\">\n <For each={actions()}>\n {(item) => (\n <button\n type=\"button\"\n onClick={() => props.onAction?.(item.action)}\n class={`px-3 py-1.5 text-sm font-medium rounded-lg transition-colors ${\n item.variant === 'primary'\n ? 'bg-blue-600 text-white hover:bg-blue-700'\n : item.variant === 'danger'\n ? 'bg-red-600 text-white hover:bg-red-700'\n : 'border border-gray-200 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700'\n }`}\n >\n {item.label}\n </button>\n )}\n </For>\n </div>\n )\n}\n\nconst StepsSection: Component<{ content: unknown }> = (props) => {\n const steps = () => {\n if (Array.isArray(props.content)) return props.content as Array<{ label: string; status: 'done' | 'active' | 'pending' }>\n return []\n }\n\n return (\n <div class=\"flex items-center gap-1\">\n <For each={steps()}>\n {(step, i) => (\n <>\n <Show when={i() > 0}>\n <div class={`w-6 h-px ${step.status === 'pending' ? 'bg-gray-300 dark:bg-gray-600' : 'bg-blue-400'}`} />\n </Show>\n <div class={`flex items-center gap-1.5 px-2 py-1 rounded text-xs font-medium ${\n step.status === 'done' ? 'text-green-600 dark:text-green-400'\n : step.status === 'active' ? 'text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20'\n : 'text-gray-400'\n }`}>\n {step.status === 'done' ? '✓' : step.status === 'active' ? '●' : '○'}\n {step.label}\n </div>\n </>\n )}\n </For>\n </div>\n )\n}\n"],"names":["STATUS_BADGES","loading","label","class","ready","waiting_human","processing","complete","ScratchpadPanel","props","badge","state","status","_el$","_$getNextElement","_tmpl$4","_el$2","firstChild","_el$3","_el$4","_el$5","nextSibling","_el$6","_el$7","_el$19","_el$20","_co$2","_$getNextMarker","_el$21","_el$22","_co$3","_$insert","title","_$createComponent","For","each","sections","children","section","SectionRenderer","filters","onFilterChange","onAction","onSectionEdit","Show","when","agentMessages","length","_el$8","_tmpl$","msg","_el$23","_tmpl$5","_el$24","_el$25","_c$","_$memo","type","text","_$effect","_$className","preview","_el$9","_tmpl$3","_el$0","_el$1","_el$10","_el$11","_el$17","_el$18","_co$","count","toLocaleString","summary","rows","_el$12","_tmpl$2","_el$13","_el$14","_el$15","_el$16","Object","keys","key","_el$26","_tmpl$6","slice","row","_el$27","_tmpl$7","values","val","_el$28","_tmpl$8","String","_el$29","_tmpl$10","_el$30","_el$31","_el$33","_el$34","_co$4","_el$37","_el$38","_co$5","editable","_tmpl$9","Switch","Match","DataSection","content","FilterSection","_el$35","_tmpl$0","ActionSection","StepsSection","_el$36","_tmpl$1","JSON","stringify","entries","_el$39","_tmpl$11","value","_el$40","_tmpl$12","_el$41","_el$43","_el$44","_co$6","_el$45","_c$2","Array","isArray","join","removeFilter","next","_el$46","_tmpl$13","_el$47","_tmpl$14","_el$48","_el$50","_el$51","_co$7","_el$53","_el$54","_co$8","_el$52","_c$3","$$click","_$setAttribute","_$runHydrationEvents","actions","_el$55","_tmpl$15","item","_el$56","_tmpl$16","action","variant","steps","_el$57","_tmpl$17","step","i","_el$58","_tmpl$18","_el$59","_tmpl$19","_el$60","_el$61","_co$9","_el$62","_el$63","_co$0","_c$4","_$delegateEvents"],"mappings":";;;;;AAoBA,MAAMA,gBAAqF;AAAA,EACzFC,SAAS;AAAA,IAAEC,OAAO;AAAA,IAAcC,OAAO;AAAA,EAAA;AAAA,EACvCC,OAAO;AAAA,IAAEF,OAAO;AAAA,IAASC,OAAO;AAAA,EAAA;AAAA,EAChCE,eAAe;AAAA,IAAEH,OAAO;AAAA,IAAaC,OAAO;AAAA,EAAA;AAAA,EAC5CG,YAAY;AAAA,IAAEJ,OAAO;AAAA,IAAiBC,OAAO;AAAA,EAAA;AAAA,EAC7CI,UAAU;AAAA,IAAEL,OAAO;AAAA,IAAYC,OAAO;AAAA,EAAA;AACxC;AAKO,MAAMK,kBAAoDC,CAAAA,UAAU;AACzE,QAAMC,QAAQA,MAAMV,cAAcS,MAAME,MAAMC,MAAM,KAAKZ,cAAcC;AAEvE,UAAA,MAAA;AAAA,QAAAY,OAAAC,IAAAA,eAAAC,OAAA,GAAAC,QAAAH,KAAAI,YAAAC,QAAAF,MAAAC,YAAAE,QAAAD,MAAAD,YAAAG,QAAAD,MAAAE,aAAAC,QAAAJ,MAAAG,aAAAE,QAAAP,MAAAK,aAAAG,SAAAD,MAAAF,aAAA,CAAAI,QAAAC,KAAA,IAAAC,IAAAA,cAAAH,OAAAH,WAAA,GAAAO,SAAAH,OAAAJ,aAAA,CAAAQ,QAAAC,KAAA,IAAAH,IAAAA,cAAAC,OAAAP,WAAA;AAAAU,QAAAA,OAAAX,OAAA,MAMyEX,MAAME,MAAMqB,KAAK;AAAAD,QAAAA,OAAAT,OAAA,MAGjFZ,MAAAA,EAAQR,KAAK;AAAA6B,eAAAR,OAAAU,IAAAA,gBAMfC,aAAG;AAAA,MAAA,IAACC,OAAI;AAAA,eAAE1B,MAAME,MAAMyB;AAAAA,MAAQ;AAAA,MAAAC,UAC3BC,CAAAA,YAAOL,IAAAA,gBACNM,iBAAe;AAAA,QACdD;AAAAA,QAAgB,IAChBE,UAAO;AAAA,iBAAE/B,MAAME,MAAM6B;AAAAA,QAAO;AAAA,QAAA,IAC5BC,iBAAc;AAAA,iBAAEhC,MAAMgC;AAAAA,QAAc;AAAA,QAAA,IACpCC,WAAQ;AAAA,iBAAEjC,MAAMiC;AAAAA,QAAQ;AAAA,QAAA,IACxBC,gBAAa;AAAA,iBAAElC,MAAMkC;AAAAA,QAAa;AAAA,MAAA,CAAA;AAAA,IAAA,CAErC,CAAA;AAAAZ,eAAAlB,MAAAoB,IAAAA,gBAKJW,cAAI;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEpC,MAAME,MAAMmC,cAAcC,SAAS;AAAA,MAAC;AAAA,MAAA,IAAAV,WAAA;AAAA,YAAAW,QAAAlC,IAAAA,eAAAmC,MAAA;AAAAlB,mBAAAiB,OAAAf,IAAAA,gBAE3CC,aAAG;AAAA,UAAA,IAACC,OAAI;AAAA,mBAAE1B,MAAME,MAAMmC;AAAAA,UAAa;AAAA,UAAAT,UAChCa,UAAG,MAAA;AAAA,gBAAAC,SAAArC,mBAAAsC,OAAA,GAAAC,SAAAF,OAAAlC,YAAAqC,SAAAD,OAAAhC;AAAAU,gBAAAA,OAAAsB,SAAA,MAAA;AAAA,kBAAAE,MAAAC,IAAAA,KAAA,MAOEN,IAAIO,SAAS,SAAS;AAAA,qBAAA,MAAtBF,IAAAA,IAAyB,OAAOL,IAAIO,SAAS,aAAa,OAAO;AAAA,YAAI,IAAA;AAAA1B,gBAAAA,OAAAuB,QAAA,MAEpEJ,IAAIQ,IAAI;AAAAC,gBAAAA,OAAA,MAAAC,IAAAA,UAAAT,QARF,kCACVD,IAAIO,SAAS,YAAY,uCACvBP,IAAIO,SAAS,aAAa,qCAC1B,kCAAkC,EACpC,CAAA;AAAA,mBAAAN;AAAAA,UAAA,GAAA;AAAA,QAAA,CAMH,CAAA;AAAA,eAAAH;AAAAA,MAAA;AAAA,IAAA,CAAA,GAAAvB,QAAAC,KAAA;AAAAK,eAAAlB,MAAAoB,IAAAA,gBAMNW,cAAI;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEpC,MAAME,MAAMkD;AAAAA,MAAO;AAAA,MAAA,IAAAxB,WAAA;AAAA,YAAAyB,QAAAhD,IAAAA,eAAAiD,OAAA,GAAAC,QAAAF,MAAA7C,YAAAgD,QAAAD,MAAA/C,YAAAiD,SAAAD,MAAA5C,aAAA8C,SAAAH,MAAA3C,aAAA+C,SAAAD,OAAA9C,aAAA,CAAAgD,QAAAC,IAAA,IAAA3C,kBAAAyC,OAAA/C,WAAA;AAAAU,YAAAA,OAAAmC,QAAA,MAKtBzD,MAAME,MAAMkD,QAASU,MAAMC,gBAAgB;AAAAzC,YAAAA,OAAAoC,QAAA,MAGK1D,MAAME,MAAMkD,QAASY,OAAO;AAAA1C,mBAAA+B,OAAA7B,IAAAA,gBAChFW,cAAI;AAAA,UAAA,IAACC,OAAI;AAAA,mBAAEW,IAAAA,aAAA/C,MAAME,MAAMkD,QAASa,IAAI,EAAA,KAAIjE,MAAME,MAAMkD,QAASa,KAAM3B,SAAS;AAAA,UAAC;AAAA,UAAA,IAAAV,WAAA;AAAA,gBAAAsC,SAAA7D,IAAAA,eAAA8D,OAAA,GAAAC,SAAAF,OAAA1D,YAAA6D,SAAAD,OAAA5D,YAAA8D,SAAAD,OAAA7D,YAAA+D,SAAAF,OAAAzD;AAAAU,uBAAAgD,QAAA9C,IAAAA,gBAKnEC,aAAG;AAAA,cAAA,IAACC,OAAI;AAAA,uBAAE8C,OAAOC,KAAKzE,MAAME,MAAMkD,QAASa,KAAM,CAAC,CAAC;AAAA,cAAC;AAAA,cAAArC,UACjD8C,UAAG,MAAA;AAAA,oBAAAC,SAAAtE,IAAAA,eAAAuE,OAAA;AAAAtD,oBAAAA,OAAAqD,QAAmFD,GAAG;AAAA,uBAAAC;AAAAA,cAAA,GAAA;AAAA,YAAA,CAAM,CAAA;AAAArD,uBAAAiD,QAAA/C,IAAAA,gBAKpGC,aAAG;AAAA,cAAA,IAACC,OAAI;AAAA,uBAAE1B,MAAME,MAAMkD,QAASa,KAAMY,MAAM,GAAG,CAAC;AAAA,cAAC;AAAA,cAAAjD,UAC7CkD,UAAG,MAAA;AAAA,oBAAAC,SAAA1E,IAAAA,eAAA2E,OAAA;AAAA1D,2BAAAyD,QAAAvD,IAAAA,gBAEAC,aAAG;AAAA,kBAAA,IAACC,OAAI;AAAA,2BAAE8C,OAAOS,OAAOH,GAAG;AAAA,kBAAC;AAAA,kBAAAlD,UACzBsD,UAAG,MAAA;AAAA,wBAAAC,SAAA9E,IAAAA,eAAA+E,OAAA;AAAA9D,wBAAAA,OAAA6D,QAAA,MAA6DE,OAAOH,GAAG,CAAC;AAAA,2BAAAC;AAAAA,kBAAA,GAAA;AAAA,gBAAA,CAAM,CAAA;AAAA,uBAAAJ;AAAAA,cAAA,GAAA;AAAA,YAAA,CAGxF,CAAA;AAAA,mBAAAb;AAAAA,UAAA;AAAA,QAAA,CAAA,GAAAN,QAAAC,IAAA;AAAA,eAAAR;AAAAA,MAAA;AAAA,IAAA,CAAA,GAAAjC,QAAAC,KAAA;AAAA6B,eAAA,MAAAC,IAAAA,UAAAtC,OApEA,gDAAgDZ,QAAQP,KAAK,EAAE,CAAA;AAAA,WAAAU;AAAAA,EAAA,GAAA;AA8EpF;AAIA,MAAM0B,kBAMA9B,CAAAA,UAAU;AACd,UAAA,MAAA;AAAA,QAAAsF,SAAAjF,IAAAA,eAAAkF,QAAA,GAAAC,SAAAF,OAAA9E,YAAAiF,SAAAD,OAAAhF,YAAAkF,SAAAD,OAAA7E,aAAA,CAAA+E,QAAAC,KAAA,IAAA1E,IAAAA,cAAAwE,OAAA9E,WAAA,GAAAiF,SAAAL,OAAA5E,aAAA,CAAAkF,QAAAC,KAAA,IAAA7E,IAAAA,cAAA2E,OAAAjF,WAAA;AAAAU,QAAAA,OAAAmE,QAAA,MAGgGzF,MAAM6B,QAAQN,KAAK;AAAAD,eAAAkE,QAAAhE,IAAAA,gBAC5GW,cAAI;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEpC,MAAM6B,QAAQmE;AAAAA,MAAQ;AAAA,MAAA,IAAApE,WAAA;AAAA,eAAAvB,IAAAA,eAAA4F,OAAA;AAAA,MAAA;AAAA,IAAA,CAAA,GAAAN,QAAAC,KAAA;AAAAtE,eAAAgE,QAAA9D,IAAAA,gBAKnC0E,gBAAM;AAAA,MAAA,IAAAtE,WAAA;AAAA,eAAA,CAAAJ,IAAAA,gBAEJ2E,eAAK;AAAA,UAAA,IAAC/D,OAAI;AAAA,mBAAEpC,MAAM6B,QAAQmB,SAAS;AAAA,UAAM;AAAA,UAAA,IAAApB,WAAA;AAAA,mBAAAJ,IAAAA,gBACvC4E,aAAW;AAAA,cAAA,IAACC,UAAO;AAAA,uBAAErG,MAAM6B,QAAQwE;AAAAA,cAAO;AAAA,YAAA,CAAA;AAAA,UAAA;AAAA,QAAA,CAAA,GAAA7E,IAAAA,gBAI5C2E,eAAK;AAAA,UAAA,IAAC/D,OAAI;AAAA,mBAAEpC,MAAM6B,QAAQmB,SAAS;AAAA,UAAQ;AAAA,UAAA,IAAApB,WAAA;AAAA,mBAAAJ,IAAAA,gBACzC8E,eAAa;AAAA,cAAA,IACZvE,UAAO;AAAA,uBAAE/B,MAAM+B;AAAAA,cAAO;AAAA,cAAA,IACtBC,iBAAc;AAAA,uBAAEhC,MAAMgC;AAAAA,cAAc;AAAA,YAAA,CAAA;AAAA,UAAA;AAAA,QAAA,CAAA,GAAAR,IAAAA,gBAKvC2E,eAAK;AAAA,UAAA,IAAC/D,OAAI;AAAA,mBAAEpC,MAAM6B,QAAQmB,SAAS;AAAA,UAAS;AAAA,UAAA,IAAApB,WAAA;AAAA,gBAAA2E,SAAAlG,IAAAA,eAAAmG,OAAA;AAAAlF,gBAAAA,OAAAiF,QAAA,MACUlB,OAAOrF,MAAM6B,QAAQwE,OAAO,CAAC;AAAA,mBAAAE;AAAAA,UAAA;AAAA,QAAA,CAAA,GAAA/E,IAAAA,gBAInF2E,eAAK;AAAA,UAAA,IAAC/D,OAAI;AAAA,mBAAEpC,MAAM6B,QAAQmB,SAAS;AAAA,UAAQ;AAAA,UAAA,IAAApB,WAAA;AAAA,mBAAAJ,IAAAA,gBACzCiF,eAAa;AAAA,cAAA,IAACJ,UAAO;AAAA,uBAAErG,MAAM6B,QAAQwE;AAAAA,cAAO;AAAA,cAAA,IAAEpE,WAAQ;AAAA,uBAAEjC,MAAMiC;AAAAA,cAAQ;AAAA,YAAA,CAAA;AAAA,UAAA;AAAA,QAAA,CAAA,GAAAT,IAAAA,gBAIxE2E,eAAK;AAAA,UAAA,IAAC/D,OAAI;AAAA,mBAAEpC,MAAM6B,QAAQmB,SAAS;AAAA,UAAO;AAAA,UAAA,IAAApB,WAAA;AAAA,mBAAAJ,IAAAA,gBACxCkF,cAAY;AAAA,cAAA,IAACL,UAAO;AAAA,uBAAErG,MAAM6B,QAAQwE;AAAAA,cAAO;AAAA,YAAA,CAAA;AAAA,UAAA;AAAA,QAAA,CAAA,GAAA7E,IAAAA,gBAI7C2E,eAAK;AAAA,UAAC/D,MAAM;AAAA,UAAI,IAAAR,WAAA;AAAA,gBAAA+E,SAAAtG,IAAAA,eAAAuG,OAAA;AAAAtF,uBAAAqF,QAAA,MAEZE,KAAKC,UAAU9G,MAAM6B,QAAQwE,SAAS,MAAM,CAAC,CAAC;AAAA,mBAAAM;AAAAA,UAAA;AAAA,QAAA,CAAA,CAAA;AAAA,MAAA;AAAA,IAAA,CAAA,GAAAb,QAAAC,KAAA;AAAA,WAAAT;AAAAA,EAAA,GAAA;AAM3D;AAIA,MAAMc,cAAgDpG,CAAAA,UAAU;AAC9D,QAAM+G,UAAUA,MAAM;AACpB,QAAI,OAAO/G,MAAMqG,YAAY,YAAY,CAACrG,MAAMqG,gBAAgB,CAAA;AAChE,WAAO7B,OAAOuC,QAAQ/G,MAAMqG,OAAkC;AAAA,EAChE;AAEA,UAAA,MAAA;AAAA,QAAAW,SAAA3G,IAAAA,eAAA4G,QAAA;AAAA3F,eAAA0F,QAAAxF,IAAAA,gBAEKC,aAAG;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEqF,QAAAA;AAAAA,MAAS;AAAA,MAAAnF,UACjBA,CAAC,CAAC8C,KAAKwC,KAAK,OAAC,MAAA;AAAA,YAAAC,SAAA9G,IAAAA,eAAA+G,QAAA,GAAAC,SAAAF,OAAA3G,YAAA8G,SAAAD,OAAA7G,YAAA,CAAA+G,QAAAC,KAAA,IAAAtG,IAAAA,cAAAoG,OAAA1G,WAAA;AAAA2G,eAAA3G;AAAAA,YAAA6G,SAAAJ,OAAAzG;AAAAU,YAAAA,OAAA+F,QAEsE3C,KAAG6C,QAAAC,KAAA;AAAAlG,YAAAA,OAAAmG,SAAA,MAAA;AAAA,cAAAC,OAAA3E,IAAAA,KAAA,MAAA,CAAA,CAEhF4E,MAAMC,QAAQV,KAAK,CAAC;AAAA,iBAAA,MAApBQ,SAAuBR,MAAMW,KAAK,IAAI,IAAIxC,OAAO6B,KAAK;AAAA,QAAC,IAAA;AAAA,eAAAC;AAAAA,MAAA,GAAA;AAAA,IAAA,CAG7D,CAAA;AAAA,WAAAH;AAAAA,EAAA,GAAA;AAIT;AAEA,MAAMV,gBAGAtG,CAAAA,UAAU;AACd,QAAM8H,eAAeA,CAACpD,QAAgB;;AACpC,UAAMqD,OAAO;AAAA,MAAE,GAAG/H,MAAM+B;AAAAA,IAAAA;AACxB,WAAOgG,KAAKrD,GAAG;AACf1E,gBAAMgC,mBAANhC,+BAAuB+H;AAAAA,EACzB;AAEA,QAAMhB,UAAUA,MAAMvC,OAAOuC,QAAQ/G,MAAM+B,OAAO;AAElD,UAAA,MAAA;AAAA,QAAAiG,SAAA3H,IAAAA,eAAA4H,QAAA;AAAA3G,eAAA0G,QAAAxG,IAAAA,gBAEKC,aAAG;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEqF,QAAAA;AAAAA,MAAS;AAAA,MAAAnF,UACjBA,CAAC,CAAC8C,KAAKwC,KAAK,OAAC,MAAA;AAAA,YAAAgB,SAAA7H,IAAAA,eAAA8H,QAAA,GAAAC,SAAAF,OAAA1H,YAAA6H,SAAAD,OAAA5H,YAAA,CAAA8H,QAAAC,KAAA,IAAArH,IAAAA,cAAAmH,OAAAzH,WAAA;AAAA0H,eAAA1H;AAAAA,YAAA4H,SAAAJ,OAAAxH,aAAA,CAAA6H,QAAAC,KAAA,IAAAxH,IAAAA,cAAAsH,OAAA5H,WAAA,GAAA+H,SAAAF,OAAA7H;AAAAU,YAAAA,OAAA8G,QAEsC1D,KAAG4D,QAAAC,KAAA;AAAAjH,YAAAA,OAAA4G,SAAA,MAAA;AAAA,cAAAU,OAAA7F,IAAAA,KAAA,MAAA,CAAA,CAClD4E,MAAMC,QAAQV,KAAK,CAAC;AAAA,iBAAA,MAApB0B,SAAuB1B,MAAMW,KAAK,IAAI,IAAIxC,OAAO6B,KAAK;AAAA,QAAC,GAAA,GAAAuB,QAAAC,KAAA;AAAAC,eAAAE,UAG7C,MAAMf,aAAapD,GAAG;AAACoE,YAAAA,aAAAH,QAAA,cAEpB,iBAAiBjE,GAAG,EAAE;AAAAqE,+BAAAA;AAAA,eAAAb;AAAAA,MAAA,GAAA;AAAA,IAAA,CAKvC,CAAA;AAAA,WAAAF;AAAAA,EAAA,GAAA;AAIT;AAEA,MAAMvB,gBAGAzG,CAAAA,UAAU;AACd,QAAMgJ,UAAUA,MAAM;AACpB,QAAIrB,MAAMC,QAAQ5H,MAAMqG,OAAO,UAAUrG,MAAMqG;AAC/C,WAAO,CAAA;AAAA,EACT;AAEA,UAAA,MAAA;AAAA,QAAA4C,SAAA5I,IAAAA,eAAA6I,QAAA;AAAA5H,eAAA2H,QAAAzH,IAAAA,gBAEKC,aAAG;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEsH,QAAAA;AAAAA,MAAS;AAAA,MAAApH,UAChBuH,WAAI,MAAA;AAAA,YAAAC,SAAA/I,IAAAA,eAAAgJ,QAAA;AAAAD,eAAAP,UAGO,MAAA;;AAAM7I,6BAAMiC,aAANjC,+BAAiBmJ,KAAKG;AAAAA;AAAOhI,YAAAA,OAAA8H,QAAA,MAS3CD,KAAK1J,KAAK;AAAAyD,YAAAA,OAAA,MAAAC,IAAAA,UAAAiG,QARJ,gEACLD,KAAKI,YAAY,YACb,6CACAJ,KAAKI,YAAY,WACjB,2CACA,uHAAuH,EAC3H,CAAA;AAAAR,+BAAAA;AAAA,eAAAK;AAAAA,MAAA,GAAA;AAAA,IAAA,CAIL,CAAA;AAAA,WAAAH;AAAAA,EAAA,GAAA;AAIT;AAEA,MAAMvC,eAAiD1G,CAAAA,UAAU;AAC/D,QAAMwJ,QAAQA,MAAM;AAClB,QAAI7B,MAAMC,QAAQ5H,MAAMqG,OAAO,UAAUrG,MAAMqG;AAC/C,WAAO,CAAA;AAAA,EACT;AAEA,UAAA,MAAA;AAAA,QAAAoD,SAAApJ,IAAAA,eAAAqJ,QAAA;AAAApI,eAAAmI,QAAAjI,IAAAA,gBAEKC,aAAG;AAAA,MAAA,IAACC,OAAI;AAAA,eAAE8H,MAAAA;AAAAA,MAAO;AAAA,MAAA5H,UACfA,CAAC+H,MAAMC,MAAC,CAAApI,IAAAA,gBAEJW,QAAAA,MAAI;AAAA,QAAA,IAACC,OAAI;AAAA,iBAAEwH,MAAM;AAAA,QAAC;AAAA,QAAA,IAAAhI,WAAA;AAAA,cAAAiI,SAAAxJ,IAAAA,eAAAyJ,QAAA;AAAA5G,cAAAA,OAAA,MAAAC,IAAAA,UAAA0G,QACL,YAAYF,KAAKxJ,WAAW,YAAY,iCAAiC,aAAa,EAAE,CAAA;AAAA,iBAAA0J;AAAAA,QAAA;AAAA,MAAA,CAAA,IAAA,MAAA;AAAA,YAAAE,SAAA1J,IAAAA,eAAA2J,QAAA,GAAAC,SAAAF,OAAAvJ,YAAA,CAAA0J,QAAAC,KAAA,IAAAjJ,IAAAA,cAAA+I,OAAArJ,WAAA,GAAAwJ,SAAAF,OAAAtJ,aAAA,CAAAyJ,QAAAC,KAAA,IAAApJ,IAAAA,cAAAkJ,OAAAxJ,WAAA;AAAAU,YAAAA,OAAAyI,SAAA,MAAA;AAAA,cAAAQ,OAAAxH,IAAAA,KAAA,MAOnG4G,KAAKxJ,WAAW,MAAM;AAAA,iBAAA,MAAtBoK,KAAAA,IAAyB,MAAMZ,KAAKxJ,WAAW,WAAW,MAAM;AAAA,QAAG,GAAA,GAAA+J,QAAAC,KAAA;AAAA7I,YAAAA,OAAAyI,QAAA,MACnEJ,KAAKlK,OAAK4K,QAAAC,KAAA;AAAApH,YAAAA,OAAA,MAAAC,IAAAA,UAAA4G,QAND,mEACVJ,KAAKxJ,WAAW,SAAS,uCACvBwJ,KAAKxJ,WAAW,WAAW,oEAC3B,eAAe,EACjB,CAAA;AAAA,eAAA4J;AAAAA,MAAA,IAAA;AAAA,IAAA,CAKL,CAAA;AAAA,WAAAN;AAAAA,EAAA,GAAA;AAIT;AAACe,IAAAA,eAAA,CAAA,OAAA,CAAA;;"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ScratchpadPanel — HITL shared workspace between agent and human
|
|
3
|
+
* v2.7.0: Renders scratchpad sections, editable filters, preview, agent messages
|
|
4
|
+
*
|
|
5
|
+
* @experimental — This component may change without major bump until v2.5.0 stabilization.
|
|
6
|
+
*/
|
|
7
|
+
import { Component } from 'solid-js';
|
|
8
|
+
import type { ScratchpadState } from '../types/chat-bus';
|
|
9
|
+
export interface ScratchpadPanelProps {
|
|
10
|
+
state: ScratchpadState;
|
|
11
|
+
/** Called when human modifies filters */
|
|
12
|
+
onFilterChange?: (filters: Record<string, string | string[]>) => void;
|
|
13
|
+
/** Called when human clicks an action button */
|
|
14
|
+
onAction?: (action: string, data?: unknown) => void;
|
|
15
|
+
/** Called when human edits a section */
|
|
16
|
+
onSectionEdit?: (sectionId: string, content: unknown) => void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* @experimental
|
|
20
|
+
*/
|
|
21
|
+
export declare const ScratchpadPanel: Component<ScratchpadPanelProps>;
|
|
22
|
+
//# sourceMappingURL=ScratchpadPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScratchpadPanel.d.ts","sourceRoot":"","sources":["../../src/components/ScratchpadPanel.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAA0C,MAAM,UAAU,CAAA;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,mBAAmB,CAAA;AAE3E,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,eAAe,CAAA;IACtB,yCAAyC;IACzC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,KAAK,IAAI,CAAA;IACrE,gDAAgD;IAChD,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACnD,wCAAwC;IACxC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CAC9D;AAUD;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,CAAC,oBAAoB,CAyF3D,CAAA"}
|