camox 0.58.1 → 0.60.2
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/createBlock.js +1 -1
- package/dist/core/editing/createEditableBlock.js +2 -2
- package/dist/core/lib/recordScope.js +1 -1
- package/dist/features/canvas/CamoxCanvas.js +2 -2
- package/dist/features/canvas/CanvasOverlays.js +1 -1
- package/dist/features/canvas/sidebar/LayoutPageSeo.js +1 -1
- package/dist/features/canvas/sidebar/PageInspector.js +1 -1
- package/dist/features/content/CamoxContent.js +1 -1
- package/dist/features/content/components/MissingFromLocale.js +1 -1
- package/dist/features/page/CuratedPageContent.js +1 -1
- package/dist/features/preview/CamoxPreview.js +3 -3
- package/dist/features/preview/components/AddBlockSheet.js +1 -1
- package/dist/features/preview/components/AssetLightbox.js +1 -1
- package/dist/features/preview/components/BlockActionsPopover.js +1 -1
- package/dist/features/preview/components/CreatePageModal.js +2 -2
- package/dist/features/preview/components/FieldOverlayStyles.js +1 -1
- package/dist/features/preview/components/MobilePreviewDrawer.js +1 -1
- package/dist/features/preview/components/Overlays.js +1 -1
- package/dist/features/preview/components/PageInfo.js +1 -1
- package/dist/features/preview/components/PagePicker.js +1 -1
- package/dist/features/preview/components/PageTree.js +1 -1
- package/dist/features/preview/components/PreviewPanel.js +1 -1
- package/dist/features/preview/components/PreviewToolbar.js +1 -1
- package/dist/features/preview/components/SelectionEditor.js +2 -2
- package/dist/features/preview/components/StudioEditingFallback.js +1 -1
- package/dist/features/provider/AuthenticatedCamoxProvider.js +1 -1
- package/dist/features/provider/CamoxProvider.js +1 -1
- package/dist/features/provider/CoreCamoxProvider.js +3 -3
- package/dist/features/provider/components/CommandPalette.js +1 -1
- package/dist/features/renderer/RendererApp.js +187 -103
- package/dist/features/renderer/rendererHost.js +3 -7
- package/dist/features/routes/pageRuntime.d.ts +2 -5
- package/dist/features/routes/pageRuntime.js +1 -2
- package/dist/features/runtime/RuntimeChrome.js +1 -1
- package/dist/features/runtime/loopbackFetch.d.ts +8 -0
- package/dist/features/runtime/navigationTarget.js +1 -2
- package/dist/features/runtime/pageApp.js +1 -1
- package/dist/features/runtime/publicCache.d.ts +21 -0
- package/dist/features/runtime/publishingDraft.d.ts +4 -0
- package/dist/features/runtime/rendererClient.js +1 -1
- package/dist/features/runtime/runtime.d.ts +0 -5
- package/dist/features/runtime/runtime.js +80 -33
- package/dist/features/runtime/worker.js +4 -7
- package/dist/features/runtime/workerRequest.d.ts +8 -0
- package/dist/features/runtime/workerRuntime.d.ts +5 -0
- package/dist/features/runtime/workerRuntime.js +6 -0
- package/dist/features/sdkBundle/buildSdkBundle.d.ts +40 -0
- package/dist/features/sdkBundle/buildSdkBundle.js +323 -0
- package/dist/features/sdkBundle/localSdkBundle.d.ts +44 -0
- package/dist/features/sdkBundle/localSdkBundle.js +162 -0
- package/dist/features/sdkBundle/sdkBundle.d.ts +3 -0
- package/dist/features/sdkBundle/sdkBundle.js +4 -0
- package/dist/features/sdkBundle/sdkBundleName.d.ts +59 -0
- package/dist/features/sdkBundle/sdkBundleName.js +164 -0
- package/dist/features/sdkBundle/specifiers.d.ts +34 -0
- package/dist/features/sdkBundle/specifiers.js +146 -0
- package/dist/features/settings/FaviconSettings.js +1 -1
- package/dist/features/settings/SocialProfilesSettings.js +284 -151
- package/dist/features/studio/CamoxStudio.js +1 -1
- package/dist/features/studio/FollowAgentProvider.js +72 -13
- package/dist/features/studio/components/ChatWidget.js +86 -44
- package/dist/features/studio/components/DraftsControl.js +232 -201
- package/dist/features/studio/components/LocalePicker.js +2 -2
- package/dist/features/studio/components/Navbar.js +3 -3
- package/dist/features/studio/components/Patrol.js +312 -209
- package/dist/features/studio/components/ProjectMenu.js +2 -2
- package/dist/features/studio/components/ReviewDraftSheet.js +9 -15
- package/dist/features/studio/components/Squareling.js +164 -66
- package/dist/features/studio/components/ThreadComposer.js +139 -69
- package/dist/features/studio/components/ThreadMessages.js +216 -64
- package/dist/features/studio/components/UserButton.js +2 -2
- package/dist/features/studio/draftLabel.js +1 -2
- package/dist/features/studio/draftNotice.js +0 -1
- package/dist/features/studio/editorWhereContext.js +11 -0
- package/dist/features/studio/showInCanvas.js +1 -1
- package/dist/features/studio/useEditorSelection.js +135 -0
- package/dist/features/vite/definitionsSync.js +14 -60
- package/dist/features/vite/devSignIn.js +1 -1
- package/dist/features/vite/hostedChecks.js +1 -1
- package/dist/features/vite/runtimeDev.js +2 -2
- package/dist/features/vite/sdkBundleBuild.js +74 -0
- package/dist/features/vite/staticAssetHeaders.js +7 -4
- package/dist/features/vite/vite.d.ts +8 -7
- package/dist/features/vite/vite.js +67 -28
- package/dist/lib/api-client-server.js +25 -8
- package/dist/lib/api-client.js +2 -6
- package/dist/lib/auth.js +25 -59
- package/dist/lib/draft-scope.js +5 -25
- package/dist/lib/preview-handoff.js +1 -1
- package/dist/lib/server-auth-cookie.js +23 -11
- package/dist/lib/stored-auth-cookies.js +76 -0
- package/dist/lib/studio-reads.js +1 -1
- package/dist/lib/use-thread.js +40 -40
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +17 -4
- package/skills/camox/references/block-definitions.md +1 -1
- package/dist/features/vite/publishSeededContent.js +0 -30
- package/skills/camox-cli/SKILL.md +0 -15
- package/skills/camox-cli/references/cli-common.md +0 -58
- package/skills/camox-cli/references/cli-content.md +0 -181
- package/skills/camox-cli/references/cli-publishing.md +0 -26
|
@@ -14,9 +14,9 @@ import { MessageScroller, MessageScrollerButton, MessageScrollerContent, Message
|
|
|
14
14
|
* A thread's messages, and the agent's squareling, which always lives in it. An empty thread has
|
|
15
15
|
* it greet the editor; when the first message arrives, it moves to the end of the thread, and
|
|
16
16
|
* stays there after each message. While a run is going or a message is still `sending` (on its
|
|
17
|
-
* way to the thread, which hasn't accepted it yet), its face
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* way to the thread, which hasn't accepted it yet), its face and a line beside it say what the
|
|
18
|
+
* agent does, never how: thinking, looking around, making changes, building, fixing the build,
|
|
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
21
|
* card, which `onOpenDraft` opens.
|
|
22
22
|
*/
|
|
@@ -154,69 +154,145 @@ function useSquarelingMorph(empty) {
|
|
|
154
154
|
return node;
|
|
155
155
|
}
|
|
156
156
|
/**
|
|
157
|
-
* The squareling at the end of the thread: idle between turns, at work during one
|
|
158
|
-
* last message, not after it: the scroller only brings a message the
|
|
159
|
-
* when it's appended last, and it arrives while the agent is already
|
|
157
|
+
* The squareling at the end of the thread: idle between turns, at work during one, saying what
|
|
158
|
+
* the agent does. Shown in the last message, not after it: the scroller only brings a message the
|
|
159
|
+
* editor just sent into view when it's appended last, and it arrives while the agent is already
|
|
160
|
+
* working.
|
|
160
161
|
*/
|
|
161
162
|
function AgentPresence(t0) {
|
|
162
|
-
const $ = c(
|
|
163
|
+
const $ = c(8);
|
|
163
164
|
const { view: t1, working, squareling } = t0;
|
|
164
|
-
const {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
t2 = working ? squarelingStatus(status, usingTools) : "idle";
|
|
168
|
-
$[0] = status;
|
|
169
|
-
$[1] = usingTools;
|
|
170
|
-
$[2] = working;
|
|
171
|
-
$[3] = t2;
|
|
172
|
-
} else t2 = $[3];
|
|
165
|
+
const { activity } = t1;
|
|
166
|
+
const shown = useSteadyActivity(working ? activity ?? "thinking" : void 0);
|
|
167
|
+
const t2 = shown ? SQUARELING_STATUSES[shown] : "idle";
|
|
173
168
|
let t3;
|
|
174
|
-
if ($[
|
|
169
|
+
if ($[0] !== squareling || $[1] !== t2) {
|
|
175
170
|
t3 = /* @__PURE__ */ jsx(Squareling, {
|
|
176
171
|
ref: squareling,
|
|
177
172
|
status: t2,
|
|
178
173
|
className: "size-6"
|
|
179
174
|
});
|
|
180
|
-
$[
|
|
181
|
-
$[
|
|
182
|
-
$[
|
|
183
|
-
} else t3 = $[
|
|
175
|
+
$[0] = squareling;
|
|
176
|
+
$[1] = t2;
|
|
177
|
+
$[2] = t3;
|
|
178
|
+
} else t3 = $[2];
|
|
184
179
|
let t4;
|
|
185
|
-
if ($[
|
|
186
|
-
t4 =
|
|
180
|
+
if ($[3] !== shown) {
|
|
181
|
+
t4 = shown && /* @__PURE__ */ jsx("span", {
|
|
187
182
|
className: "shimmer",
|
|
188
|
-
children:
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
$[7] = status;
|
|
194
|
-
$[8] = working;
|
|
195
|
-
$[9] = t4;
|
|
196
|
-
} else t4 = $[9];
|
|
183
|
+
children: ACTIVITY_LINES[shown]
|
|
184
|
+
});
|
|
185
|
+
$[3] = shown;
|
|
186
|
+
$[4] = t4;
|
|
187
|
+
} else t4 = $[4];
|
|
197
188
|
let t5;
|
|
198
|
-
if ($[
|
|
189
|
+
if ($[5] !== t3 || $[6] !== t4) {
|
|
199
190
|
t5 = /* @__PURE__ */ jsxs("div", {
|
|
200
191
|
role: "status",
|
|
201
192
|
className: "text-muted-foreground flex items-center gap-2 text-sm",
|
|
202
193
|
children: [t3, t4]
|
|
203
194
|
});
|
|
204
|
-
$[
|
|
205
|
-
$[
|
|
206
|
-
$[
|
|
207
|
-
} else t5 = $[
|
|
195
|
+
$[5] = t3;
|
|
196
|
+
$[6] = t4;
|
|
197
|
+
$[7] = t5;
|
|
198
|
+
} else t5 = $[7];
|
|
208
199
|
return t5;
|
|
209
200
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
201
|
+
/**
|
|
202
|
+
* How long a line saying what the agent does stays at least, in ms, so editors have time to read
|
|
203
|
+
* it: a round of tool calls can take far less.
|
|
204
|
+
*/
|
|
205
|
+
const ACTIVITY_MIN_DURATION = 2e3;
|
|
206
|
+
/**
|
|
207
|
+
* How long the agent must keep doing something before a line says so, in ms: thinking briefly
|
|
208
|
+
* between two rounds of tool calls never shows.
|
|
209
|
+
*/
|
|
210
|
+
const ACTIVITY_SETTLE_DURATION = 800;
|
|
211
|
+
/**
|
|
212
|
+
* `activity` as a line shows it, steadied: a new activity shows once it lasted
|
|
213
|
+
* `ACTIVITY_SETTLE_DURATION` and the line before held for `ACTIVITY_MIN_DURATION`, so a brief
|
|
214
|
+
* one never shows. Only the line lags: a turn that starts or ends shows at once.
|
|
215
|
+
*/
|
|
216
|
+
function useSteadyActivity(activity) {
|
|
217
|
+
const $ = c(10);
|
|
218
|
+
let t0;
|
|
219
|
+
if ($[0] !== activity) {
|
|
220
|
+
t0 = { activity };
|
|
221
|
+
$[0] = activity;
|
|
222
|
+
$[1] = t0;
|
|
223
|
+
} else t0 = $[1];
|
|
224
|
+
const [latest, setLatest] = React.useState(t0);
|
|
225
|
+
const [lasted, setLasted] = React.useState();
|
|
226
|
+
let t1;
|
|
227
|
+
if ($[2] !== activity) {
|
|
228
|
+
t1 = { activity };
|
|
229
|
+
$[2] = activity;
|
|
230
|
+
$[3] = t1;
|
|
231
|
+
} else t1 = $[3];
|
|
232
|
+
const [held, setHeld] = React.useState(t1);
|
|
233
|
+
const [settled, setSettled] = React.useState();
|
|
234
|
+
let t2;
|
|
235
|
+
let t3;
|
|
236
|
+
if ($[4] !== latest) {
|
|
237
|
+
t2 = () => {
|
|
238
|
+
const timer = setTimeout(() => setLasted(latest), 800);
|
|
239
|
+
return () => clearTimeout(timer);
|
|
240
|
+
};
|
|
241
|
+
t3 = [latest];
|
|
242
|
+
$[4] = latest;
|
|
243
|
+
$[5] = t2;
|
|
244
|
+
$[6] = t3;
|
|
245
|
+
} else {
|
|
246
|
+
t2 = $[5];
|
|
247
|
+
t3 = $[6];
|
|
248
|
+
}
|
|
249
|
+
React.useEffect(t2, t3);
|
|
250
|
+
let t4;
|
|
251
|
+
let t5;
|
|
252
|
+
if ($[7] !== held) {
|
|
253
|
+
t4 = () => {
|
|
254
|
+
const timer_0 = setTimeout(() => setSettled(held), ACTIVITY_MIN_DURATION);
|
|
255
|
+
return () => clearTimeout(timer_0);
|
|
256
|
+
};
|
|
257
|
+
t5 = [held];
|
|
258
|
+
$[7] = held;
|
|
259
|
+
$[8] = t4;
|
|
260
|
+
$[9] = t5;
|
|
261
|
+
} else {
|
|
262
|
+
t4 = $[8];
|
|
263
|
+
t5 = $[9];
|
|
264
|
+
}
|
|
265
|
+
React.useEffect(t4, t5);
|
|
266
|
+
if (activity !== latest.activity) setLatest({ activity });
|
|
267
|
+
else if (activity !== held.activity) {
|
|
268
|
+
if (!activity || !held.activity || lasted === latest && settled === held) setHeld({ activity });
|
|
269
|
+
}
|
|
270
|
+
return activity && (held.activity ?? activity);
|
|
213
271
|
}
|
|
214
|
-
const
|
|
272
|
+
const SQUARELING_STATUSES = {
|
|
273
|
+
thinking: "thinking",
|
|
274
|
+
exploring: "exploring",
|
|
275
|
+
changing: "changing",
|
|
276
|
+
building: "building",
|
|
277
|
+
fixing: "fixing",
|
|
278
|
+
startingDraft: "changing"
|
|
279
|
+
};
|
|
280
|
+
const ACTIVITY_LINES = {
|
|
281
|
+
thinking: "Thinking…",
|
|
282
|
+
exploring: "Looking around…",
|
|
283
|
+
changing: "Making changes…",
|
|
215
284
|
building: "Building…",
|
|
216
|
-
fixing: "Fixing
|
|
285
|
+
fixing: "Fixing the build…",
|
|
286
|
+
startingDraft: "Starting a draft…"
|
|
287
|
+
};
|
|
288
|
+
/** How a member's pushed code built, as the thread says it. */
|
|
289
|
+
const PUSH_OUTCOMES = {
|
|
290
|
+
built: "Built, and in the preview.",
|
|
291
|
+
typeErrors: "Built, with type errors that block publishing.",
|
|
292
|
+
notPreviewed: "Built, but the preview can’t show it."
|
|
217
293
|
};
|
|
218
294
|
function ThreadMessageRow(t0) {
|
|
219
|
-
const $ = c(
|
|
295
|
+
const $ = c(36);
|
|
220
296
|
const { message, onOpenDraft } = t0;
|
|
221
297
|
if (message.from === "draft") {
|
|
222
298
|
let t1;
|
|
@@ -253,17 +329,87 @@ function ThreadMessageRow(t0) {
|
|
|
253
329
|
} else t1 = $[6];
|
|
254
330
|
return t1;
|
|
255
331
|
}
|
|
332
|
+
if (message.from === "push") {
|
|
333
|
+
const commits = message.subjects.length;
|
|
334
|
+
let t1;
|
|
335
|
+
if ($[7] !== message.sender) {
|
|
336
|
+
t1 = /* @__PURE__ */ jsx(MessageAvatar, { children: /* @__PURE__ */ jsx(SenderAvatar, { sender: message.sender }) });
|
|
337
|
+
$[7] = message.sender;
|
|
338
|
+
$[8] = t1;
|
|
339
|
+
} else t1 = $[8];
|
|
340
|
+
const t2 = `${message.sender.name} pushed ${commits} ${commits === 1 ? "commit" : "commits"}`;
|
|
341
|
+
let t3;
|
|
342
|
+
if ($[9] !== t2) {
|
|
343
|
+
t3 = /* @__PURE__ */ jsx(MessageHeader, {
|
|
344
|
+
className: "text-muted-foreground text-xs",
|
|
345
|
+
children: t2
|
|
346
|
+
});
|
|
347
|
+
$[9] = t2;
|
|
348
|
+
$[10] = t3;
|
|
349
|
+
} else t3 = $[10];
|
|
350
|
+
let t4;
|
|
351
|
+
if ($[11] !== message.subjects) {
|
|
352
|
+
t4 = message.subjects.map(_temp);
|
|
353
|
+
$[11] = message.subjects;
|
|
354
|
+
$[12] = t4;
|
|
355
|
+
} else t4 = $[12];
|
|
356
|
+
let t5;
|
|
357
|
+
if ($[13] !== t4) {
|
|
358
|
+
t5 = /* @__PURE__ */ jsx("ul", {
|
|
359
|
+
className: "flex flex-col gap-0.5",
|
|
360
|
+
children: t4
|
|
361
|
+
});
|
|
362
|
+
$[13] = t4;
|
|
363
|
+
$[14] = t5;
|
|
364
|
+
} else t5 = $[14];
|
|
365
|
+
const t6 = PUSH_OUTCOMES[message.outcome];
|
|
366
|
+
let t7;
|
|
367
|
+
if ($[15] !== t6) {
|
|
368
|
+
t7 = /* @__PURE__ */ jsx("span", {
|
|
369
|
+
className: "text-muted-foreground text-xs",
|
|
370
|
+
children: t6
|
|
371
|
+
});
|
|
372
|
+
$[15] = t6;
|
|
373
|
+
$[16] = t7;
|
|
374
|
+
} else t7 = $[16];
|
|
375
|
+
let t8;
|
|
376
|
+
if ($[17] !== t5 || $[18] !== t7) {
|
|
377
|
+
t8 = /* @__PURE__ */ jsxs("div", {
|
|
378
|
+
"data-thread-push": true,
|
|
379
|
+
className: DRAFT_CARD_CLASSES,
|
|
380
|
+
children: [t5, t7]
|
|
381
|
+
});
|
|
382
|
+
$[17] = t5;
|
|
383
|
+
$[18] = t7;
|
|
384
|
+
$[19] = t8;
|
|
385
|
+
} else t8 = $[19];
|
|
386
|
+
let t9;
|
|
387
|
+
if ($[20] !== t3 || $[21] !== t8) {
|
|
388
|
+
t9 = /* @__PURE__ */ jsxs(MessageContent, { children: [t3, t8] });
|
|
389
|
+
$[20] = t3;
|
|
390
|
+
$[21] = t8;
|
|
391
|
+
$[22] = t9;
|
|
392
|
+
} else t9 = $[22];
|
|
393
|
+
let t10;
|
|
394
|
+
if ($[23] !== t1 || $[24] !== t9) {
|
|
395
|
+
t10 = /* @__PURE__ */ jsxs(Message, { children: [t1, t9] });
|
|
396
|
+
$[23] = t1;
|
|
397
|
+
$[24] = t9;
|
|
398
|
+
$[25] = t10;
|
|
399
|
+
} else t10 = $[25];
|
|
400
|
+
return t10;
|
|
401
|
+
}
|
|
256
402
|
if (message.from === "camox") {
|
|
257
403
|
let t1;
|
|
258
|
-
if ($[
|
|
404
|
+
if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
|
|
259
405
|
t1 = /* @__PURE__ */ jsx(MessageHeader, {
|
|
260
406
|
className: "text-muted-foreground text-xs",
|
|
261
407
|
children: "Camox"
|
|
262
408
|
});
|
|
263
|
-
$[
|
|
264
|
-
} else t1 = $[
|
|
409
|
+
$[26] = t1;
|
|
410
|
+
} else t1 = $[26];
|
|
265
411
|
let t2;
|
|
266
|
-
if ($[
|
|
412
|
+
if ($[27] !== message.text) {
|
|
267
413
|
t2 = /* @__PURE__ */ jsx(Message, { children: /* @__PURE__ */ jsxs(MessageContent, { children: [t1, /* @__PURE__ */ jsx(Bubble, {
|
|
268
414
|
variant: "muted",
|
|
269
415
|
className: "max-w-full",
|
|
@@ -272,19 +418,19 @@ function ThreadMessageRow(t0) {
|
|
|
272
418
|
children: message.text
|
|
273
419
|
})
|
|
274
420
|
})] }) });
|
|
275
|
-
$[
|
|
276
|
-
$[
|
|
277
|
-
} else t2 = $[
|
|
421
|
+
$[27] = message.text;
|
|
422
|
+
$[28] = t2;
|
|
423
|
+
} else t2 = $[28];
|
|
278
424
|
return t2;
|
|
279
425
|
}
|
|
280
426
|
let t1;
|
|
281
|
-
if ($[
|
|
427
|
+
if ($[29] !== message.sender) {
|
|
282
428
|
t1 = /* @__PURE__ */ jsx(MessageAvatar, { children: /* @__PURE__ */ jsx(SenderAvatar, { sender: message.sender }) });
|
|
283
|
-
$[
|
|
284
|
-
$[
|
|
285
|
-
} else t1 = $[
|
|
429
|
+
$[29] = message.sender;
|
|
430
|
+
$[30] = t1;
|
|
431
|
+
} else t1 = $[30];
|
|
286
432
|
let t2;
|
|
287
|
-
if ($[
|
|
433
|
+
if ($[31] !== message.text) {
|
|
288
434
|
t2 = /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(Bubble, {
|
|
289
435
|
align: "end",
|
|
290
436
|
variant: "muted",
|
|
@@ -294,21 +440,27 @@ function ThreadMessageRow(t0) {
|
|
|
294
440
|
children: message.text
|
|
295
441
|
})
|
|
296
442
|
}) });
|
|
297
|
-
$[
|
|
298
|
-
$[
|
|
299
|
-
} else t2 = $[
|
|
443
|
+
$[31] = message.text;
|
|
444
|
+
$[32] = t2;
|
|
445
|
+
} else t2 = $[32];
|
|
300
446
|
let t3;
|
|
301
|
-
if ($[
|
|
447
|
+
if ($[33] !== t1 || $[34] !== t2) {
|
|
302
448
|
t3 = /* @__PURE__ */ jsxs(Message, {
|
|
303
449
|
align: "end",
|
|
304
450
|
children: [t1, t2]
|
|
305
451
|
});
|
|
306
|
-
$[
|
|
307
|
-
$[
|
|
308
|
-
$[
|
|
309
|
-
} else t3 = $[
|
|
452
|
+
$[33] = t1;
|
|
453
|
+
$[34] = t2;
|
|
454
|
+
$[35] = t3;
|
|
455
|
+
} else t3 = $[35];
|
|
310
456
|
return t3;
|
|
311
457
|
}
|
|
458
|
+
function _temp(subject, index) {
|
|
459
|
+
return /* @__PURE__ */ jsx("li", {
|
|
460
|
+
className: "font-mono text-xs",
|
|
461
|
+
children: subject
|
|
462
|
+
}, index);
|
|
463
|
+
}
|
|
312
464
|
const initials = (name) => name.split(" ").map((part) => part[0]).join("").toUpperCase().slice(0, 2);
|
|
313
465
|
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";
|
|
314
466
|
/**
|
|
@@ -424,4 +576,4 @@ function SenderAvatar(t0) {
|
|
|
424
576
|
}
|
|
425
577
|
|
|
426
578
|
//#endregion
|
|
427
|
-
export { ThreadMessages };
|
|
579
|
+
export { ACTIVITY_MIN_DURATION, ThreadMessages };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useAuthContext, useAuthState } from "../../../lib/auth.js";
|
|
2
1
|
import { useNavigate } from "../../navigation/navigation.js";
|
|
2
|
+
import { useAuthContext, useAuthState } from "../../../lib/auth.js";
|
|
3
3
|
import { useLocalePath, useLocalizedPath } from "../../../lib/view-locale.js";
|
|
4
4
|
import { previewStore, selectIsCanvasShown } from "../../preview/previewStore.js";
|
|
5
5
|
import { PlatformLabel } from "../../../components/PlatformLabel.js";
|
|
@@ -7,8 +7,8 @@ import { STUDIO_BASE_PATH } from "../routes.js";
|
|
|
7
7
|
import { studioStore } from "../studioStore.js";
|
|
8
8
|
import { useApplyTheme } from "../useTheme.js";
|
|
9
9
|
import { c } from "react/compiler-runtime";
|
|
10
|
-
import { useSelector } from "@xstate/store-react";
|
|
11
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { useSelector } from "@xstate/store-react";
|
|
12
12
|
import { Button } from "@camox/ui/button";
|
|
13
13
|
import { Check, Command, EyeOff, LogOut, Monitor, Moon, Settings, Sun, User } from "lucide-react";
|
|
14
14
|
import { Avatar, AvatarFallback, AvatarImage } from "@camox/ui/avatar";
|
|
@@ -5,10 +5,9 @@ const dayFormat = new Intl.DateTimeFormat(void 0, {
|
|
|
5
5
|
});
|
|
6
6
|
/**
|
|
7
7
|
* A draft's name, or for an unnamed draft its creator and creation date formatted for the
|
|
8
|
-
* viewer, e.g. "Rémi, Oct 13".
|
|
8
|
+
* viewer, e.g. "Rémi, Oct 13".
|
|
9
9
|
*/
|
|
10
10
|
function draftLabel(draft) {
|
|
11
|
-
if (draft.kind === "development") return "Development draft";
|
|
12
11
|
if (draft.name) return draft.name;
|
|
13
12
|
return `${draft.createdBy.name}, ${dayFormat.format(draft.createdAt)}`;
|
|
14
13
|
}
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
function draftNoticeMessage(notice) {
|
|
4
4
|
switch (notice.reason) {
|
|
5
5
|
case "missing": return "This draft doesn't exist, so you're viewing Live.";
|
|
6
|
-
case "noDevelopmentDraft": return "Your development draft doesn't exist until the dev server syncs your definitions, so you're viewing Live.";
|
|
7
6
|
case "forbidden": return "You can't open this draft, so you're viewing Live.";
|
|
8
7
|
case "ended": return `${notice.endedBy.name} ${notice.outcome} this draft, so you're viewing Live.`;
|
|
9
8
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/features/studio/editorWhereContext.ts
|
|
4
|
+
/**
|
|
5
|
+
* Where the editor is in the Website Section: the Page they look at, or the Canvas with no page
|
|
6
|
+
* selected. Undefined elsewhere in the Studio. Their messages to the agent carry it as a hint.
|
|
7
|
+
*/
|
|
8
|
+
const EditorWhereContext = React.createContext(void 0);
|
|
9
|
+
|
|
10
|
+
//#endregion
|
|
11
|
+
export { EditorWhereContext };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { useProjectUuid } from "../../lib/auth.js";
|
|
2
1
|
import { localizedPath } from "../../lib/locale-path.js";
|
|
3
2
|
import { useViewLocale } from "../../lib/view-locale-context.js";
|
|
4
3
|
import { useLocation, useNavigate } from "../navigation/navigation.js";
|
|
4
|
+
import { useProjectUuid } from "../../lib/auth.js";
|
|
5
5
|
import { reads, useStudioCache } from "../../lib/studio-reads.js";
|
|
6
6
|
import { previewStore, sameEditingOwner } from "../preview/previewStore.js";
|
|
7
7
|
import { fieldTypesDictionary } from "../../core/lib/fieldTypes.js";
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { placedRecords } from "../../lib/normalized-data.js";
|
|
2
|
+
import { reads, useReadQuery } from "../../lib/studio-reads.js";
|
|
3
|
+
import { useBlockDefinition, useCollectionDefinition } from "../../lib/studio-definitions.js";
|
|
4
|
+
import { isBlockPlacement, previewStore, selectionBlockId, selectionForOwner, selectionItemId } from "../preview/previewStore.js";
|
|
5
|
+
import { entityName } from "../preview/entityName.js";
|
|
6
|
+
import { contentFieldSchema } from "../preview/components/contentFieldSchema.js";
|
|
7
|
+
import { formatFieldName } from "../preview/components/ItemFieldsEditor.js";
|
|
8
|
+
import { getSchemaForItem } from "../preview/components/SelectionEditor.js";
|
|
9
|
+
import { c } from "react/compiler-runtime";
|
|
10
|
+
import { useSelector } from "@xstate/store-react";
|
|
11
|
+
|
|
12
|
+
//#region src/features/studio/useEditorSelection.ts
|
|
13
|
+
/** The owner the page the editor looks at edits, as the editing frame names it. */
|
|
14
|
+
function ownerOf(where) {
|
|
15
|
+
if (where?.on !== "page") return null;
|
|
16
|
+
if (where.layoutId != null) return {
|
|
17
|
+
kind: "layout",
|
|
18
|
+
layoutId: where.layoutId
|
|
19
|
+
};
|
|
20
|
+
if (where.pageId != null) return {
|
|
21
|
+
kind: "page",
|
|
22
|
+
pageId: where.pageId
|
|
23
|
+
};
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
/** The selection as the agent reads it, from the parts the studio loaded. */
|
|
27
|
+
function editorSelectionOf({ selection, block, items, schema, records, recordSchema }) {
|
|
28
|
+
const fieldLabel = (fieldSchema, fieldName) => contentFieldSchema(fieldSchema, fieldName)?.title ?? formatFieldName(fieldName);
|
|
29
|
+
const path = [];
|
|
30
|
+
const blockId = selectionBlockId(selection) ?? void 0;
|
|
31
|
+
if (blockId) path.push(block?.title ?? "Block");
|
|
32
|
+
for (const item of items) path.push(entityName(item, "Item"));
|
|
33
|
+
const recordSelected = selection.type === "record" || selection.type === "record-field";
|
|
34
|
+
if (recordSelected) path.push(...records.length > 0 ? records.map((record) => record.title || "Record") : ["Record"]);
|
|
35
|
+
let fieldName;
|
|
36
|
+
if (selection.type === "block-field" || selection.type === "item-field") {
|
|
37
|
+
fieldName = selection.fieldName;
|
|
38
|
+
path.push(fieldLabel(schema, fieldName));
|
|
39
|
+
} else if (selection.type === "record-field") {
|
|
40
|
+
fieldName = selection.recordFieldName;
|
|
41
|
+
path.push(fieldLabel(recordSchema, fieldName));
|
|
42
|
+
}
|
|
43
|
+
const itemId = selectionItemId(selection) ?? void 0;
|
|
44
|
+
const recordId = recordSelected ? selection.nested?.recordId ?? selection.recordId : void 0;
|
|
45
|
+
return {
|
|
46
|
+
path,
|
|
47
|
+
...blockId ? { blockId } : {},
|
|
48
|
+
...itemId ? { itemId } : {},
|
|
49
|
+
...recordId ? { recordId } : {},
|
|
50
|
+
...fieldName ? { fieldName } : {}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* What the editor has selected on the page they look at, as the agent reads it, or undefined
|
|
55
|
+
* with nothing selected there.
|
|
56
|
+
*/
|
|
57
|
+
function useEditorSelection(where) {
|
|
58
|
+
const $ = c(12);
|
|
59
|
+
let t0;
|
|
60
|
+
if ($[0] !== where) {
|
|
61
|
+
t0 = ownerOf(where);
|
|
62
|
+
$[0] = where;
|
|
63
|
+
$[1] = t0;
|
|
64
|
+
} else t0 = $[1];
|
|
65
|
+
const owner = t0;
|
|
66
|
+
let t1;
|
|
67
|
+
if ($[2] !== owner) {
|
|
68
|
+
t1 = (state) => selectionForOwner(state.context, owner);
|
|
69
|
+
$[2] = owner;
|
|
70
|
+
$[3] = t1;
|
|
71
|
+
} else t1 = $[3];
|
|
72
|
+
const selection = useSelector(previewStore, t1);
|
|
73
|
+
const blockId = selectionBlockId(selection);
|
|
74
|
+
const itemId = selectionItemId(selection);
|
|
75
|
+
const t2 = blockId != null;
|
|
76
|
+
let t3;
|
|
77
|
+
if ($[4] !== t2) {
|
|
78
|
+
t3 = { enabled: t2 };
|
|
79
|
+
$[4] = t2;
|
|
80
|
+
$[5] = t3;
|
|
81
|
+
} else t3 = $[5];
|
|
82
|
+
const { data: bundle } = useReadQuery(reads.blockBundle(blockId), t3);
|
|
83
|
+
const blockDef = useBlockDefinition(bundle?.block.type);
|
|
84
|
+
bundle?.repeatableItems;
|
|
85
|
+
let t4;
|
|
86
|
+
if ($[6] !== bundle?.repeatableItems) {
|
|
87
|
+
t4 = bundle?.repeatableItems ?? [];
|
|
88
|
+
$[6] = bundle?.repeatableItems;
|
|
89
|
+
$[7] = t4;
|
|
90
|
+
} else t4 = $[7];
|
|
91
|
+
let t5;
|
|
92
|
+
if ($[8] !== t4) {
|
|
93
|
+
t5 = new Map(t4.map(_temp));
|
|
94
|
+
$[8] = t4;
|
|
95
|
+
$[9] = t5;
|
|
96
|
+
} else t5 = $[9];
|
|
97
|
+
const itemsMap = t5;
|
|
98
|
+
const items = [];
|
|
99
|
+
for (let item_0 = itemId ? itemsMap.get(itemId) : void 0; item_0;) {
|
|
100
|
+
items.unshift(item_0);
|
|
101
|
+
item_0 = item_0.parentItemId ? itemsMap.get(item_0.parentItemId) : void 0;
|
|
102
|
+
}
|
|
103
|
+
const schema = blockDef && itemId ? getSchemaForItem(blockDef.contentSchema, itemId, itemsMap) : blockDef?.contentSchema;
|
|
104
|
+
const records = [];
|
|
105
|
+
if ((selection?.type === "record" || selection?.type === "record-field") && isBlockPlacement(selection)) {
|
|
106
|
+
const placer = itemId ? items.at(-1) : bundle?.block;
|
|
107
|
+
let t6;
|
|
108
|
+
if ($[10] !== selection.recordId) {
|
|
109
|
+
t6 = (record) => record.id === selection.recordId;
|
|
110
|
+
$[10] = selection.recordId;
|
|
111
|
+
$[11] = t6;
|
|
112
|
+
} else t6 = $[11];
|
|
113
|
+
const outer = placedRecords(placer?.references, selection.fieldName).find(t6);
|
|
114
|
+
if (outer) records.push(outer);
|
|
115
|
+
const { nested } = selection;
|
|
116
|
+
const linked = nested && placedRecords(outer?.references, nested.fieldName).find((record_0) => record_0.id === nested.recordId);
|
|
117
|
+
if (linked) records.push(linked);
|
|
118
|
+
}
|
|
119
|
+
const recordSchema = useCollectionDefinition(records.at(-1)?.collectionId)?.contentSchema;
|
|
120
|
+
if (!selection) return;
|
|
121
|
+
return editorSelectionOf({
|
|
122
|
+
selection,
|
|
123
|
+
block: blockDef,
|
|
124
|
+
items,
|
|
125
|
+
schema,
|
|
126
|
+
records,
|
|
127
|
+
recordSchema
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function _temp(item) {
|
|
131
|
+
return [item.id, item];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
//#endregion
|
|
135
|
+
export { editorSelectionOf, useEditorSelection };
|