camox 0.53.1 → 0.56.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 +14 -11
- package/dist/features/canvas/CanvasLoadingScreen.js +1 -1
- package/dist/features/canvas/sidebar/CanvasViewHeader.js +1 -1
- package/dist/features/canvas/sidebar/{CanvasSidebar.js → ContentSidebar.js} +5 -5
- package/dist/features/canvas/sidebar/{CanvasSidebarFrame.js → ContentSidebarFrame.js} +4 -4
- package/dist/features/canvas/sidebar/{CanvasSidebarSkeleton.js → ContentSidebarSkeleton.js} +7 -7
- package/dist/features/og/documentFonts.js +49 -0
- package/dist/features/og/imageResponse.d.ts +14 -5
- package/dist/features/og/imageResponse.js +20 -21
- package/dist/features/og/pageImage.js +7 -4
- package/dist/features/preview/CamoxPreview.js +2 -2
- package/dist/features/preview/components/BlockActionsPopover.js +1 -1
- package/dist/features/preview/components/IconFieldEditor.js +1 -1
- package/dist/features/preview/components/LinkFieldEditor.js +1 -1
- package/dist/features/preview/components/PagePicker.js +1 -1
- package/dist/features/preview/components/PreviewToolbar.js +1 -1
- package/dist/features/preview/components/SelectionEditor.js +136 -110
- package/dist/features/preview/components/SidebarStack.js +110 -83
- package/dist/features/preview/components/StudioEditingFallback.js +3 -3
- package/dist/features/routes/pageRuntime.d.ts +1 -1
- package/dist/features/runtime/RuntimeChrome.js +4 -4
- package/dist/features/runtime/runtime.d.ts +5 -0
- package/dist/features/runtime/runtime.js +15 -4
- package/dist/features/studio/components/AgentSidebar.js +56 -0
- package/dist/features/studio/components/ChatWidget.js +237 -0
- package/dist/features/studio/components/DraftsControl.js +17 -17
- package/dist/features/studio/components/ReviewDraftSheet.js +38 -38
- package/dist/features/studio/components/Squareling.js +116 -0
- package/dist/features/studio/components/ThreadMessages.js +190 -165
- package/dist/features/studio/components/WorkersWidget.js +52 -0
- package/dist/features/studio/studioStore.js +5 -5
- package/dist/features/vite/bundlerLogs.js +1 -0
- package/dist/features/vite/runtimeDev.js +11 -0
- package/dist/features/vite/vite.js +3 -1
- package/dist/lib/queries.js +1 -1
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +5 -5
- package/skills/camox/SKILL.md +3 -10
- package/skills/camox/references/artifacts.md +2 -2
- package/skills/camox/references/block-definitions.md +1 -1
- package/skills/camox/references/layout-definitions.md +12 -17
- package/skills/camox/references/routed-layouts.md +2 -2
- package/skills/camox-cli/SKILL.md +15 -0
- package/skills/{camox → camox-cli}/references/cli-common.md +1 -1
- package/skills/{camox → camox-cli}/references/cli-content.md +2 -2
- package/skills/{camox → camox-cli}/references/cli-publishing.md +4 -4
- package/skills/camox-expand/SKILL.md +1 -1
- package/skills/camoxify/SKILL.md +1 -1
- package/dist/features/og/defaultFonts.js +0 -31
- package/dist/features/og/geist-variable-ttf-base64.js +0 -21
- package/dist/features/studio/components/ChatSidebar.js +0 -364
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { cn } from "../../../lib/utils.js";
|
|
2
|
+
import { c } from "react/compiler-runtime";
|
|
3
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
|
|
5
|
+
//#region src/features/studio/components/Squareling.tsx
|
|
6
|
+
/**
|
|
7
|
+
* Camox's agent, drawn from the logo's shapes: its square, the soft corner, and the knockout as
|
|
8
|
+
* eyes, looking right like the mark. Its face and motion say what the agent is doing. The
|
|
9
|
+
* animations live in `studio.css`.
|
|
10
|
+
*/
|
|
11
|
+
function Squareling(t0) {
|
|
12
|
+
const $ = c(18);
|
|
13
|
+
const { status, className, ref } = t0;
|
|
14
|
+
let t1;
|
|
15
|
+
if ($[0] !== className) {
|
|
16
|
+
t1 = cn("squareling shrink-0 overflow-visible", className);
|
|
17
|
+
$[0] = className;
|
|
18
|
+
$[1] = t1;
|
|
19
|
+
} else t1 = $[1];
|
|
20
|
+
let t2;
|
|
21
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
22
|
+
t2 = /* @__PURE__ */ jsx("path", {
|
|
23
|
+
d: "M20 12H80Q88 12 88 20V64Q88 88 64 88H20Q12 88 12 80V20Q12 12 20 12Z",
|
|
24
|
+
className: "fill-emerald-500"
|
|
25
|
+
});
|
|
26
|
+
$[2] = t2;
|
|
27
|
+
} else t2 = $[2];
|
|
28
|
+
let t3;
|
|
29
|
+
if ($[3] !== status) {
|
|
30
|
+
t3 = (status === "idle" || status === "thinking") && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("rect", {
|
|
31
|
+
className: "squareling-eye",
|
|
32
|
+
x: "50",
|
|
33
|
+
y: "36",
|
|
34
|
+
width: "11",
|
|
35
|
+
height: "17"
|
|
36
|
+
}), /* @__PURE__ */ jsx("rect", {
|
|
37
|
+
className: "squareling-eye",
|
|
38
|
+
x: "69",
|
|
39
|
+
y: "36",
|
|
40
|
+
width: "11",
|
|
41
|
+
height: "17"
|
|
42
|
+
})] });
|
|
43
|
+
$[3] = status;
|
|
44
|
+
$[4] = t3;
|
|
45
|
+
} else t3 = $[4];
|
|
46
|
+
let t4;
|
|
47
|
+
if ($[5] !== status) {
|
|
48
|
+
t4 = status === "acting" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("rect", {
|
|
49
|
+
x: "50",
|
|
50
|
+
y: "44",
|
|
51
|
+
width: "11",
|
|
52
|
+
height: "6"
|
|
53
|
+
}), /* @__PURE__ */ jsx("rect", {
|
|
54
|
+
x: "69",
|
|
55
|
+
y: "44",
|
|
56
|
+
width: "11",
|
|
57
|
+
height: "6"
|
|
58
|
+
})] });
|
|
59
|
+
$[5] = status;
|
|
60
|
+
$[6] = t4;
|
|
61
|
+
} else t4 = $[6];
|
|
62
|
+
let t5;
|
|
63
|
+
if ($[7] !== status) {
|
|
64
|
+
t5 = status === "fixing" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("rect", {
|
|
65
|
+
x: "50",
|
|
66
|
+
y: "36",
|
|
67
|
+
width: "11",
|
|
68
|
+
height: "17"
|
|
69
|
+
}), /* @__PURE__ */ jsx("rect", {
|
|
70
|
+
x: "69",
|
|
71
|
+
y: "44",
|
|
72
|
+
width: "11",
|
|
73
|
+
height: "6"
|
|
74
|
+
})] });
|
|
75
|
+
$[7] = status;
|
|
76
|
+
$[8] = t5;
|
|
77
|
+
} else t5 = $[8];
|
|
78
|
+
let t6;
|
|
79
|
+
if ($[9] !== t3 || $[10] !== t4 || $[11] !== t5) {
|
|
80
|
+
t6 = /* @__PURE__ */ jsxs("g", {
|
|
81
|
+
className: "squareling-body",
|
|
82
|
+
children: [t2, /* @__PURE__ */ jsxs("g", {
|
|
83
|
+
className: "squareling-eyes fill-neutral-950",
|
|
84
|
+
children: [
|
|
85
|
+
t3,
|
|
86
|
+
t4,
|
|
87
|
+
t5
|
|
88
|
+
]
|
|
89
|
+
})]
|
|
90
|
+
});
|
|
91
|
+
$[9] = t3;
|
|
92
|
+
$[10] = t4;
|
|
93
|
+
$[11] = t5;
|
|
94
|
+
$[12] = t6;
|
|
95
|
+
} else t6 = $[12];
|
|
96
|
+
let t7;
|
|
97
|
+
if ($[13] !== ref || $[14] !== status || $[15] !== t1 || $[16] !== t6) {
|
|
98
|
+
t7 = /* @__PURE__ */ jsx("svg", {
|
|
99
|
+
ref,
|
|
100
|
+
viewBox: "0 0 100 100",
|
|
101
|
+
"aria-hidden": true,
|
|
102
|
+
"data-squareling": status,
|
|
103
|
+
className: t1,
|
|
104
|
+
children: t6
|
|
105
|
+
});
|
|
106
|
+
$[13] = ref;
|
|
107
|
+
$[14] = status;
|
|
108
|
+
$[15] = t1;
|
|
109
|
+
$[16] = t6;
|
|
110
|
+
$[17] = t7;
|
|
111
|
+
} else t7 = $[17];
|
|
112
|
+
return t7;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
//#endregion
|
|
116
|
+
export { Squareling };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { Squareling } from "./Squareling.js";
|
|
1
2
|
import { ThreadMarkdown } from "./ThreadMarkdown.js";
|
|
2
3
|
import { c } from "react/compiler-runtime";
|
|
4
|
+
import * as React from "react";
|
|
3
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
6
|
import { Avatar, AvatarFallback, AvatarImage } from "@camox/ui/avatar";
|
|
5
7
|
import { Bubble, BubbleContent } from "@camox/ui/bubble";
|
|
@@ -8,143 +10,208 @@ import { MessageScroller, MessageScrollerButton, MessageScrollerContent, Message
|
|
|
8
10
|
|
|
9
11
|
//#region src/features/studio/components/ThreadMessages.tsx
|
|
10
12
|
/**
|
|
11
|
-
* A thread's messages, and
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* A thread's messages, and the agent's squareling, which always lives in it. An empty thread has
|
|
14
|
+
* it greet the editor; when the first message arrives, it moves to the end of the thread, and
|
|
15
|
+
* stays there after each message. While a run is going or a message is still `sending` (on its
|
|
16
|
+
* way to the thread, which hasn't accepted it yet), its face says whether the agent thinks or
|
|
17
|
+
* acts (uses its tools, or builds its code). While the end of a turn builds the agent's code, or
|
|
18
|
+
* the agent fixes a build error, it says so in words too. Each editor's message shows its
|
|
19
|
+
* sender's avatar, without their name.
|
|
16
20
|
*/
|
|
17
21
|
function ThreadMessages(t0) {
|
|
18
|
-
const $ = c(
|
|
19
|
-
const { view, sending: t1
|
|
22
|
+
const $ = c(19);
|
|
23
|
+
const { view, sending: t1 } = t0;
|
|
20
24
|
const sending = t1 === void 0 ? false : t1;
|
|
21
|
-
const showSenders = t2 === void 0 ? false : t2;
|
|
22
25
|
const working = view.running || sending;
|
|
23
|
-
|
|
26
|
+
const empty = view.messages.length === 0 && !working;
|
|
27
|
+
const squareling = useSquarelingMorph(empty);
|
|
28
|
+
if (empty) {
|
|
29
|
+
let t2;
|
|
30
|
+
if ($[0] !== squareling) {
|
|
31
|
+
t2 = /* @__PURE__ */ jsx(Squareling, {
|
|
32
|
+
ref: squareling,
|
|
33
|
+
status: "idle",
|
|
34
|
+
className: "size-10"
|
|
35
|
+
});
|
|
36
|
+
$[0] = squareling;
|
|
37
|
+
$[1] = t2;
|
|
38
|
+
} else t2 = $[1];
|
|
24
39
|
let t3;
|
|
25
|
-
if ($[0] !== continuedIn) {
|
|
26
|
-
t3 = continuedIn && /* @__PURE__ */ jsx(ContinuedIn, { link: continuedIn });
|
|
27
|
-
$[0] = continuedIn;
|
|
28
|
-
$[1] = t3;
|
|
29
|
-
} else t3 = $[1];
|
|
30
|
-
let t4;
|
|
31
40
|
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
32
|
-
|
|
41
|
+
t3 = /* @__PURE__ */ jsx("p", { children: "How can I help?" });
|
|
42
|
+
$[2] = t3;
|
|
43
|
+
} else t3 = $[2];
|
|
44
|
+
let t4;
|
|
45
|
+
if ($[3] !== t2) {
|
|
46
|
+
t4 = /* @__PURE__ */ jsxs("div", {
|
|
33
47
|
"data-thread-empty": true,
|
|
34
|
-
className: "text-muted-foreground flex min-h-0 flex-1 items-center justify-center p-4 text-center text-sm",
|
|
35
|
-
children:
|
|
48
|
+
className: "text-muted-foreground flex min-h-0 flex-1 flex-col items-center justify-center gap-3 p-4 text-center text-sm",
|
|
49
|
+
children: [t2, t3]
|
|
36
50
|
});
|
|
37
|
-
$[
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
t5 = /* @__PURE__ */ jsxs("div", {
|
|
42
|
-
className: "flex min-h-0 flex-1 flex-col",
|
|
43
|
-
children: [t3, t4]
|
|
44
|
-
});
|
|
45
|
-
$[3] = t3;
|
|
46
|
-
$[4] = t5;
|
|
47
|
-
} else t5 = $[4];
|
|
48
|
-
return t5;
|
|
51
|
+
$[3] = t2;
|
|
52
|
+
$[4] = t4;
|
|
53
|
+
} else t4 = $[4];
|
|
54
|
+
return t4;
|
|
49
55
|
}
|
|
56
|
+
let t2;
|
|
57
|
+
if ($[5] !== squareling || $[6] !== view || $[7] !== working) {
|
|
58
|
+
t2 = view.messages.map((message, index) => /* @__PURE__ */ jsxs(MessageScrollerItem, {
|
|
59
|
+
messageId: message.id,
|
|
60
|
+
scrollAnchor: message.from === "editor",
|
|
61
|
+
className: "flex flex-col gap-4",
|
|
62
|
+
children: [/* @__PURE__ */ jsx(ThreadMessageRow, { message }), index === view.messages.length - 1 && /* @__PURE__ */ jsx(AgentPresence, {
|
|
63
|
+
view,
|
|
64
|
+
working,
|
|
65
|
+
squareling
|
|
66
|
+
})]
|
|
67
|
+
}, message.id));
|
|
68
|
+
$[5] = squareling;
|
|
69
|
+
$[6] = view;
|
|
70
|
+
$[7] = working;
|
|
71
|
+
$[8] = t2;
|
|
72
|
+
} else t2 = $[8];
|
|
50
73
|
let t3;
|
|
51
|
-
if ($[
|
|
52
|
-
t3 =
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
74
|
+
if ($[9] !== squareling || $[10] !== view || $[11] !== working) {
|
|
75
|
+
t3 = view.messages.length === 0 && /* @__PURE__ */ jsx(AgentPresence, {
|
|
76
|
+
view,
|
|
77
|
+
working,
|
|
78
|
+
squareling
|
|
79
|
+
});
|
|
80
|
+
$[9] = squareling;
|
|
81
|
+
$[10] = view;
|
|
82
|
+
$[11] = working;
|
|
83
|
+
$[12] = t3;
|
|
84
|
+
} else t3 = $[12];
|
|
56
85
|
let t4;
|
|
57
|
-
if ($[
|
|
58
|
-
|
|
59
|
-
if ($[12] !== showSenders || $[13] !== view.messages.length || $[14] !== view.status || $[15] !== working) {
|
|
60
|
-
t5 = (message, index) => /* @__PURE__ */ jsxs(MessageScrollerItem, {
|
|
61
|
-
messageId: message.id,
|
|
62
|
-
scrollAnchor: message.from === "editor",
|
|
63
|
-
className: "flex flex-col gap-4",
|
|
64
|
-
children: [/* @__PURE__ */ jsx(ThreadMessageRow, {
|
|
65
|
-
message,
|
|
66
|
-
showSender: showSenders
|
|
67
|
-
}), working && index === view.messages.length - 1 && /* @__PURE__ */ jsx(Working, { status: view.status })]
|
|
68
|
-
}, message.id);
|
|
69
|
-
$[12] = showSenders;
|
|
70
|
-
$[13] = view.messages.length;
|
|
71
|
-
$[14] = view.status;
|
|
72
|
-
$[15] = working;
|
|
73
|
-
$[16] = t5;
|
|
74
|
-
} else t5 = $[16];
|
|
75
|
-
t4 = view.messages.map(t5);
|
|
76
|
-
$[7] = showSenders;
|
|
77
|
-
$[8] = view.messages;
|
|
78
|
-
$[9] = view.status;
|
|
79
|
-
$[10] = working;
|
|
80
|
-
$[11] = t4;
|
|
81
|
-
} else t4 = $[11];
|
|
82
|
-
let t5;
|
|
83
|
-
if ($[17] !== view.messages.length || $[18] !== view.status || $[19] !== working) {
|
|
84
|
-
t5 = working && view.messages.length === 0 && /* @__PURE__ */ jsx(Working, { status: view.status });
|
|
85
|
-
$[17] = view.messages.length;
|
|
86
|
-
$[18] = view.status;
|
|
87
|
-
$[19] = working;
|
|
88
|
-
$[20] = t5;
|
|
89
|
-
} else t5 = $[20];
|
|
90
|
-
let t6;
|
|
91
|
-
if ($[21] !== t3 || $[22] !== t4 || $[23] !== t5) {
|
|
92
|
-
t6 = /* @__PURE__ */ jsx(MessageScrollerViewport, { children: /* @__PURE__ */ jsxs(MessageScrollerContent, {
|
|
86
|
+
if ($[13] !== t2 || $[14] !== t3) {
|
|
87
|
+
t4 = /* @__PURE__ */ jsx(MessageScrollerViewport, { children: /* @__PURE__ */ jsxs(MessageScrollerContent, {
|
|
93
88
|
className: "flex flex-col gap-4 px-2 py-3",
|
|
94
|
-
children: [
|
|
95
|
-
t3,
|
|
96
|
-
t4,
|
|
97
|
-
t5
|
|
98
|
-
]
|
|
89
|
+
children: [t2, t3]
|
|
99
90
|
}) });
|
|
100
|
-
$[
|
|
101
|
-
$[
|
|
102
|
-
$[
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
t8 = /* @__PURE__ */ jsx(MessageScrollerProvider, { children: /* @__PURE__ */ jsxs(MessageScroller, {
|
|
91
|
+
$[13] = t2;
|
|
92
|
+
$[14] = t3;
|
|
93
|
+
$[15] = t4;
|
|
94
|
+
} else t4 = $[15];
|
|
95
|
+
let t5;
|
|
96
|
+
if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
|
|
97
|
+
t5 = /* @__PURE__ */ jsx(MessageScrollerButton, {});
|
|
98
|
+
$[16] = t5;
|
|
99
|
+
} else t5 = $[16];
|
|
100
|
+
let t6;
|
|
101
|
+
if ($[17] !== t4) {
|
|
102
|
+
t6 = /* @__PURE__ */ jsx(MessageScrollerProvider, { children: /* @__PURE__ */ jsxs(MessageScroller, {
|
|
113
103
|
className: "min-h-0 flex-1",
|
|
114
|
-
children: [
|
|
104
|
+
children: [t4, t5]
|
|
115
105
|
}) });
|
|
116
|
-
$[
|
|
117
|
-
$[
|
|
118
|
-
} else
|
|
119
|
-
return
|
|
106
|
+
$[17] = t4;
|
|
107
|
+
$[18] = t6;
|
|
108
|
+
} else t6 = $[18];
|
|
109
|
+
return t6;
|
|
120
110
|
}
|
|
111
|
+
/** How long the greeting's squareling takes to reach the end of the thread, in ms. */
|
|
112
|
+
const MORPH_DURATION = 350;
|
|
113
|
+
/** A strong ease-in-out, for moving across the screen. */
|
|
114
|
+
const MORPH_EASING = "cubic-bezier(0.77, 0, 0.175, 1)";
|
|
121
115
|
/**
|
|
122
|
-
*
|
|
123
|
-
*
|
|
116
|
+
* Moves the squareling from where the greeting showed it to the end of the thread, as the first
|
|
117
|
+
* message arrives, so it reads as the same one. Without motion for editors who reduce it.
|
|
124
118
|
*/
|
|
125
|
-
function
|
|
119
|
+
function useSquarelingMorph(empty) {
|
|
126
120
|
const $ = c(2);
|
|
127
|
-
const
|
|
128
|
-
const
|
|
121
|
+
const node = React.useRef(null);
|
|
122
|
+
const greeting = React.useRef(null);
|
|
123
|
+
let t0;
|
|
124
|
+
if ($[0] !== empty) {
|
|
125
|
+
t0 = () => {
|
|
126
|
+
const element = node.current;
|
|
127
|
+
if (!element) return;
|
|
128
|
+
if (empty) {
|
|
129
|
+
greeting.current = element.getBoundingClientRect();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const from = greeting.current;
|
|
133
|
+
greeting.current = null;
|
|
134
|
+
if (!from || matchMedia("(prefers-reduced-motion: reduce)").matches) return;
|
|
135
|
+
const to = element.getBoundingClientRect();
|
|
136
|
+
if (to.width === 0) return;
|
|
137
|
+
const dx = from.left + from.width / 2 - (to.left + to.width / 2);
|
|
138
|
+
const dy = from.top + from.height / 2 - (to.top + to.height / 2);
|
|
139
|
+
element.animate([{ transform: `translate(${dx}px, ${dy}px) scale(${from.width / to.width})` }, { transform: "none" }], {
|
|
140
|
+
duration: MORPH_DURATION,
|
|
141
|
+
easing: MORPH_EASING
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
$[0] = empty;
|
|
145
|
+
$[1] = t0;
|
|
146
|
+
} else t0 = $[1];
|
|
147
|
+
React.useLayoutEffect(t0);
|
|
148
|
+
return node;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* The squareling at the end of the thread: idle between turns, at work during one. Shown in the
|
|
152
|
+
* last message, not after it: the scroller only brings a message the editor just sent into view
|
|
153
|
+
* when it's appended last, and it arrives while the agent is already working.
|
|
154
|
+
*/
|
|
155
|
+
function AgentPresence(t0) {
|
|
156
|
+
const $ = c(13);
|
|
157
|
+
const { view: t1, working, squareling } = t0;
|
|
158
|
+
const { status, usingTools } = t1;
|
|
129
159
|
let t2;
|
|
130
|
-
if ($[0] !==
|
|
131
|
-
t2 =
|
|
160
|
+
if ($[0] !== status || $[1] !== usingTools || $[2] !== working) {
|
|
161
|
+
t2 = working ? squarelingStatus(status, usingTools) : "idle";
|
|
162
|
+
$[0] = status;
|
|
163
|
+
$[1] = usingTools;
|
|
164
|
+
$[2] = working;
|
|
165
|
+
$[3] = t2;
|
|
166
|
+
} else t2 = $[3];
|
|
167
|
+
let t3;
|
|
168
|
+
if ($[4] !== squareling || $[5] !== t2) {
|
|
169
|
+
t3 = /* @__PURE__ */ jsx(Squareling, {
|
|
170
|
+
ref: squareling,
|
|
171
|
+
status: t2,
|
|
172
|
+
className: "size-6"
|
|
173
|
+
});
|
|
174
|
+
$[4] = squareling;
|
|
175
|
+
$[5] = t2;
|
|
176
|
+
$[6] = t3;
|
|
177
|
+
} else t3 = $[6];
|
|
178
|
+
let t4;
|
|
179
|
+
if ($[7] !== status || $[8] !== working) {
|
|
180
|
+
t4 = working && (status ? /* @__PURE__ */ jsx("span", {
|
|
181
|
+
className: "shimmer",
|
|
182
|
+
children: STATUS_LINES[status]
|
|
183
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
184
|
+
className: "sr-only",
|
|
185
|
+
children: "Working…"
|
|
186
|
+
}));
|
|
187
|
+
$[7] = status;
|
|
188
|
+
$[8] = working;
|
|
189
|
+
$[9] = t4;
|
|
190
|
+
} else t4 = $[9];
|
|
191
|
+
let t5;
|
|
192
|
+
if ($[10] !== t3 || $[11] !== t4) {
|
|
193
|
+
t5 = /* @__PURE__ */ jsxs("div", {
|
|
132
194
|
role: "status",
|
|
133
|
-
className: "
|
|
134
|
-
children:
|
|
195
|
+
className: "text-muted-foreground flex items-center gap-2 text-sm",
|
|
196
|
+
children: [t3, t4]
|
|
135
197
|
});
|
|
136
|
-
$[
|
|
137
|
-
$[
|
|
138
|
-
|
|
139
|
-
|
|
198
|
+
$[10] = t3;
|
|
199
|
+
$[11] = t4;
|
|
200
|
+
$[12] = t5;
|
|
201
|
+
} else t5 = $[12];
|
|
202
|
+
return t5;
|
|
203
|
+
}
|
|
204
|
+
function squarelingStatus(status, usingTools) {
|
|
205
|
+
if (status === "fixing") return "fixing";
|
|
206
|
+
return status === "building" || usingTools ? "acting" : "thinking";
|
|
140
207
|
}
|
|
141
208
|
const STATUS_LINES = {
|
|
142
209
|
building: "Building…",
|
|
143
210
|
fixing: "Fixing a build error…"
|
|
144
211
|
};
|
|
145
212
|
function ThreadMessageRow(t0) {
|
|
146
|
-
const $ = c(
|
|
147
|
-
const { message
|
|
213
|
+
const $ = c(14);
|
|
214
|
+
const { message } = t0;
|
|
148
215
|
if (message.from === "stopped" || message.from === "failed") {
|
|
149
216
|
const t1 = message.from === "stopped" ? `Stopped by ${message.sender.name}` : "Camox couldn’t finish this. Send your message again to retry.";
|
|
150
217
|
let t2;
|
|
@@ -198,18 +265,8 @@ function ThreadMessageRow(t0) {
|
|
|
198
265
|
$[8] = t1;
|
|
199
266
|
} else t1 = $[8];
|
|
200
267
|
let t2;
|
|
201
|
-
if ($[9] !== message.
|
|
202
|
-
t2 =
|
|
203
|
-
className: "text-muted-foreground text-xs",
|
|
204
|
-
children: message.sender.name
|
|
205
|
-
});
|
|
206
|
-
$[9] = message.sender;
|
|
207
|
-
$[10] = showSender;
|
|
208
|
-
$[11] = t2;
|
|
209
|
-
} else t2 = $[11];
|
|
210
|
-
let t3;
|
|
211
|
-
if ($[12] !== message.text) {
|
|
212
|
-
t3 = /* @__PURE__ */ jsx(Bubble, {
|
|
268
|
+
if ($[9] !== message.text) {
|
|
269
|
+
t2 = /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(Bubble, {
|
|
213
270
|
align: "end",
|
|
214
271
|
variant: "muted",
|
|
215
272
|
className: "max-w-full",
|
|
@@ -217,53 +274,21 @@ function ThreadMessageRow(t0) {
|
|
|
217
274
|
className: "whitespace-pre-wrap",
|
|
218
275
|
children: message.text
|
|
219
276
|
})
|
|
277
|
+
}) });
|
|
278
|
+
$[9] = message.text;
|
|
279
|
+
$[10] = t2;
|
|
280
|
+
} else t2 = $[10];
|
|
281
|
+
let t3;
|
|
282
|
+
if ($[11] !== t1 || $[12] !== t2) {
|
|
283
|
+
t3 = /* @__PURE__ */ jsxs(Message, {
|
|
284
|
+
align: "end",
|
|
285
|
+
children: [t1, t2]
|
|
220
286
|
});
|
|
221
|
-
$[
|
|
287
|
+
$[11] = t1;
|
|
288
|
+
$[12] = t2;
|
|
222
289
|
$[13] = t3;
|
|
223
290
|
} else t3 = $[13];
|
|
224
|
-
|
|
225
|
-
if ($[14] !== t2 || $[15] !== t3) {
|
|
226
|
-
t4 = /* @__PURE__ */ jsxs(MessageContent, { children: [t2, t3] });
|
|
227
|
-
$[14] = t2;
|
|
228
|
-
$[15] = t3;
|
|
229
|
-
$[16] = t4;
|
|
230
|
-
} else t4 = $[16];
|
|
231
|
-
let t5;
|
|
232
|
-
if ($[17] !== t1 || $[18] !== t4) {
|
|
233
|
-
t5 = /* @__PURE__ */ jsxs(Message, {
|
|
234
|
-
align: "end",
|
|
235
|
-
children: [t1, t4]
|
|
236
|
-
});
|
|
237
|
-
$[17] = t1;
|
|
238
|
-
$[18] = t4;
|
|
239
|
-
$[19] = t5;
|
|
240
|
-
} else t5 = $[19];
|
|
241
|
-
return t5;
|
|
242
|
-
}
|
|
243
|
-
function ContinuedIn(t0) {
|
|
244
|
-
const $ = c(4);
|
|
245
|
-
const { link } = t0;
|
|
246
|
-
let t1;
|
|
247
|
-
if ($[0] !== link.href || $[1] !== link.label || $[2] !== link.onOpen) {
|
|
248
|
-
t1 = /* @__PURE__ */ jsxs("p", {
|
|
249
|
-
className: "text-muted-foreground px-2 pt-3 text-center text-sm",
|
|
250
|
-
children: [
|
|
251
|
-
"Continued in",
|
|
252
|
-
" ",
|
|
253
|
-
/* @__PURE__ */ jsx("a", {
|
|
254
|
-
href: link.href,
|
|
255
|
-
onClick: link.onOpen,
|
|
256
|
-
className: "text-foreground underline",
|
|
257
|
-
children: link.label
|
|
258
|
-
})
|
|
259
|
-
]
|
|
260
|
-
});
|
|
261
|
-
$[0] = link.href;
|
|
262
|
-
$[1] = link.label;
|
|
263
|
-
$[2] = link.onOpen;
|
|
264
|
-
$[3] = t1;
|
|
265
|
-
} else t1 = $[3];
|
|
266
|
-
return t1;
|
|
291
|
+
return t3;
|
|
267
292
|
}
|
|
268
293
|
const initials = (name) => name.split(" ").map((part) => part[0]).join("").toUpperCase().slice(0, 2);
|
|
269
294
|
function SenderAvatar(t0) {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { cn } from "../../../lib/utils.js";
|
|
2
|
+
import { BOTTOM_CARD_EDGES, CARD_BODY_EDGES } from "../../preview/components/SidebarStack.js";
|
|
3
|
+
import { c } from "react/compiler-runtime";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/features/studio/components/WorkersWidget.tsx
|
|
7
|
+
/** The Agent Sidebar's Workers widget, over the Chat widget. A placeholder for now. */
|
|
8
|
+
function WorkersWidget(t0) {
|
|
9
|
+
const $ = c(6);
|
|
10
|
+
const { className } = t0;
|
|
11
|
+
let t1;
|
|
12
|
+
if ($[0] !== className) {
|
|
13
|
+
t1 = cn("flex flex-col", className);
|
|
14
|
+
$[0] = className;
|
|
15
|
+
$[1] = t1;
|
|
16
|
+
} else t1 = $[1];
|
|
17
|
+
let t2;
|
|
18
|
+
let t3;
|
|
19
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
20
|
+
t2 = /* @__PURE__ */ jsx("header", {
|
|
21
|
+
className: cn("bg-background flex h-11 min-w-0 shrink-0 items-center justify-center px-3", BOTTOM_CARD_EDGES),
|
|
22
|
+
children: /* @__PURE__ */ jsx("h2", {
|
|
23
|
+
className: "truncate text-sm font-medium",
|
|
24
|
+
children: "Workers"
|
|
25
|
+
})
|
|
26
|
+
});
|
|
27
|
+
t3 = /* @__PURE__ */ jsx("div", {
|
|
28
|
+
className: cn("bg-background text-muted-foreground flex min-h-0 flex-1 items-center justify-center p-4 text-sm", CARD_BODY_EDGES),
|
|
29
|
+
children: "No workers yet"
|
|
30
|
+
});
|
|
31
|
+
$[2] = t2;
|
|
32
|
+
$[3] = t3;
|
|
33
|
+
} else {
|
|
34
|
+
t2 = $[2];
|
|
35
|
+
t3 = $[3];
|
|
36
|
+
}
|
|
37
|
+
let t4;
|
|
38
|
+
if ($[4] !== t1) {
|
|
39
|
+
t4 = /* @__PURE__ */ jsxs("section", {
|
|
40
|
+
"aria-label": "Workers",
|
|
41
|
+
"data-workers-widget": true,
|
|
42
|
+
className: t1,
|
|
43
|
+
children: [t2, t3]
|
|
44
|
+
});
|
|
45
|
+
$[4] = t1;
|
|
46
|
+
$[5] = t4;
|
|
47
|
+
} else t4 = $[5];
|
|
48
|
+
return t4;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
//#endregion
|
|
52
|
+
export { WorkersWidget };
|
|
@@ -9,7 +9,7 @@ const studioStore = createStore({
|
|
|
9
9
|
open: false,
|
|
10
10
|
startRenaming: false
|
|
11
11
|
},
|
|
12
|
-
|
|
12
|
+
isDeleteDraftDialogOpen: false,
|
|
13
13
|
localeDialog: null,
|
|
14
14
|
websiteLocation: null
|
|
15
15
|
},
|
|
@@ -64,16 +64,16 @@ const studioStore = createStore({
|
|
|
64
64
|
}
|
|
65
65
|
};
|
|
66
66
|
},
|
|
67
|
-
|
|
67
|
+
openDeleteDraftDialog: (context) => {
|
|
68
68
|
return {
|
|
69
69
|
...context,
|
|
70
|
-
|
|
70
|
+
isDeleteDraftDialogOpen: true
|
|
71
71
|
};
|
|
72
72
|
},
|
|
73
|
-
|
|
73
|
+
closeDeleteDraftDialog: (context) => {
|
|
74
74
|
return {
|
|
75
75
|
...context,
|
|
76
|
-
|
|
76
|
+
isDeleteDraftDialogOpen: false
|
|
77
77
|
};
|
|
78
78
|
},
|
|
79
79
|
openLocaleDialog: (context, event) => {
|
|
@@ -10,6 +10,7 @@ function withoutExpectedCamoxLogs(onLog) {
|
|
|
10
10
|
function isExpectedCamoxLog(log) {
|
|
11
11
|
if (log.code === "MODULE_LEVEL_DIRECTIVE") return log.message.includes("\"use client\"");
|
|
12
12
|
if (log.code === "INEFFECTIVE_DYNAMIC_IMPORT") return log.message.includes("virtual:camox/app");
|
|
13
|
+
if (log.code === "SOURCEMAP_BROKEN") return log.message.includes("(@tailwindcss/vite:");
|
|
13
14
|
return false;
|
|
14
15
|
}
|
|
15
16
|
|
|
@@ -30,6 +30,8 @@ const VIRTUAL_BLOCK_CHUNKS = "virtual:camox/block-chunks";
|
|
|
30
30
|
const RESOLVED_VIRTUAL_BLOCK_CHUNKS = "\0" + VIRTUAL_BLOCK_CHUNKS;
|
|
31
31
|
const VIRTUAL_APP_STYLESHEET_URL = "virtual:camox/app-stylesheet-url";
|
|
32
32
|
const RESOLVED_VIRTUAL_APP_STYLESHEET_URL = "\0" + VIRTUAL_APP_STYLESHEET_URL;
|
|
33
|
+
const VIRTUAL_APP_STYLESHEET = "virtual:camox/app-stylesheet";
|
|
34
|
+
const RESOLVED_VIRTUAL_APP_STYLESHEET = "\0" + VIRTUAL_APP_STYLESHEET;
|
|
33
35
|
const VIRTUAL_STUDIO_CSS = "virtual:camox-studio-css";
|
|
34
36
|
const RESOLVED_VIRTUAL_STUDIO_CSS = "\0" + VIRTUAL_STUDIO_CSS;
|
|
35
37
|
const VIRTUAL_OVERLAY_CSS = "virtual:camox-overlay-css";
|
|
@@ -197,6 +199,11 @@ function generateVirtualAppStylesheetUrl() {
|
|
|
197
199
|
export default stylesheetUrl;
|
|
198
200
|
`;
|
|
199
201
|
}
|
|
202
|
+
/** The app's compiled stylesheet as text, which page images render with. */
|
|
203
|
+
function generateVirtualAppStylesheet() {
|
|
204
|
+
return `export { default } from "/src/styles.css?inline";
|
|
205
|
+
`;
|
|
206
|
+
}
|
|
200
207
|
function generateVirtualCamoxServer(runtimeBasePath) {
|
|
201
208
|
return `import {
|
|
202
209
|
handleCamoxRequest as handleRuntimeRequest,
|
|
@@ -227,6 +234,8 @@ const options = {
|
|
|
227
234
|
developmentDraft: __CAMOX_DEVELOPMENT_DRAFT__,
|
|
228
235
|
getCamoxApp: async () => camoxApp,
|
|
229
236
|
getDocument: async () => camoxDocument,
|
|
237
|
+
// Loaded by the first page image, so the stylesheet stays out of the Worker's main chunk.
|
|
238
|
+
getImageStylesheet: () => import("virtual:camox/app-stylesheet").then((module) => module.default),
|
|
230
239
|
projectUuid: __CAMOX_PROJECT_ID__,
|
|
231
240
|
renderPage,
|
|
232
241
|
renderStudio,
|
|
@@ -272,6 +281,7 @@ function resolveRuntimeDevId(id, importer) {
|
|
|
272
281
|
if (id === VIRTUAL_RENDERER_CLIENT) return RESOLVED_VIRTUAL_RENDERER_CLIENT;
|
|
273
282
|
if (id === VIRTUAL_RENDERER_CLIENT_URL) return RESOLVED_VIRTUAL_RENDERER_CLIENT_URL;
|
|
274
283
|
if (id === VIRTUAL_APP_STYLESHEET_URL) return RESOLVED_VIRTUAL_APP_STYLESHEET_URL;
|
|
284
|
+
if (id === VIRTUAL_APP_STYLESHEET) return RESOLVED_VIRTUAL_APP_STYLESHEET;
|
|
275
285
|
if (id === VIRTUAL_BLOCK_CHUNKS) return RESOLVED_VIRTUAL_BLOCK_CHUNKS;
|
|
276
286
|
if (id === VIRTUAL_STUDIO_CSS) return RESOLVED_VIRTUAL_STUDIO_CSS;
|
|
277
287
|
if (id === VIRTUAL_OVERLAY_CSS) return RESOLVED_VIRTUAL_OVERLAY_CSS;
|
|
@@ -291,6 +301,7 @@ function loadRuntimeDevModule(id, options = {}) {
|
|
|
291
301
|
if (id === RESOLVED_VIRTUAL_RENDERER_CLIENT) return generateVirtualRendererClient();
|
|
292
302
|
if (id === RESOLVED_VIRTUAL_RENDERER_CLIENT_URL) return generateVirtualRendererClientUrl();
|
|
293
303
|
if (id === RESOLVED_VIRTUAL_APP_STYLESHEET_URL) return generateVirtualAppStylesheetUrl();
|
|
304
|
+
if (id === RESOLVED_VIRTUAL_APP_STYLESHEET) return generateVirtualAppStylesheet();
|
|
294
305
|
if (id === RESOLVED_VIRTUAL_STUDIO_CSS) {
|
|
295
306
|
const cssUrl = `/@fs/${resolve(sdkRoot, "dist/studio.css").replaceAll("\\", "/").replace(/^\/+/, "")}`;
|
|
296
307
|
return `export default ${JSON.stringify(cssUrl)};`;
|
|
@@ -123,7 +123,8 @@ const CAMOX_OPTIMIZED_DEPS = [
|
|
|
123
123
|
"camox > @shikijs/themes/github-dark-high-contrast",
|
|
124
124
|
"camox > @shikijs/themes/github-light",
|
|
125
125
|
"camox > @sinclair/typebox",
|
|
126
|
-
"camox >
|
|
126
|
+
"camox > takumi-js/helpers",
|
|
127
|
+
"camox > takumi-js/response",
|
|
127
128
|
"camox > @tanstack/react-form",
|
|
128
129
|
"camox > @tanstack/react-query",
|
|
129
130
|
"camox > @tanstack/react-router",
|
|
@@ -189,6 +190,7 @@ function camox(options) {
|
|
|
189
190
|
return {
|
|
190
191
|
name: "camox",
|
|
191
192
|
enforce: "pre",
|
|
193
|
+
sharedDuringBuild: true,
|
|
192
194
|
resolveId(id, importer) {
|
|
193
195
|
if (hostedProject) {
|
|
194
196
|
const forbidden = forbiddenImport(hostedProject, id, importer);
|