camox 0.65.1 → 0.66.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/dist/features/canvas/CamoxCanvas.js +195 -173
- package/dist/features/canvas/canvasFrameCapture.js +5 -12
- package/dist/features/canvas/canvasFrameDocument.js +90 -29
- package/dist/features/canvas/canvasItems.js +22 -6
- package/dist/features/canvas/sidebar/ContentSidebar.js +19 -21
- package/dist/features/canvas/sidebar/LayoutPageOverview.js +22 -49
- package/dist/features/canvas/sidebar/LayoutPageSeo.js +73 -76
- package/dist/features/canvas/sidebar/PageInspector.js +61 -50
- package/dist/features/canvas/sidebar/PageInspectorSkeleton.js +4 -4
- package/dist/features/canvas/useCanvasCamera.js +22 -5
- package/dist/features/preview/components/PageInfo.js +103 -100
- package/dist/features/runtime/RuntimeChrome.js +66 -40
- package/dist/features/studio/components/AgentSidebar.js +3 -3
- package/dist/features/studio/components/ChatWidget.js +34 -29
- package/dist/features/studio/components/DraftsControl.js +172 -159
- package/dist/features/studio/components/Patrol.js +423 -418
- package/dist/features/studio/components/ReviewDraftSheet.js +227 -188
- package/dist/features/studio/components/ThreadComposer.js +183 -121
- package/dist/features/studio/components/ThreadMessages.js +19 -11
- package/dist/features/studio/components/UnnamedDraftBar.js +349 -0
- package/dist/features/studio/patrollerBio.js +40 -0
- package/dist/features/studio/studioStore.js +13 -0
- package/dist/features/studio/workingSentence.js +2 -7
- package/dist/lib/revisions.js +25 -3
- package/dist/lib/use-thread.js +1 -1
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +4 -4
- package/dist/features/canvas/sidebar/DerivedPageInspector.js +0 -49
- package/dist/features/canvas/sidebar/SingletonPageInspector.js +0 -39
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { c } from "react/compiler-runtime";
|
|
2
|
-
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
import { useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
import { ArrowUp, Square, SquareDashedMousePointer, X } from "lucide-react";
|
|
5
5
|
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupTextarea } from "@camox/ui/input-group";
|
|
@@ -9,68 +9,116 @@ import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupTextarea } fro
|
|
|
9
9
|
* Where an editor writes to the agent: Enter sends, Shift+Enter adds a line. While a run is
|
|
10
10
|
* going, sending steers it, and a Stop button sits beside Send. Over the message, what the
|
|
11
11
|
* editor has selected, which their messages carry to the agent until they clear it. A message
|
|
12
|
-
* filled in from elsewhere in the studio replaces what the editor wrote, for them to send.
|
|
12
|
+
* filled in from elsewhere in the studio replaces what the editor wrote, for them to send. Given a
|
|
13
|
+
* `carry`, the composer of the next thread goes on from this one, as when the studio enters the
|
|
14
|
+
* draft the editor's request was handed off to: with what they were writing, focused if it was.
|
|
13
15
|
*/
|
|
14
16
|
function ThreadComposer(t0) {
|
|
15
|
-
const $ = c(
|
|
16
|
-
const { onSend, onStop, selection, onClearSelection, running: t1, disabled: t2, filled } = t0;
|
|
17
|
+
const $ = c(48);
|
|
18
|
+
const { onSend, onStop, selection, onClearSelection, running: t1, disabled: t2, filled, carry } = t0;
|
|
17
19
|
const running = t1 === void 0 ? false : t1;
|
|
18
20
|
const disabled = t2 === void 0 ? false : t2;
|
|
19
|
-
|
|
21
|
+
let t3;
|
|
22
|
+
if ($[0] !== carry) {
|
|
23
|
+
t3 = () => carry?.held()?.text ?? "";
|
|
24
|
+
$[0] = carry;
|
|
25
|
+
$[1] = t3;
|
|
26
|
+
} else t3 = $[1];
|
|
27
|
+
const [text, setText] = useState(t3);
|
|
20
28
|
const [filledId, setFilledId] = useState();
|
|
21
29
|
if (filled && filled.id !== filledId) {
|
|
22
30
|
setFilledId(filled.id);
|
|
23
31
|
setText(filled.text);
|
|
24
32
|
}
|
|
25
33
|
const box = useRef(null);
|
|
26
|
-
let t3;
|
|
27
34
|
let t4;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
let t5;
|
|
36
|
+
if ($[2] !== carry || $[3] !== text) {
|
|
37
|
+
t4 = () => {
|
|
38
|
+
carry?.hold({
|
|
39
|
+
text,
|
|
40
|
+
focused: carry.held()?.focused ?? false
|
|
41
|
+
});
|
|
31
42
|
};
|
|
32
|
-
|
|
33
|
-
$[
|
|
34
|
-
$[
|
|
35
|
-
$[
|
|
43
|
+
t5 = [carry, text];
|
|
44
|
+
$[2] = carry;
|
|
45
|
+
$[3] = text;
|
|
46
|
+
$[4] = t4;
|
|
47
|
+
$[5] = t5;
|
|
36
48
|
} else {
|
|
37
|
-
|
|
38
|
-
|
|
49
|
+
t4 = $[4];
|
|
50
|
+
t5 = $[5];
|
|
39
51
|
}
|
|
40
|
-
useEffect(
|
|
41
|
-
let t5;
|
|
42
|
-
if ($[3] !== text) {
|
|
43
|
-
t5 = text.trim();
|
|
44
|
-
$[3] = text;
|
|
45
|
-
$[4] = t5;
|
|
46
|
-
} else t5 = $[4];
|
|
47
|
-
const message = t5;
|
|
48
|
-
const canSend = !disabled && message !== "" && onSend !== void 0;
|
|
52
|
+
useEffect(t4, t5);
|
|
49
53
|
let t6;
|
|
50
|
-
|
|
54
|
+
let t7;
|
|
55
|
+
if ($[6] !== carry) {
|
|
51
56
|
t6 = () => {
|
|
57
|
+
const element = box.current;
|
|
58
|
+
if (!carry || !element) return;
|
|
59
|
+
if (carry.held()?.focused) element.focus();
|
|
60
|
+
return () => carry.hold({
|
|
61
|
+
text: element.value,
|
|
62
|
+
focused: element.ownerDocument.activeElement === element
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
t7 = [carry];
|
|
66
|
+
$[6] = carry;
|
|
67
|
+
$[7] = t6;
|
|
68
|
+
$[8] = t7;
|
|
69
|
+
} else {
|
|
70
|
+
t6 = $[7];
|
|
71
|
+
t7 = $[8];
|
|
72
|
+
}
|
|
73
|
+
useLayoutEffect(t6, t7);
|
|
74
|
+
let t8;
|
|
75
|
+
let t9;
|
|
76
|
+
if ($[9] !== filledId) {
|
|
77
|
+
t8 = () => {
|
|
78
|
+
if (filledId !== void 0) box.current?.focus();
|
|
79
|
+
};
|
|
80
|
+
t9 = [filledId];
|
|
81
|
+
$[9] = filledId;
|
|
82
|
+
$[10] = t8;
|
|
83
|
+
$[11] = t9;
|
|
84
|
+
} else {
|
|
85
|
+
t8 = $[10];
|
|
86
|
+
t9 = $[11];
|
|
87
|
+
}
|
|
88
|
+
useEffect(t8, t9);
|
|
89
|
+
let t10;
|
|
90
|
+
if ($[12] !== text) {
|
|
91
|
+
t10 = text.trim();
|
|
92
|
+
$[12] = text;
|
|
93
|
+
$[13] = t10;
|
|
94
|
+
} else t10 = $[13];
|
|
95
|
+
const message = t10;
|
|
96
|
+
const canSend = !disabled && message !== "" && onSend !== void 0;
|
|
97
|
+
let t11;
|
|
98
|
+
if ($[14] !== canSend || $[15] !== message || $[16] !== onSend) {
|
|
99
|
+
t11 = () => {
|
|
52
100
|
if (!canSend) return;
|
|
53
101
|
onSend(message);
|
|
54
102
|
setText("");
|
|
55
103
|
};
|
|
56
|
-
$[
|
|
57
|
-
$[
|
|
58
|
-
$[
|
|
59
|
-
$[
|
|
60
|
-
} else
|
|
61
|
-
const submit =
|
|
62
|
-
let
|
|
63
|
-
if ($[
|
|
64
|
-
|
|
104
|
+
$[14] = canSend;
|
|
105
|
+
$[15] = message;
|
|
106
|
+
$[16] = onSend;
|
|
107
|
+
$[17] = t11;
|
|
108
|
+
} else t11 = $[17];
|
|
109
|
+
const submit = t11;
|
|
110
|
+
let t12;
|
|
111
|
+
if ($[18] !== submit) {
|
|
112
|
+
t12 = (event) => {
|
|
65
113
|
event.preventDefault();
|
|
66
114
|
submit();
|
|
67
115
|
};
|
|
68
|
-
$[
|
|
69
|
-
$[
|
|
70
|
-
} else
|
|
71
|
-
let
|
|
72
|
-
if ($[
|
|
73
|
-
|
|
116
|
+
$[18] = submit;
|
|
117
|
+
$[19] = t12;
|
|
118
|
+
} else t12 = $[19];
|
|
119
|
+
let t13;
|
|
120
|
+
if ($[20] !== onClearSelection || $[21] !== selection) {
|
|
121
|
+
t13 = selection && /* @__PURE__ */ jsx(InputGroupAddon, {
|
|
74
122
|
align: "block-start",
|
|
75
123
|
className: "border-input border-b",
|
|
76
124
|
children: /* @__PURE__ */ jsx(SelectionChip, {
|
|
@@ -78,45 +126,45 @@ function ThreadComposer(t0) {
|
|
|
78
126
|
onClear: onClearSelection
|
|
79
127
|
})
|
|
80
128
|
});
|
|
81
|
-
$[
|
|
82
|
-
$[
|
|
83
|
-
$[
|
|
84
|
-
} else
|
|
85
|
-
let
|
|
86
|
-
if ($[
|
|
87
|
-
|
|
88
|
-
$[
|
|
89
|
-
} else
|
|
90
|
-
let
|
|
91
|
-
if ($[
|
|
92
|
-
|
|
129
|
+
$[20] = onClearSelection;
|
|
130
|
+
$[21] = selection;
|
|
131
|
+
$[22] = t13;
|
|
132
|
+
} else t13 = $[22];
|
|
133
|
+
let t14;
|
|
134
|
+
if ($[23] === Symbol.for("react.memo_cache_sentinel")) {
|
|
135
|
+
t14 = (event_0) => setText(event_0.target.value);
|
|
136
|
+
$[23] = t14;
|
|
137
|
+
} else t14 = $[23];
|
|
138
|
+
let t15;
|
|
139
|
+
if ($[24] !== submit) {
|
|
140
|
+
t15 = (event_1) => {
|
|
93
141
|
if (event_1.key !== "Enter" || event_1.shiftKey || event_1.nativeEvent.isComposing) return;
|
|
94
142
|
event_1.preventDefault();
|
|
95
143
|
submit();
|
|
96
144
|
};
|
|
97
|
-
$[
|
|
98
|
-
$[
|
|
99
|
-
} else
|
|
100
|
-
let
|
|
101
|
-
if ($[
|
|
102
|
-
|
|
145
|
+
$[24] = submit;
|
|
146
|
+
$[25] = t15;
|
|
147
|
+
} else t15 = $[25];
|
|
148
|
+
let t16;
|
|
149
|
+
if ($[26] !== disabled || $[27] !== t15 || $[28] !== text) {
|
|
150
|
+
t16 = /* @__PURE__ */ jsx(InputGroupTextarea, {
|
|
103
151
|
ref: box,
|
|
104
152
|
"aria-label": "Message",
|
|
105
153
|
placeholder: "Message Camox…",
|
|
106
154
|
value: text,
|
|
107
155
|
disabled,
|
|
108
|
-
onChange:
|
|
109
|
-
onKeyDown:
|
|
156
|
+
onChange: t14,
|
|
157
|
+
onKeyDown: t15,
|
|
110
158
|
className: "max-h-48 min-h-14"
|
|
111
159
|
});
|
|
112
|
-
$[
|
|
113
|
-
$[
|
|
114
|
-
$[
|
|
115
|
-
$[
|
|
116
|
-
} else
|
|
117
|
-
let
|
|
118
|
-
if ($[
|
|
119
|
-
|
|
160
|
+
$[26] = disabled;
|
|
161
|
+
$[27] = t15;
|
|
162
|
+
$[28] = text;
|
|
163
|
+
$[29] = t16;
|
|
164
|
+
} else t16 = $[29];
|
|
165
|
+
let t17;
|
|
166
|
+
if ($[30] !== disabled || $[31] !== onStop || $[32] !== running) {
|
|
167
|
+
t17 = running && onStop && /* @__PURE__ */ jsxs(InputGroupButton, {
|
|
120
168
|
type: "button",
|
|
121
169
|
variant: "outline",
|
|
122
170
|
size: "icon-sm",
|
|
@@ -127,73 +175,87 @@ function ThreadComposer(t0) {
|
|
|
127
175
|
children: "Stop"
|
|
128
176
|
})]
|
|
129
177
|
});
|
|
130
|
-
$[
|
|
131
|
-
$[
|
|
132
|
-
$[
|
|
133
|
-
$[
|
|
134
|
-
} else
|
|
135
|
-
const
|
|
136
|
-
let
|
|
137
|
-
let
|
|
138
|
-
if ($[
|
|
139
|
-
|
|
140
|
-
|
|
178
|
+
$[30] = disabled;
|
|
179
|
+
$[31] = onStop;
|
|
180
|
+
$[32] = running;
|
|
181
|
+
$[33] = t17;
|
|
182
|
+
} else t17 = $[33];
|
|
183
|
+
const t18 = !canSend;
|
|
184
|
+
let t19;
|
|
185
|
+
let t20;
|
|
186
|
+
if ($[34] === Symbol.for("react.memo_cache_sentinel")) {
|
|
187
|
+
t19 = /* @__PURE__ */ jsx(ArrowUp, {});
|
|
188
|
+
t20 = /* @__PURE__ */ jsx("span", {
|
|
141
189
|
className: "sr-only",
|
|
142
190
|
children: "Send"
|
|
143
191
|
});
|
|
144
|
-
$[
|
|
145
|
-
$[
|
|
192
|
+
$[34] = t19;
|
|
193
|
+
$[35] = t20;
|
|
146
194
|
} else {
|
|
147
|
-
|
|
148
|
-
|
|
195
|
+
t19 = $[34];
|
|
196
|
+
t20 = $[35];
|
|
149
197
|
}
|
|
150
|
-
let
|
|
151
|
-
if ($[
|
|
152
|
-
|
|
198
|
+
let t21;
|
|
199
|
+
if ($[36] !== t18) {
|
|
200
|
+
t21 = /* @__PURE__ */ jsxs(InputGroupButton, {
|
|
153
201
|
type: "submit",
|
|
154
202
|
variant: "default",
|
|
155
203
|
size: "icon-sm",
|
|
156
|
-
disabled:
|
|
157
|
-
children: [
|
|
204
|
+
disabled: t18,
|
|
205
|
+
children: [t19, t20]
|
|
158
206
|
});
|
|
159
|
-
$[
|
|
160
|
-
$[
|
|
161
|
-
} else
|
|
162
|
-
let
|
|
163
|
-
if ($[
|
|
164
|
-
|
|
207
|
+
$[36] = t18;
|
|
208
|
+
$[37] = t21;
|
|
209
|
+
} else t21 = $[37];
|
|
210
|
+
let t22;
|
|
211
|
+
if ($[38] !== t17 || $[39] !== t21) {
|
|
212
|
+
t22 = /* @__PURE__ */ jsxs(InputGroupAddon, {
|
|
165
213
|
align: "block-end",
|
|
166
214
|
className: "justify-end",
|
|
167
|
-
children: [
|
|
215
|
+
children: [t17, t21]
|
|
168
216
|
});
|
|
169
|
-
$[
|
|
170
|
-
$[
|
|
171
|
-
$[
|
|
172
|
-
} else
|
|
173
|
-
let
|
|
174
|
-
if ($[
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
217
|
+
$[38] = t17;
|
|
218
|
+
$[39] = t21;
|
|
219
|
+
$[40] = t22;
|
|
220
|
+
} else t22 = $[40];
|
|
221
|
+
let t23;
|
|
222
|
+
if ($[41] !== t13 || $[42] !== t16 || $[43] !== t22) {
|
|
223
|
+
t23 = /* @__PURE__ */ jsxs(InputGroup, { children: [
|
|
224
|
+
t13,
|
|
225
|
+
t16,
|
|
226
|
+
t22
|
|
179
227
|
] });
|
|
180
|
-
$[
|
|
181
|
-
$[
|
|
182
|
-
$[
|
|
183
|
-
$[
|
|
184
|
-
} else
|
|
185
|
-
let
|
|
186
|
-
if ($[
|
|
187
|
-
|
|
228
|
+
$[41] = t13;
|
|
229
|
+
$[42] = t16;
|
|
230
|
+
$[43] = t22;
|
|
231
|
+
$[44] = t23;
|
|
232
|
+
} else t23 = $[44];
|
|
233
|
+
let t24;
|
|
234
|
+
if ($[45] !== t12 || $[46] !== t23) {
|
|
235
|
+
t24 = /* @__PURE__ */ jsx("form", {
|
|
188
236
|
className: "p-2",
|
|
189
|
-
onSubmit:
|
|
190
|
-
children:
|
|
237
|
+
onSubmit: t12,
|
|
238
|
+
children: t23
|
|
191
239
|
});
|
|
192
|
-
$[
|
|
193
|
-
$[
|
|
194
|
-
$[
|
|
195
|
-
} else
|
|
196
|
-
return
|
|
240
|
+
$[45] = t12;
|
|
241
|
+
$[46] = t23;
|
|
242
|
+
$[47] = t24;
|
|
243
|
+
} else t24 = $[47];
|
|
244
|
+
return t24;
|
|
245
|
+
}
|
|
246
|
+
/** A carrier that lasts as long as the component that keeps it. */
|
|
247
|
+
function useComposerCarrier() {
|
|
248
|
+
const [carrier] = useState(_temp);
|
|
249
|
+
return carrier;
|
|
250
|
+
}
|
|
251
|
+
function _temp() {
|
|
252
|
+
let held = null;
|
|
253
|
+
return {
|
|
254
|
+
held: () => held,
|
|
255
|
+
hold: (carry) => {
|
|
256
|
+
held = carry;
|
|
257
|
+
}
|
|
258
|
+
};
|
|
197
259
|
}
|
|
198
260
|
/** The selection the editor's messages carry, by its name. */
|
|
199
261
|
function SelectionChip(t0) {
|
|
@@ -247,4 +309,4 @@ function SelectionChip(t0) {
|
|
|
247
309
|
}
|
|
248
310
|
|
|
249
311
|
//#endregion
|
|
250
|
-
export { ThreadComposer };
|
|
312
|
+
export { ThreadComposer, useComposerCarrier };
|
|
@@ -18,7 +18,7 @@ import { MessageScroller, MessageScrollerButton, MessageScrollerContent, Message
|
|
|
18
18
|
* agent does, never how: thinking, looking around, making changes, building, fixing the build,
|
|
19
19
|
* or starting a draft. Each editor's message shows its
|
|
20
20
|
* sender's avatar, without their name. A Live turn handed off to a draft ends on the draft's
|
|
21
|
-
* card, which `onOpenDraft` opens.
|
|
21
|
+
* card, which `onOpenDraft` opens. The thread keeps its end in view, unless the editor scrolls up.
|
|
22
22
|
*/
|
|
23
23
|
function ThreadMessages(t0) {
|
|
24
24
|
const $ = c(20);
|
|
@@ -105,10 +105,13 @@ function ThreadMessages(t0) {
|
|
|
105
105
|
} else t5 = $[17];
|
|
106
106
|
let t6;
|
|
107
107
|
if ($[18] !== t4) {
|
|
108
|
-
t6 = /* @__PURE__ */ jsx(MessageScrollerProvider, {
|
|
109
|
-
|
|
110
|
-
children:
|
|
111
|
-
|
|
108
|
+
t6 = /* @__PURE__ */ jsx(MessageScrollerProvider, {
|
|
109
|
+
autoScroll: true,
|
|
110
|
+
children: /* @__PURE__ */ jsxs(MessageScroller, {
|
|
111
|
+
className: "min-h-0 flex-1",
|
|
112
|
+
children: [t4, t5]
|
|
113
|
+
})
|
|
114
|
+
});
|
|
112
115
|
$[18] = t4;
|
|
113
116
|
$[19] = t6;
|
|
114
117
|
} else t6 = $[19];
|
|
@@ -492,8 +495,8 @@ function _temp(subject, index) {
|
|
|
492
495
|
}, index);
|
|
493
496
|
}
|
|
494
497
|
/**
|
|
495
|
-
* A message's text, cropped past
|
|
496
|
-
* shows it all. A message that fits shows as is.
|
|
498
|
+
* A message's text, cropped past five lines and a half, fading out gently from its second line,
|
|
499
|
+
* above a button that shows it all. A message that fits shows as is.
|
|
497
500
|
*/
|
|
498
501
|
function CroppedText(t0) {
|
|
499
502
|
const $ = c(17);
|
|
@@ -508,9 +511,14 @@ function CroppedText(t0) {
|
|
|
508
511
|
if (!element || expanded) return;
|
|
509
512
|
const measure = () => setOverflows(element.scrollHeight > element.clientHeight + 1);
|
|
510
513
|
measure();
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
|
|
514
|
+
const resizes = new ResizeObserver(measure);
|
|
515
|
+
resizes.observe(element);
|
|
516
|
+
const views = new IntersectionObserver(measure);
|
|
517
|
+
views.observe(element);
|
|
518
|
+
return () => {
|
|
519
|
+
resizes.disconnect();
|
|
520
|
+
views.disconnect();
|
|
521
|
+
};
|
|
514
522
|
};
|
|
515
523
|
$[0] = expanded;
|
|
516
524
|
$[1] = t1;
|
|
@@ -526,7 +534,7 @@ function CroppedText(t0) {
|
|
|
526
534
|
const cropped = !expanded && overflows;
|
|
527
535
|
const t3 = cropped || void 0;
|
|
528
536
|
const t4 = !expanded && "max-h-[5.5lh] overflow-hidden";
|
|
529
|
-
const t5 = cropped && "mask-[linear-gradient(to_bottom,
|
|
537
|
+
const t5 = cropped && "mask-[linear-gradient(to_bottom,black_1.5lh,transparent)]";
|
|
530
538
|
let t6;
|
|
531
539
|
if ($[5] !== t4 || $[6] !== t5) {
|
|
532
540
|
t6 = cn("whitespace-pre-wrap", t4, t5);
|