camox 0.53.1 → 0.54.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/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/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/SelectionEditor.js +136 -110
- package/dist/features/preview/components/SidebarStack.js +112 -83
- package/dist/features/runtime/runtime.d.ts +5 -0
- package/dist/features/runtime/runtime.js +15 -4
- package/dist/features/studio/components/ChatSidebar.js +49 -67
- package/dist/features/studio/components/Squareling.js +114 -0
- package/dist/features/studio/components/ThreadMessages.js +128 -126
- 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/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +5 -5
- package/skills/camox/references/layout-definitions.md +11 -16
- package/dist/features/og/defaultFonts.js +0 -31
- package/dist/features/og/geist-variable-ttf-base64.js +0 -21
|
@@ -5,12 +5,20 @@ import { c } from "react/compiler-runtime";
|
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import * as Tooltip$1 from "@camox/ui/tooltip";
|
|
8
|
+
import { Popover, PopoverContent, PopoverTrigger } from "@camox/ui/popover";
|
|
8
9
|
|
|
9
10
|
//#region src/features/preview/components/SidebarStack.tsx
|
|
10
11
|
/** How much narrower, on each side, the header right behind the front is than the front's. */
|
|
11
12
|
const FIRST_STEP_INSET = 9;
|
|
13
|
+
/**
|
|
14
|
+
* How much each step back shades a card, relative to the step in front of it. The selection
|
|
15
|
+
* path collapses its middle, so the stack stays short and its steps can stay even.
|
|
16
|
+
*/
|
|
17
|
+
const STEP_FALLOFF = .85;
|
|
12
18
|
/** How much each step back narrows a header, relative to the step in front of it. */
|
|
13
|
-
const
|
|
19
|
+
const INSET_FALLOFF = .75;
|
|
20
|
+
/** How much each step back tilts a header, relative to the step in front of it. */
|
|
21
|
+
const TILT_FALLOFF = .65;
|
|
14
22
|
/** How far the header right behind the front leans back, in degrees. */
|
|
15
23
|
const FIRST_STEP_TILT = 4;
|
|
16
24
|
/**
|
|
@@ -22,14 +30,17 @@ const FIRST_STEP_SHADE = 1.2;
|
|
|
22
30
|
const DARK_SHADE_STRENGTH = 2.5;
|
|
23
31
|
/** Keeps a sidebar's cards off its sides, so their edges show. */
|
|
24
32
|
const SIDEBAR_GUTTER = "px-2";
|
|
25
|
-
/** The front card's sides and bottom, drawn just outside it, above the bottom of the sidebar. */
|
|
26
|
-
const CARD_BODY_EDGES = "rounded-b-lg shadow-[-1px_0_0_var(--color-border),1px_0_0_var(--color-border),0_1px_0_var(--color-border)]";
|
|
27
33
|
/**
|
|
28
|
-
* The
|
|
29
|
-
*
|
|
30
|
-
* past each side to meet the sides below, keeps the edge even around the rounded corners.
|
|
34
|
+
* The color of a card's edges: the border's, solid. Dark mode's border is translucent, so it's
|
|
35
|
+
* laid over the Canvas behind the sidebars, to look the same over the card as beside it.
|
|
31
36
|
*/
|
|
32
|
-
const
|
|
37
|
+
const CARD_EDGE_COLOR = "border-border dark:border-[color-mix(in_srgb,var(--color-muted),white_10%)]";
|
|
38
|
+
/** The front card's sides and bottom, under its header. */
|
|
39
|
+
const CARD_BODY_EDGES = `rounded-b-lg border border-t-0 ${CARD_EDGE_COLOR}`;
|
|
40
|
+
/** The bottom card's top and sides, as it meets the top of a sidebar. */
|
|
41
|
+
const BOTTOM_CARD_EDGES = `rounded-t-lg border border-b-0 ${CARD_EDGE_COLOR}`;
|
|
42
|
+
/** The front card's top and sides, over the cards behind it. */
|
|
43
|
+
const FRONT_CARD_EDGES = `border border-b-0 ${CARD_EDGE_COLOR}`;
|
|
33
44
|
/**
|
|
34
45
|
* How much the second card behind the front fades its name, which shows depth on dark
|
|
35
46
|
* backgrounds too. The card right behind the front doesn't fade.
|
|
@@ -38,12 +49,12 @@ const FIRST_STEP_FADE = .05;
|
|
|
38
49
|
/** How far away the eye is from the stack, in px: the less, the stronger the depth. */
|
|
39
50
|
const PERSPECTIVE = 900;
|
|
40
51
|
/** Sums the steps of a falloff series, `distance` views behind the front. */
|
|
41
|
-
function stepSeries(first, distance) {
|
|
42
|
-
return first * (1 -
|
|
52
|
+
function stepSeries(first, distance, falloff = STEP_FALLOFF) {
|
|
53
|
+
return first * (1 - falloff ** distance) / (1 - falloff);
|
|
43
54
|
}
|
|
44
55
|
/** A header's inset on each side, `distance` views behind the front. */
|
|
45
56
|
function stackInset(distance) {
|
|
46
|
-
return stepSeries(FIRST_STEP_INSET, distance);
|
|
57
|
+
return stepSeries(FIRST_STEP_INSET, distance, INSET_FALLOFF);
|
|
47
58
|
}
|
|
48
59
|
/** Cards settle into place, without bouncing. */
|
|
49
60
|
const EASE = "cubic-bezier(0.2, 0, 0, 1)";
|
|
@@ -100,7 +111,10 @@ const GOING = {
|
|
|
100
111
|
},
|
|
101
112
|
PULLED
|
|
102
113
|
],
|
|
103
|
-
back: [PLACED,
|
|
114
|
+
back: [PLACED, {
|
|
115
|
+
...BEHIND,
|
|
116
|
+
opacity: 0
|
|
117
|
+
}],
|
|
104
118
|
same: [{ opacity: 1 }, { opacity: 0 }]
|
|
105
119
|
};
|
|
106
120
|
const GOING_TIMING = {
|
|
@@ -338,7 +352,7 @@ function SidebarStackView(t0) {
|
|
|
338
352
|
const { depth, className, children } = t0;
|
|
339
353
|
const ref = React.useRef(null);
|
|
340
354
|
useStackCard(ref, depth, true);
|
|
341
|
-
const t1 = React.useContext(StackMotionContext) != null && "rounded-b-lg
|
|
355
|
+
const t1 = React.useContext(StackMotionContext) != null && "rounded-b-lg border border-t-0 border-border dark:border-[color-mix(in_srgb,var(--color-muted),white_10%)]";
|
|
342
356
|
let t2;
|
|
343
357
|
if ($[0] !== className || $[1] !== t1) {
|
|
344
358
|
t2 = cn("bg-background min-h-0 flex-1 origin-top", t1, className);
|
|
@@ -360,8 +374,8 @@ function SidebarStackView(t0) {
|
|
|
360
374
|
return t3;
|
|
361
375
|
}
|
|
362
376
|
function SidebarStackHeader(t0) {
|
|
363
|
-
const $ = c(
|
|
364
|
-
const { depth, distance: t1, first: t2, onSelect, hoverTarget, tooltip, children } = t0;
|
|
377
|
+
const $ = c(55);
|
|
378
|
+
const { depth, distance: t1, first: t2, onSelect, hoverTarget, tooltip, popover, children } = t0;
|
|
365
379
|
const distance = t1 === void 0 ? 0 : t1;
|
|
366
380
|
const first = t2 === void 0 ? false : t2;
|
|
367
381
|
const covered = distance > 0;
|
|
@@ -397,12 +411,13 @@ function SidebarStackHeader(t0) {
|
|
|
397
411
|
React.useEffect(t4, t5);
|
|
398
412
|
const ref = React.useRef(null);
|
|
399
413
|
useStackCard(ref, depth, false);
|
|
400
|
-
const
|
|
414
|
+
const [popoverOpen, setPopoverOpen] = React.useState(false);
|
|
415
|
+
const liftable = covered && (onSelect != null || popover != null);
|
|
401
416
|
const inStack = React.useContext(StackMotionContext) != null;
|
|
402
417
|
const flat = first && !covered && !inStack;
|
|
403
418
|
let t6;
|
|
404
419
|
if ($[8] !== covered || $[9] !== distance) {
|
|
405
|
-
t6 = covered ? stepSeries(FIRST_STEP_TILT, distance) : 0;
|
|
420
|
+
t6 = covered ? stepSeries(FIRST_STEP_TILT, distance, TILT_FALLOFF) : 0;
|
|
406
421
|
$[8] = covered;
|
|
407
422
|
$[9] = distance;
|
|
408
423
|
$[10] = t6;
|
|
@@ -419,12 +434,12 @@ function SidebarStackHeader(t0) {
|
|
|
419
434
|
if ($[13] !== children || $[14] !== liftable || $[15] !== onSelect) {
|
|
420
435
|
t8 = liftable ? /* @__PURE__ */ jsx("button", {
|
|
421
436
|
type: "button",
|
|
422
|
-
className: "hover:text-foreground flex h-full w-full min-w-0 cursor-pointer items-center justify-center rounded-[inherit] px-3 text-center text-(--ancestor-foreground) transition-colors focus-visible:outline-none",
|
|
437
|
+
className: "hover:text-foreground data-popup-open:text-foreground flex h-full w-full min-w-0 cursor-pointer items-center justify-center rounded-[inherit] px-3 text-center text-(--ancestor-foreground) transition-colors focus-visible:outline-none",
|
|
423
438
|
onMouseEnter: () => setHovered(true),
|
|
424
439
|
onMouseLeave: () => setHovered(false),
|
|
425
440
|
onClick: () => {
|
|
426
441
|
setHovered(false);
|
|
427
|
-
onSelect();
|
|
442
|
+
onSelect?.();
|
|
428
443
|
},
|
|
429
444
|
children: /* @__PURE__ */ jsx("span", {
|
|
430
445
|
className: "truncate opacity-(--fade) transition-opacity",
|
|
@@ -446,14 +461,15 @@ function SidebarStackHeader(t0) {
|
|
|
446
461
|
} else t10 = $[18];
|
|
447
462
|
const t11 = !flat && !first && "rounded-t-sm";
|
|
448
463
|
const t12 = covered ? "h-[38px] pb-1" : "h-11 px-3";
|
|
449
|
-
const t13 = first && !flat && "
|
|
450
|
-
const t14 = covered && !first &&
|
|
451
|
-
const t15 = !covered && !first && (inStack ?
|
|
464
|
+
const t13 = first && !flat && "rounded-t-lg border border-b-0 border-border dark:border-[color-mix(in_srgb,var(--color-muted),white_10%)]";
|
|
465
|
+
const t14 = covered && !first && `border ${CARD_EDGE_COLOR} shadow-[0_-2px_5px_-3px_rgb(0_0_0/0.08)] dark:shadow-[0_-2px_5px_-3px_rgb(0_0_0/0.4)]`;
|
|
466
|
+
const t15 = !covered && !first && (inStack ? `${FRONT_CARD_EDGES} shadow-[0_-3px_8px_-4px_rgb(0_0_0/0.08)] dark:shadow-[0_-3px_8px_-4px_rgb(0_0_0/0.4)]` : `border-t ${CARD_EDGE_COLOR} shadow-[0_-3px_8px_-4px_rgb(0_0_0/0.08)] dark:shadow-[0_-3px_8px_-4px_rgb(0_0_0/0.4)]`);
|
|
452
467
|
const t16 = liftable && "hover:[--fade:1] hover:[--lift:var(--hover-lift)] hover:[--shade:var(--hover-shade)] hover:[--tilt:var(--hover-tilt)]";
|
|
453
468
|
const t17 = liftable && "has-focus-visible:[--fade:1] has-focus-visible:[--lift:var(--hover-lift)] has-focus-visible:[--shade:var(--hover-shade)] has-focus-visible:[--tilt:var(--hover-tilt)]";
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
469
|
+
const t18 = liftable && "has-data-popup-open:[--fade:1] has-data-popup-open:[--lift:var(--hover-lift)] has-data-popup-open:[--shade:var(--hover-shade)] has-data-popup-open:[--tilt:var(--hover-tilt)]";
|
|
470
|
+
let t19;
|
|
471
|
+
if ($[19] !== t11 || $[20] !== t12 || $[21] !== t13 || $[22] !== t14 || $[23] !== t15 || $[24] !== t16 || $[25] !== t17 || $[26] !== t18) {
|
|
472
|
+
t19 = cn("relative flex min-w-0 items-center justify-center text-center text-sm", t11, "[--ancestor-foreground:color-mix(in_oklab,var(--color-muted-foreground),var(--color-foreground)_40%)]", "[--fade:var(--rest-fade)] [--lift:0px] [--shade:var(--rest-shade)] [--tilt:var(--rest-tilt)]", "[--shade-color:black] [--shade-strength:1] dark:[--shade-color:white] dark:[--shade-strength:var(--dark-shade-strength)]", "origin-bottom [backface-visibility:hidden] motion-reduce:transition-none!", t12, t13, t14, t15, t16, t17, t18);
|
|
457
473
|
$[19] = t11;
|
|
458
474
|
$[20] = t12;
|
|
459
475
|
$[21] = t13;
|
|
@@ -462,91 +478,104 @@ function SidebarStackHeader(t0) {
|
|
|
462
478
|
$[24] = t16;
|
|
463
479
|
$[25] = t17;
|
|
464
480
|
$[26] = t18;
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
const t20 = `${tilt
|
|
468
|
-
const t21 = `${
|
|
469
|
-
const t22 =
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
481
|
+
$[27] = t19;
|
|
482
|
+
} else t19 = $[27];
|
|
483
|
+
const t20 = `${tilt}deg`;
|
|
484
|
+
const t21 = `${tilt / 2}deg`;
|
|
485
|
+
const t22 = `${shade}%`;
|
|
486
|
+
const t23 = Math.max(0, distance - 1);
|
|
487
|
+
let t24;
|
|
488
|
+
if ($[28] !== t23) {
|
|
489
|
+
t24 = stepSeries(FIRST_STEP_SHADE, t23);
|
|
474
490
|
$[28] = t23;
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
const t25 = `${
|
|
478
|
-
const t26 =
|
|
479
|
-
|
|
480
|
-
if ($[29] !== covered || $[30] !== distance) {
|
|
481
|
-
t27 = covered ? stackInset(distance) : void 0;
|
|
482
|
-
$[29] = covered;
|
|
483
|
-
$[30] = distance;
|
|
484
|
-
$[31] = t27;
|
|
485
|
-
} else t27 = $[31];
|
|
491
|
+
$[29] = t24;
|
|
492
|
+
} else t24 = $[29];
|
|
493
|
+
const t25 = `${t24}%`;
|
|
494
|
+
const t26 = `${first ? 0 : -1.5}px`;
|
|
495
|
+
const t27 = covered ? 1 - stepSeries(FIRST_STEP_FADE, distance - 1) : 1;
|
|
486
496
|
let t28;
|
|
487
|
-
if ($[
|
|
488
|
-
t28 =
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
497
|
+
if ($[30] !== covered || $[31] !== distance) {
|
|
498
|
+
t28 = covered ? stackInset(distance) : void 0;
|
|
499
|
+
$[30] = covered;
|
|
500
|
+
$[31] = distance;
|
|
501
|
+
$[32] = t28;
|
|
502
|
+
} else t28 = $[32];
|
|
503
|
+
let t29;
|
|
504
|
+
if ($[33] !== t20 || $[34] !== t21 || $[35] !== t22 || $[36] !== t25 || $[37] !== t26 || $[38] !== t27 || $[39] !== t28) {
|
|
505
|
+
t29 = {
|
|
506
|
+
"--rest-tilt": t20,
|
|
507
|
+
"--hover-tilt": t21,
|
|
508
|
+
"--rest-shade": t22,
|
|
492
509
|
"--dark-shade-strength": DARK_SHADE_STRENGTH,
|
|
493
|
-
"--hover-shade":
|
|
494
|
-
"--hover-lift":
|
|
495
|
-
"--rest-fade":
|
|
496
|
-
marginInline:
|
|
510
|
+
"--hover-shade": t25,
|
|
511
|
+
"--hover-lift": t26,
|
|
512
|
+
"--rest-fade": t27,
|
|
513
|
+
marginInline: t28,
|
|
497
514
|
transform: `perspective(${PERSPECTIVE}px) translateY(var(--lift)) rotateX(var(--tilt))`,
|
|
498
515
|
backgroundColor: "color-mix(in oklab, var(--color-background), var(--shade-color) calc(var(--shade) * var(--shade-strength)))",
|
|
499
516
|
transition: HEADER_TRANSITION
|
|
500
517
|
};
|
|
501
|
-
$[32] = t19;
|
|
502
518
|
$[33] = t20;
|
|
503
519
|
$[34] = t21;
|
|
504
|
-
$[35] =
|
|
520
|
+
$[35] = t22;
|
|
505
521
|
$[36] = t25;
|
|
506
522
|
$[37] = t26;
|
|
507
523
|
$[38] = t27;
|
|
508
524
|
$[39] = t28;
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
525
|
+
$[40] = t29;
|
|
526
|
+
} else t29 = $[40];
|
|
527
|
+
const t30 = t29;
|
|
528
|
+
let t31;
|
|
529
|
+
if ($[41] !== button || $[42] !== children || $[43] !== covered || $[44] !== popover || $[45] !== popoverOpen || $[46] !== tooltip) {
|
|
530
|
+
t31 = button && popover ? /* @__PURE__ */ jsxs(Popover, {
|
|
531
|
+
open: popoverOpen,
|
|
532
|
+
onOpenChange: setPopoverOpen,
|
|
533
|
+
children: [/* @__PURE__ */ jsx(PopoverTrigger, { render: button }), /* @__PURE__ */ jsx(PopoverContent, {
|
|
534
|
+
side: "bottom",
|
|
535
|
+
sideOffset: 8,
|
|
536
|
+
className: "w-48 gap-0 p-1",
|
|
537
|
+
onClick: () => setPopoverOpen(false),
|
|
538
|
+
children: popover
|
|
539
|
+
})]
|
|
540
|
+
}) : button && tooltip ? /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [/* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, { render: button }), /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, {
|
|
514
541
|
side: "bottom",
|
|
515
542
|
children: tooltip
|
|
516
543
|
})] }) : button ?? (covered ? /* @__PURE__ */ jsx("span", {
|
|
517
544
|
className: "truncate px-3 text-(--ancestor-foreground) opacity-(--fade)",
|
|
518
545
|
children
|
|
519
546
|
}) : children);
|
|
520
|
-
$[
|
|
521
|
-
$[
|
|
522
|
-
$[
|
|
523
|
-
$[
|
|
524
|
-
$[
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
t31 = /* @__PURE__ */ jsx("div", {
|
|
529
|
-
className: t18,
|
|
530
|
-
style: t29,
|
|
531
|
-
children: t30
|
|
532
|
-
});
|
|
533
|
-
$[45] = t18;
|
|
534
|
-
$[46] = t29;
|
|
535
|
-
$[47] = t30;
|
|
536
|
-
$[48] = t31;
|
|
537
|
-
} else t31 = $[48];
|
|
547
|
+
$[41] = button;
|
|
548
|
+
$[42] = children;
|
|
549
|
+
$[43] = covered;
|
|
550
|
+
$[44] = popover;
|
|
551
|
+
$[45] = popoverOpen;
|
|
552
|
+
$[46] = tooltip;
|
|
553
|
+
$[47] = t31;
|
|
554
|
+
} else t31 = $[47];
|
|
538
555
|
let t32;
|
|
539
|
-
if ($[49] !==
|
|
556
|
+
if ($[48] !== t19 || $[49] !== t30 || $[50] !== t31) {
|
|
540
557
|
t32 = /* @__PURE__ */ jsx("div", {
|
|
541
|
-
|
|
542
|
-
|
|
558
|
+
className: t19,
|
|
559
|
+
style: t30,
|
|
543
560
|
children: t31
|
|
544
561
|
});
|
|
545
|
-
$[
|
|
562
|
+
$[48] = t19;
|
|
563
|
+
$[49] = t30;
|
|
546
564
|
$[50] = t31;
|
|
547
565
|
$[51] = t32;
|
|
548
566
|
} else t32 = $[51];
|
|
549
|
-
|
|
567
|
+
let t33;
|
|
568
|
+
if ($[52] !== t10 || $[53] !== t32) {
|
|
569
|
+
t33 = /* @__PURE__ */ jsx("div", {
|
|
570
|
+
ref,
|
|
571
|
+
className: t10,
|
|
572
|
+
children: t32
|
|
573
|
+
});
|
|
574
|
+
$[52] = t10;
|
|
575
|
+
$[53] = t32;
|
|
576
|
+
$[54] = t33;
|
|
577
|
+
} else t33 = $[54];
|
|
578
|
+
return t33;
|
|
550
579
|
}
|
|
551
580
|
|
|
552
581
|
//#endregion
|
|
@@ -93,6 +93,11 @@ export interface RuntimeOptions {
|
|
|
93
93
|
rendererClientEntryUrl?: string;
|
|
94
94
|
getCamoxApp?: () => Promise<CamoxApp>;
|
|
95
95
|
getDocument?: () => Promise<CamoxDocument>;
|
|
96
|
+
/**
|
|
97
|
+
* The app's stylesheet, compiled, which page images render with: a `toImage` styles its
|
|
98
|
+
* elements with the same classes as the site.
|
|
99
|
+
*/
|
|
100
|
+
getImageStylesheet?: () => Promise<string>;
|
|
96
101
|
projectUuid?: string;
|
|
97
102
|
renderPage?: (input: PageRenderInput) => Promise<string>;
|
|
98
103
|
renderStudio?: (input: StudioRenderInput) => Promise<string>;
|
|
@@ -14,6 +14,7 @@ import { discoverLayoutPages, matchDerivedLayout } from "../../core/derivedRoute
|
|
|
14
14
|
import { buildLayoutContext, curatedLayoutContext } from "../../core/layoutContext.js";
|
|
15
15
|
import { buildCamoxPageHead, buildFaviconUrl, buildPageHead, buildPageMeta, createServerApiClient, createServerStudioCache, curatedMarkdownResponse, declarePage, isNotFoundError, loadCamoxPageForRequest, parseMarkdownPath, prefersMarkdown, readDraftOrLive, readPageMarkdown, readScopeLocales, renderedHref, resolveMemberProject, withFrontMatter } from "../routes/pageRuntime.js";
|
|
16
16
|
import { assetPrefix } from "./assetPrefix.js";
|
|
17
|
+
import { documentGoogleFonts } from "../og/documentFonts.js";
|
|
17
18
|
import { alternatesByPage, findAlternates, hreflangLinks } from "./alternates.js";
|
|
18
19
|
import { configuredProviders, renderAnalyticsScripts } from "./analytics.js";
|
|
19
20
|
import { omitArtifactSources } from "./artifactSources.js";
|
|
@@ -294,16 +295,26 @@ async function createRoutesResponse(request, options) {
|
|
|
294
295
|
}
|
|
295
296
|
/**
|
|
296
297
|
* The image of the page `/og?path=` names, by its path with its locale's prefix: its layout's
|
|
297
|
-
* `toImage`, or Camox's default image, rendered with the page's context
|
|
298
|
-
* one, read as the page itself would be, in the draft
|
|
298
|
+
* `toImage`, or Camox's default image, rendered with the page's context and the site's
|
|
299
|
+
* stylesheet and fonts. Only real pages have one, read as the page itself would be, in the draft
|
|
300
|
+
* the URL names for a member.
|
|
299
301
|
*/
|
|
300
302
|
async function createOgResponse(request, options) {
|
|
301
303
|
const camoxApp = await options.getCamoxApp?.();
|
|
302
304
|
if (!camoxApp) return Response.json({ message: "Camox app registry is not available." }, { status: 500 });
|
|
303
305
|
const source = await readPageImageSource(request, options, camoxApp);
|
|
304
306
|
if (!source) return new Response("Not found", { status: 404 });
|
|
307
|
+
const [css, document] = await Promise.all([options.getImageStylesheet?.(), options.getDocument?.()]);
|
|
308
|
+
const style = {
|
|
309
|
+
css,
|
|
310
|
+
fonts: documentGoogleFonts(document ?? {})
|
|
311
|
+
};
|
|
305
312
|
const headers = {
|
|
306
|
-
ETag: await etagOf(JSON.stringify([
|
|
313
|
+
ETag: await etagOf(JSON.stringify([
|
|
314
|
+
source.layout?.id ?? null,
|
|
315
|
+
source.context,
|
|
316
|
+
style
|
|
317
|
+
])),
|
|
307
318
|
"Cache-Control": isPrivateRender(request, options) ? "private, no-store" : "public, no-cache"
|
|
308
319
|
};
|
|
309
320
|
if (namesEtag(request, headers.ETag)) return new Response(null, {
|
|
@@ -311,7 +322,7 @@ async function createOgResponse(request, options) {
|
|
|
311
322
|
headers
|
|
312
323
|
});
|
|
313
324
|
const toImage = source.layout?.toImage ?? DefaultPageImage;
|
|
314
|
-
const image = await renderPageImage(toImage(source.context));
|
|
325
|
+
const image = await renderPageImage(toImage(source.context), style);
|
|
315
326
|
for (const [name, value] of Object.entries(headers)) image.headers.set(name, value);
|
|
316
327
|
return image;
|
|
317
328
|
}
|
|
@@ -7,6 +7,7 @@ import { BOTTOM_CARD_EDGES, CARD_BODY_EDGES, SIDEBAR_GUTTER } from "../../previe
|
|
|
7
7
|
import { draftLabel } from "../draftLabel.js";
|
|
8
8
|
import { FollowAgentContext } from "../followAgentContext.js";
|
|
9
9
|
import { useThread } from "../../../lib/use-thread.js";
|
|
10
|
+
import { Squareling } from "./Squareling.js";
|
|
10
11
|
import { ThreadComposer } from "./ThreadComposer.js";
|
|
11
12
|
import { ThreadMessages } from "./ThreadMessages.js";
|
|
12
13
|
import { c } from "react/compiler-runtime";
|
|
@@ -34,9 +35,12 @@ function ChatSidebar(t0) {
|
|
|
34
35
|
t3 = { width: 265 };
|
|
35
36
|
t4 = /* @__PURE__ */ jsxs("header", {
|
|
36
37
|
className: cn("bg-background flex h-11 min-w-0 shrink-0 items-center justify-center gap-2 px-3", BOTTOM_CARD_EDGES),
|
|
37
|
-
children: [/* @__PURE__ */ jsx(
|
|
38
|
+
children: [/* @__PURE__ */ jsx(Squareling, {
|
|
39
|
+
status: "idle",
|
|
40
|
+
className: "size-5"
|
|
41
|
+
}), /* @__PURE__ */ jsx("h2", {
|
|
38
42
|
className: "truncate text-sm font-medium",
|
|
39
|
-
children: "
|
|
43
|
+
children: "Agent"
|
|
40
44
|
})]
|
|
41
45
|
});
|
|
42
46
|
t5 = /* @__PURE__ */ jsx("div", {
|
|
@@ -56,7 +60,7 @@ function ChatSidebar(t0) {
|
|
|
56
60
|
let t6;
|
|
57
61
|
if ($[4] !== hidden) {
|
|
58
62
|
t6 = /* @__PURE__ */ jsxs("aside", {
|
|
59
|
-
"aria-label": "
|
|
63
|
+
"aria-label": "Agent",
|
|
60
64
|
"data-chat-sidebar": true,
|
|
61
65
|
hidden,
|
|
62
66
|
className: t2,
|
|
@@ -68,25 +72,6 @@ function ChatSidebar(t0) {
|
|
|
68
72
|
} else t6 = $[5];
|
|
69
73
|
return t6;
|
|
70
74
|
}
|
|
71
|
-
/** Camox's logo, beside the heading: the agent is Camox. */
|
|
72
|
-
function CamoxMark() {
|
|
73
|
-
const $ = c(1);
|
|
74
|
-
let t0;
|
|
75
|
-
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
76
|
-
t0 = /* @__PURE__ */ jsx("svg", {
|
|
77
|
-
"aria-hidden": true,
|
|
78
|
-
viewBox: "0 0 191.03 132",
|
|
79
|
-
className: "size-5 shrink-0",
|
|
80
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
81
|
-
children: /* @__PURE__ */ jsx("path", {
|
|
82
|
-
d: "M0 22.55A22.55 22.55 0 0 1 22.55 0L90.19 0A5.32 5.32 0 0 1 95.52 5.32L95.52 36.48L36.48 36.48L36.48 95.52L5.32 95.52A5.32 5.32 0 0 1 0 90.19ZM95.52 36.48L181.48 36.48A5.32 5.32 0 0 1 186.01 44.61L138.61 121.31A22.55 22.55 0 0 1 119.43 132L41.81 132A5.32 5.32 0 0 1 36.48 126.68L36.48 95.52L95.52 95.52Z",
|
|
83
|
-
fill: "#00BC7D"
|
|
84
|
-
})
|
|
85
|
-
});
|
|
86
|
-
$[0] = t0;
|
|
87
|
-
} else t0 = $[0];
|
|
88
|
-
return t0;
|
|
89
|
-
}
|
|
90
75
|
function CurrentThread() {
|
|
91
76
|
const $ = c(15);
|
|
92
77
|
const { apiUrl, projectUuid } = React.useContext(AuthContext);
|
|
@@ -164,7 +149,7 @@ function CurrentThread() {
|
|
|
164
149
|
return t6;
|
|
165
150
|
}
|
|
166
151
|
function Thread(t0) {
|
|
167
|
-
const $ = c(
|
|
152
|
+
const $ = c(30);
|
|
168
153
|
const { apiUrl, projectId, draftId, carried, onEnterDraft } = t0;
|
|
169
154
|
let t1;
|
|
170
155
|
if ($[0] !== carried || $[1] !== onEnterDraft) {
|
|
@@ -212,68 +197,65 @@ function Thread(t0) {
|
|
|
212
197
|
$[12] = t5;
|
|
213
198
|
} else t5 = $[12];
|
|
214
199
|
const sendFollowing = t5;
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
t7 = {
|
|
200
|
+
let t6;
|
|
201
|
+
if ($[13] !== sending || $[14] !== view) {
|
|
202
|
+
t6 = {
|
|
219
203
|
view,
|
|
220
|
-
sending
|
|
221
|
-
showSenders: t6
|
|
204
|
+
sending
|
|
222
205
|
};
|
|
223
206
|
$[13] = sending;
|
|
224
|
-
$[14] =
|
|
225
|
-
$[15] =
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const messages = t7;
|
|
207
|
+
$[14] = view;
|
|
208
|
+
$[15] = t6;
|
|
209
|
+
} else t6 = $[15];
|
|
210
|
+
const messages = t6;
|
|
229
211
|
const continuedIn = draftId === null ? view.continuedIn?.draftId : void 0;
|
|
230
|
-
let
|
|
231
|
-
if ($[
|
|
232
|
-
|
|
212
|
+
let t7;
|
|
213
|
+
if ($[16] !== continuedIn || $[17] !== messages || $[18] !== projectId) {
|
|
214
|
+
t7 = continuedIn ? /* @__PURE__ */ jsx(ContinuedInMessages, {
|
|
233
215
|
...messages,
|
|
234
216
|
projectId,
|
|
235
217
|
draftId: continuedIn
|
|
236
218
|
}) : /* @__PURE__ */ jsx(ThreadMessages, { ...messages });
|
|
237
|
-
$[
|
|
238
|
-
$[
|
|
239
|
-
$[
|
|
240
|
-
$[
|
|
241
|
-
} else
|
|
242
|
-
let
|
|
243
|
-
if ($[
|
|
244
|
-
|
|
219
|
+
$[16] = continuedIn;
|
|
220
|
+
$[17] = messages;
|
|
221
|
+
$[18] = projectId;
|
|
222
|
+
$[19] = t7;
|
|
223
|
+
} else t7 = $[19];
|
|
224
|
+
let t8;
|
|
225
|
+
if ($[20] !== error) {
|
|
226
|
+
t8 = error && /* @__PURE__ */ jsx("p", {
|
|
245
227
|
role: "alert",
|
|
246
228
|
className: "text-destructive px-2 pt-2 text-sm",
|
|
247
229
|
children: error
|
|
248
230
|
});
|
|
249
|
-
$[
|
|
250
|
-
$[
|
|
251
|
-
} else
|
|
252
|
-
let
|
|
253
|
-
if ($[
|
|
254
|
-
|
|
231
|
+
$[20] = error;
|
|
232
|
+
$[21] = t8;
|
|
233
|
+
} else t8 = $[21];
|
|
234
|
+
let t9;
|
|
235
|
+
if ($[22] !== sendFollowing || $[23] !== stop || $[24] !== view.running) {
|
|
236
|
+
t9 = /* @__PURE__ */ jsx(ThreadComposer, {
|
|
255
237
|
onSend: sendFollowing,
|
|
256
238
|
onStop: stop,
|
|
257
239
|
running: view.running
|
|
258
240
|
});
|
|
259
|
-
$[
|
|
260
|
-
$[
|
|
261
|
-
$[
|
|
262
|
-
$[
|
|
263
|
-
} else
|
|
264
|
-
let
|
|
265
|
-
if ($[
|
|
266
|
-
|
|
241
|
+
$[22] = sendFollowing;
|
|
242
|
+
$[23] = stop;
|
|
243
|
+
$[24] = view.running;
|
|
244
|
+
$[25] = t9;
|
|
245
|
+
} else t9 = $[25];
|
|
246
|
+
let t10;
|
|
247
|
+
if ($[26] !== t7 || $[27] !== t8 || $[28] !== t9) {
|
|
248
|
+
t10 = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
249
|
+
t7,
|
|
267
250
|
t8,
|
|
268
|
-
t9
|
|
269
|
-
t10
|
|
251
|
+
t9
|
|
270
252
|
] });
|
|
271
|
-
$[
|
|
272
|
-
$[
|
|
273
|
-
$[
|
|
274
|
-
$[
|
|
275
|
-
} else
|
|
276
|
-
return
|
|
253
|
+
$[26] = t7;
|
|
254
|
+
$[27] = t8;
|
|
255
|
+
$[28] = t9;
|
|
256
|
+
$[29] = t10;
|
|
257
|
+
} else t10 = $[29];
|
|
258
|
+
return t10;
|
|
277
259
|
}
|
|
278
260
|
/**
|
|
279
261
|
* A fresh Live thread's messages, linking to the draft the editor's previous one continued in,
|
|
@@ -0,0 +1,114 @@
|
|
|
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(17);
|
|
13
|
+
const { status, className } = 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] !== status || $[14] !== t1 || $[15] !== t6) {
|
|
98
|
+
t7 = /* @__PURE__ */ jsx("svg", {
|
|
99
|
+
viewBox: "0 0 100 100",
|
|
100
|
+
"aria-hidden": true,
|
|
101
|
+
"data-squareling": status,
|
|
102
|
+
className: t1,
|
|
103
|
+
children: t6
|
|
104
|
+
});
|
|
105
|
+
$[13] = status;
|
|
106
|
+
$[14] = t1;
|
|
107
|
+
$[15] = t6;
|
|
108
|
+
$[16] = t7;
|
|
109
|
+
} else t7 = $[16];
|
|
110
|
+
return t7;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
//#endregion
|
|
114
|
+
export { Squareling };
|