camox 0.69.0 → 0.72.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/core/createApp.d.ts +4 -103
- package/dist/core/createApp.js +3 -24
- package/dist/core/createBlock.d.ts +2 -2
- package/dist/core/createBlock.js +55 -192
- package/dist/core/createLayout.d.ts +6 -77
- package/dist/core/createLayout.js +12 -50
- package/dist/core/editing/createEditableBlock.d.ts +9 -75
- package/dist/core/editing/createEditableBlock.js +258 -640
- package/dist/core/hooks/useArtifactHost.js +56 -46
- package/dist/core/hooks/useIsEditable.js +2 -2
- package/dist/core/lib/artifact.d.ts +4 -0
- package/dist/core/lib/artifactData.js +8 -3
- package/dist/core/lib/artifactHost.js +40 -0
- package/dist/core/lib/artifactRuntime.js +20 -1
- package/dist/core/lib/contentType.d.ts +23 -38
- package/dist/core/lib/contentType.js +34 -62
- package/dist/core/lib/iconTypes.d.ts +0 -3
- package/dist/core/lib/icons.js +63 -51
- package/dist/core/lib/recordScope.js +1 -1
- package/dist/features/canvas/CanvasOverlays.js +94 -176
- package/dist/features/canvas/CanvasPageFrame.js +62 -68
- package/dist/features/canvas/CanvasPreviewPageSlot.js +1 -3
- package/dist/features/canvas/canvasOverlayGeometry.js +1 -7
- package/dist/features/canvas/sidebar/CuratedPageInspector.js +3 -21
- package/dist/features/canvas/sidebar/LayoutPageBlocks.js +1 -2
- package/dist/features/canvas/useCanvasCamera.js +1 -1
- package/dist/features/canvas/useCanvasFrame.js +1 -1
- package/dist/features/content/ContentCollection.js +2 -2
- package/dist/features/content/collection-form.js +6 -7
- package/dist/features/page/CuratedPageContent.js +15 -24
- package/dist/features/page/UnplacedBlockContent.js +1 -6
- package/dist/features/preview/CamoxPreview.js +30 -33
- package/dist/features/preview/EditablePageContent.js +131 -151
- package/dist/features/preview/components/BlockActionsPopover.js +43 -152
- package/dist/features/preview/components/CanvasPreview.js +2 -2
- package/dist/features/preview/components/Frame.js +3 -3
- package/dist/features/preview/components/IconFieldEditor.js +1 -1
- package/dist/features/preview/components/ItemFieldsEditor.js +1 -3
- package/dist/features/preview/components/Overlays.js +18 -84
- package/dist/features/preview/components/PageTree.js +57 -103
- package/dist/features/preview/components/PreviewPanel.js +8 -11
- package/dist/features/preview/components/RecordCombobox.js +65 -78
- package/dist/features/preview/components/ReferenceFieldEditor.js +1 -19
- package/dist/features/preview/components/ReferenceListFieldEditor.js +1 -19
- package/dist/features/preview/components/RemovedBlockPlaceholder.js +2 -2
- package/dist/features/preview/components/SelectionEditor.js +5 -4
- package/dist/features/preview/components/useRepeatableItemActions.js +18 -24
- package/dist/features/preview/components/useUpdateBlockPosition.js +1 -1
- package/dist/features/preview/overlayMessages.js +1 -4
- package/dist/features/preview/previewStore.js +3 -23
- package/dist/features/renderer/RendererApp.js +17 -141
- package/dist/features/renderer/definitionAnswers.js +1 -8
- package/dist/features/renderer/rendererHost.js +1 -31
- package/dist/features/renderer/studioConnection.js +1 -25
- package/dist/features/runtime/pageApp.js +8 -4
- package/dist/features/runtime/runtime.js +3 -3
- package/dist/features/studio/agentRunToast.js +71 -0
- package/dist/features/studio/components/ChatWidget.js +2 -0
- package/dist/features/studio/components/DraftBar.js +2 -3
- package/dist/features/studio/components/DraftsControl.js +150 -176
- package/dist/features/studio/components/ReviewDraftSheet.js +344 -548
- package/dist/features/studio/components/ThreadMessages.js +89 -22
- package/dist/features/studio/draftLabel.js +1 -1
- package/dist/features/studio/studioStore.js +5 -17
- package/dist/features/studio/viewSwitch.js +2 -4
- package/dist/features/vite/blockBoilerplate.js +1 -1
- package/dist/features/vite/definitionsSync.js +1 -8
- package/dist/lib/queries.js +0 -1
- package/dist/lib/studio-definitions.js +0 -2
- package/dist/lib/studio-reads.js +0 -5
- package/dist/lib/use-thread.js +196 -138
- package/dist/package.js +1 -1
- package/dist/studio-overlays.css +0 -29
- package/dist/studio.css +1 -1
- package/package.json +6 -4
- package/skills/camox/SKILL.md +1 -1
- package/skills/camox/references/artifacts.md +89 -5
- package/skills/camox/references/block-definitions.md +21 -25
- package/skills/camox/references/dom-integrations.md +1 -1
- package/skills/camox/references/layout-definitions.md +3 -12
- package/skills/camox/references/routed-layouts.md +2 -2
- package/skills/camox-expand/SKILL.md +5 -5
- package/skills/camoxify/SKILL.md +4 -4
- package/dist/features/canvas/canvasInsertionSeams.js +0 -44
- package/dist/features/preview/components/AddBlockSheet.js +0 -314
- package/dist/features/preview/components/BlockPeek.js +0 -66
- package/dist/features/preview/components/BlockThumbnail.js +0 -281
- package/dist/features/preview/components/blockGridNavigation.js +0 -15
- package/dist/features/preview/referencePickerFocus.js +0 -29
|
@@ -18,7 +18,8 @@ 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, and the draft's thread shows the hand-off's Brief collapsed
|
|
22
|
+
* under the editor's messages. The thread keeps its end in view, unless the editor scrolls up.
|
|
22
23
|
*/
|
|
23
24
|
function ThreadMessages(t0) {
|
|
24
25
|
const $ = c(20);
|
|
@@ -297,7 +298,7 @@ const PUSH_OUTCOMES = {
|
|
|
297
298
|
notPreviewed: "Built, but the preview can’t show it."
|
|
298
299
|
};
|
|
299
300
|
function ThreadMessageRow(t0) {
|
|
300
|
-
const $ = c(
|
|
301
|
+
const $ = c(46);
|
|
301
302
|
const { message, onOpenDraft } = t0;
|
|
302
303
|
if (message.from === "draft") {
|
|
303
304
|
let t1;
|
|
@@ -438,54 +439,63 @@ function ThreadMessageRow(t0) {
|
|
|
438
439
|
} else t5 = $[33];
|
|
439
440
|
return t5;
|
|
440
441
|
}
|
|
442
|
+
if (message.from === "brief") {
|
|
443
|
+
let t1;
|
|
444
|
+
if ($[34] !== message.text) {
|
|
445
|
+
t1 = /* @__PURE__ */ jsx(Message, { children: /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(BriefNote, { text: message.text }) }) });
|
|
446
|
+
$[34] = message.text;
|
|
447
|
+
$[35] = t1;
|
|
448
|
+
} else t1 = $[35];
|
|
449
|
+
return t1;
|
|
450
|
+
}
|
|
441
451
|
if (message.from === "camox") {
|
|
442
452
|
let t1;
|
|
443
|
-
if ($[
|
|
453
|
+
if ($[36] === Symbol.for("react.memo_cache_sentinel")) {
|
|
444
454
|
t1 = /* @__PURE__ */ jsx(MessageHeader, {
|
|
445
455
|
className: "text-muted-foreground text-xs",
|
|
446
456
|
children: "Camox"
|
|
447
457
|
});
|
|
448
|
-
$[
|
|
449
|
-
} else t1 = $[
|
|
458
|
+
$[36] = t1;
|
|
459
|
+
} else t1 = $[36];
|
|
450
460
|
let t2;
|
|
451
|
-
if ($[
|
|
461
|
+
if ($[37] !== message.text) {
|
|
452
462
|
t2 = /* @__PURE__ */ jsx(Message, { children: /* @__PURE__ */ jsxs(MessageContent, { children: [t1, /* @__PURE__ */ jsx(Bubble, {
|
|
453
463
|
variant: "muted",
|
|
454
464
|
className: "max-w-full",
|
|
455
465
|
children: /* @__PURE__ */ jsx(BubbleContent, { children: /* @__PURE__ */ jsx(CroppedText, { text: message.text }) })
|
|
456
466
|
})] }) });
|
|
457
|
-
$[
|
|
458
|
-
$[
|
|
459
|
-
} else t2 = $[
|
|
467
|
+
$[37] = message.text;
|
|
468
|
+
$[38] = t2;
|
|
469
|
+
} else t2 = $[38];
|
|
460
470
|
return t2;
|
|
461
471
|
}
|
|
462
472
|
let t1;
|
|
463
|
-
if ($[
|
|
473
|
+
if ($[39] !== message.sender) {
|
|
464
474
|
t1 = /* @__PURE__ */ jsx(MessageAvatar, { children: /* @__PURE__ */ jsx(SenderAvatar, { sender: message.sender }) });
|
|
465
|
-
$[
|
|
466
|
-
$[
|
|
467
|
-
} else t1 = $[
|
|
475
|
+
$[39] = message.sender;
|
|
476
|
+
$[40] = t1;
|
|
477
|
+
} else t1 = $[40];
|
|
468
478
|
let t2;
|
|
469
|
-
if ($[
|
|
479
|
+
if ($[41] !== message.text) {
|
|
470
480
|
t2 = /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(Bubble, {
|
|
471
481
|
align: "end",
|
|
472
482
|
variant: "muted",
|
|
473
483
|
className: "max-w-full",
|
|
474
484
|
children: /* @__PURE__ */ jsx(BubbleContent, { children: /* @__PURE__ */ jsx(CroppedText, { text: message.text }) })
|
|
475
485
|
}) });
|
|
476
|
-
$[
|
|
477
|
-
$[
|
|
478
|
-
} else t2 = $[
|
|
486
|
+
$[41] = message.text;
|
|
487
|
+
$[42] = t2;
|
|
488
|
+
} else t2 = $[42];
|
|
479
489
|
let t3;
|
|
480
|
-
if ($[
|
|
490
|
+
if ($[43] !== t1 || $[44] !== t2) {
|
|
481
491
|
t3 = /* @__PURE__ */ jsxs(Message, {
|
|
482
492
|
align: "end",
|
|
483
493
|
children: [t1, t2]
|
|
484
494
|
});
|
|
485
|
-
$[
|
|
486
|
-
$[
|
|
487
|
-
$[
|
|
488
|
-
} else t3 = $[
|
|
495
|
+
$[43] = t1;
|
|
496
|
+
$[44] = t2;
|
|
497
|
+
$[45] = t3;
|
|
498
|
+
} else t3 = $[45];
|
|
489
499
|
return t3;
|
|
490
500
|
}
|
|
491
501
|
function _temp(subject, index) {
|
|
@@ -575,6 +585,63 @@ function CroppedText(t0) {
|
|
|
575
585
|
} else t9 = $[16];
|
|
576
586
|
return t9;
|
|
577
587
|
}
|
|
588
|
+
/**
|
|
589
|
+
* The Brief the agent on Live handed the request off with, under the editor's messages: a quiet
|
|
590
|
+
* line, so the request reads on as they sent it, which shows it once clicked.
|
|
591
|
+
*/
|
|
592
|
+
function BriefNote(t0) {
|
|
593
|
+
const $ = c(10);
|
|
594
|
+
const { text } = t0;
|
|
595
|
+
const [open, setOpen] = React.useState(false);
|
|
596
|
+
let t1;
|
|
597
|
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
598
|
+
t1 = () => setOpen(_temp2);
|
|
599
|
+
$[0] = t1;
|
|
600
|
+
} else t1 = $[0];
|
|
601
|
+
const t2 = open ? "Hide the brief" : "Camox briefed the agent";
|
|
602
|
+
let t3;
|
|
603
|
+
if ($[1] !== open || $[2] !== t2) {
|
|
604
|
+
t3 = /* @__PURE__ */ jsx("button", {
|
|
605
|
+
type: "button",
|
|
606
|
+
"aria-expanded": open,
|
|
607
|
+
onClick: t1,
|
|
608
|
+
className: "focus-visible:ring-ring self-start rounded-sm hover:underline focus-visible:ring-2 focus-visible:outline-none",
|
|
609
|
+
children: t2
|
|
610
|
+
});
|
|
611
|
+
$[1] = open;
|
|
612
|
+
$[2] = t2;
|
|
613
|
+
$[3] = t3;
|
|
614
|
+
} else t3 = $[3];
|
|
615
|
+
let t4;
|
|
616
|
+
if ($[4] !== open || $[5] !== text) {
|
|
617
|
+
t4 = open && /* @__PURE__ */ jsx(Bubble, {
|
|
618
|
+
variant: "muted",
|
|
619
|
+
className: "max-w-full",
|
|
620
|
+
children: /* @__PURE__ */ jsx(BubbleContent, { children: /* @__PURE__ */ jsx("div", {
|
|
621
|
+
className: "whitespace-pre-wrap",
|
|
622
|
+
children: text
|
|
623
|
+
}) })
|
|
624
|
+
});
|
|
625
|
+
$[4] = open;
|
|
626
|
+
$[5] = text;
|
|
627
|
+
$[6] = t4;
|
|
628
|
+
} else t4 = $[6];
|
|
629
|
+
let t5;
|
|
630
|
+
if ($[7] !== t3 || $[8] !== t4) {
|
|
631
|
+
t5 = /* @__PURE__ */ jsxs("div", {
|
|
632
|
+
"data-thread-brief": true,
|
|
633
|
+
className: "text-muted-foreground flex flex-col gap-2 text-xs",
|
|
634
|
+
children: [t3, t4]
|
|
635
|
+
});
|
|
636
|
+
$[7] = t3;
|
|
637
|
+
$[8] = t4;
|
|
638
|
+
$[9] = t5;
|
|
639
|
+
} else t5 = $[9];
|
|
640
|
+
return t5;
|
|
641
|
+
}
|
|
642
|
+
function _temp2(current) {
|
|
643
|
+
return !current;
|
|
644
|
+
}
|
|
578
645
|
const initials = (name) => name.split(" ").map((part) => part[0]).join("").toUpperCase().slice(0, 2);
|
|
579
646
|
const DRAFT_CARD_CLASSES = "bg-muted/50 flex w-full flex-col items-start gap-0.5 rounded-lg border px-3 py-2 text-left text-sm";
|
|
580
647
|
/**
|
|
@@ -4,7 +4,7 @@ const dayFormat = new Intl.DateTimeFormat(void 0, {
|
|
|
4
4
|
day: "numeric"
|
|
5
5
|
});
|
|
6
6
|
/**
|
|
7
|
-
* A draft's name, or for
|
|
7
|
+
* A draft's name, or for a draft not named yet its creator and creation date formatted for the
|
|
8
8
|
* viewer, e.g. "Rémi, Oct 13".
|
|
9
9
|
*/
|
|
10
10
|
function draftLabel(draft) {
|
|
@@ -5,10 +5,7 @@ const studioStore = createStore({
|
|
|
5
5
|
context: {
|
|
6
6
|
isCommandPaletteOpen: false,
|
|
7
7
|
commandPalettePages: [],
|
|
8
|
-
|
|
9
|
-
open: false,
|
|
10
|
-
startRenaming: false
|
|
11
|
-
},
|
|
8
|
+
isReviewDraftSheetOpen: false,
|
|
12
9
|
isDeleteDraftDialogOpen: false,
|
|
13
10
|
localeDialog: null,
|
|
14
11
|
websiteLocation: null,
|
|
@@ -48,22 +45,16 @@ const studioStore = createStore({
|
|
|
48
45
|
commandPalettePages: context.commandPalettePages.slice(0, -1)
|
|
49
46
|
};
|
|
50
47
|
},
|
|
51
|
-
openReviewDraftSheet: (context
|
|
48
|
+
openReviewDraftSheet: (context) => {
|
|
52
49
|
return {
|
|
53
50
|
...context,
|
|
54
|
-
|
|
55
|
-
open: true,
|
|
56
|
-
startRenaming: event.startRenaming ?? false
|
|
57
|
-
}
|
|
51
|
+
isReviewDraftSheetOpen: true
|
|
58
52
|
};
|
|
59
53
|
},
|
|
60
54
|
closeReviewDraftSheet: (context) => {
|
|
61
55
|
return {
|
|
62
56
|
...context,
|
|
63
|
-
|
|
64
|
-
open: false,
|
|
65
|
-
startRenaming: false
|
|
66
|
-
}
|
|
57
|
+
isReviewDraftSheetOpen: false
|
|
67
58
|
};
|
|
68
59
|
},
|
|
69
60
|
openDeleteDraftDialog: (context) => {
|
|
@@ -93,10 +84,7 @@ const studioStore = createStore({
|
|
|
93
84
|
askAgent: (context, event) => {
|
|
94
85
|
return {
|
|
95
86
|
...context,
|
|
96
|
-
|
|
97
|
-
open: false,
|
|
98
|
-
startRenaming: false
|
|
99
|
-
},
|
|
87
|
+
isReviewDraftSheetOpen: false,
|
|
100
88
|
agentAsk: {
|
|
101
89
|
text: event.text,
|
|
102
90
|
id: context.agentAsks + 1
|
|
@@ -41,13 +41,11 @@ function useLeaveDraft() {
|
|
|
41
41
|
const shown = useViewShown();
|
|
42
42
|
let t0;
|
|
43
43
|
if ($[0] !== draftScope || $[1] !== shown) {
|
|
44
|
-
t0 = (ended
|
|
45
|
-
const { discarded: t2 } = t1 === void 0 ? {} : t1;
|
|
46
|
-
const discarded = t2 === void 0 ? false : t2;
|
|
44
|
+
t0 = (ended) => {
|
|
47
45
|
if (ended && draftScope.current() !== ended.draftId) return;
|
|
48
46
|
draftScope.leave(ended);
|
|
49
47
|
if (!ended) return;
|
|
50
|
-
const what =
|
|
48
|
+
const what = `Draft ${ended.outcome}`;
|
|
51
49
|
toastSwitch(shown(), {
|
|
52
50
|
loading: `${what}. Switching to Live…`,
|
|
53
51
|
success: `${what}. You're now viewing Live.`
|
|
@@ -24,7 +24,7 @@ const ${camelName} = createBlock({
|
|
|
24
24
|
title: "${kebabToTitle(name)}",
|
|
25
25
|
description: "Describe when the AI should use this block.",
|
|
26
26
|
content: (field) => ({
|
|
27
|
-
title: field.string(
|
|
27
|
+
title: field.string(),
|
|
28
28
|
}),
|
|
29
29
|
toReact: ${pascalName}Component,
|
|
30
30
|
toTitle: ({ content }) => content.title,
|
|
@@ -54,14 +54,7 @@ async function syncDefinitionsToApi(options) {
|
|
|
54
54
|
const unused = layoutSyncResults.deletedDefinitionTypes;
|
|
55
55
|
if (unused.length > 0) logger.info(`[camox] Removed ${counted(unused.length, "layoutOnly block definition")} (no layout uses ${unused.length === 1 ? "it" : "them"} anymore): ${quoted(unused)}`, { timestamp: true });
|
|
56
56
|
}
|
|
57
|
-
|
|
58
|
-
if (homepage && result.homepage?.created) {
|
|
59
|
-
if (homepage.hasInitialBlocks) logger.info(`[camox] Initialized content: homepage with ${counted(result.homepage.blockCount, "block")}`, { timestamp: true });
|
|
60
|
-
else {
|
|
61
|
-
logger.info("[camox] Created empty homepage (using first layout)", { timestamp: true });
|
|
62
|
-
logger.info("[camox] Tip: add blocks.initial to your layout to pre-populate pages with content", { timestamp: true });
|
|
63
|
-
}
|
|
64
|
-
}
|
|
57
|
+
if (definitionSet.homepage && result.homepage?.created) logger.info(`[camox] Created an empty homepage with the "${definitionSet.homepage.layoutId}" layout`, { timestamp: true });
|
|
65
58
|
}
|
|
66
59
|
const VIRTUAL_CAMOX_APP = "virtual:camox/app";
|
|
67
60
|
const RESOLVED_VIRTUAL_CAMOX_APP = "\0virtual:camox/app";
|
package/dist/lib/queries.js
CHANGED
|
@@ -66,7 +66,6 @@ const localeMutations = {
|
|
|
66
66
|
addBack: () => getOrpc().locales.addBack.mutationOptions()
|
|
67
67
|
};
|
|
68
68
|
const blockMutations = {
|
|
69
|
-
create: () => getOrpc().blocks.create.mutationOptions(),
|
|
70
69
|
delete: () => getOrpc().blocks.delete.mutationOptions(),
|
|
71
70
|
deleteMany: () => getOrpc().blocks.deleteMany.mutationOptions(),
|
|
72
71
|
duplicate: () => getOrpc().blocks.duplicate.mutationOptions(),
|
|
@@ -9,8 +9,6 @@ const toBlockDefinitions = (rows) => rows.map((row) => ({
|
|
|
9
9
|
description: row.description,
|
|
10
10
|
contentSchema: row.contentSchema,
|
|
11
11
|
settingsSchema: row.settingsSchema ?? void 0,
|
|
12
|
-
defaultContent: row.defaultContent ?? {},
|
|
13
|
-
defaultSettings: row.defaultSettings ?? {},
|
|
14
12
|
layoutOnly: !!row.layoutOnly,
|
|
15
13
|
synced: row.synced
|
|
16
14
|
}));
|
package/dist/lib/studio-reads.js
CHANGED
|
@@ -157,11 +157,6 @@ const reads = {
|
|
|
157
157
|
fetch: async ({ api, signal }, id) => (await api.files.getUsageCount({ id }, { signal })).count,
|
|
158
158
|
staleTime: Infinity
|
|
159
159
|
}),
|
|
160
|
-
blockUsageCounts: entry({
|
|
161
|
-
key: () => usageCountsPrefix,
|
|
162
|
-
fetch: async ({ api, signal }, { projectId }) => Object.fromEntries((await api.blocks.getUsageCounts({ projectId }, { signal })).map(({ type, count }) => [type, count])),
|
|
163
|
-
staleTime: Infinity
|
|
164
|
-
}),
|
|
165
160
|
pageMarkdown: entry({
|
|
166
161
|
key: (pageId) => queryKeys.blocks.getPageMarkdown(pageId),
|
|
167
162
|
fetch: async ({ api, signal }, pageId) => (await api.blocks.getPageMarkdown({ pageId }, { signal })).markdown,
|