camox 0.54.0 → 0.57.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.
Files changed (50) hide show
  1. package/dist/features/canvas/CamoxCanvas.js +14 -11
  2. package/dist/features/canvas/CanvasLoadingScreen.js +1 -1
  3. package/dist/features/canvas/CanvasPageHeader.js +1 -1
  4. package/dist/features/canvas/canvasFrameDocument.js +13 -6
  5. package/dist/features/canvas/sidebar/CanvasViewHeader.js +1 -1
  6. package/dist/features/canvas/sidebar/{CanvasSidebar.js → ContentSidebar.js} +5 -5
  7. package/dist/features/canvas/sidebar/{CanvasSidebarFrame.js → ContentSidebarFrame.js} +4 -4
  8. package/dist/features/canvas/sidebar/{CanvasSidebarSkeleton.js → ContentSidebarSkeleton.js} +7 -7
  9. package/dist/features/preview/CamoxPreview.js +2 -2
  10. package/dist/features/preview/components/Frame.js +1 -18
  11. package/dist/features/preview/components/PreviewToolbar.js +1 -1
  12. package/dist/features/preview/components/SelectionEditor.js +2 -2
  13. package/dist/features/preview/components/SidebarStack.js +201 -116
  14. package/dist/features/preview/components/StudioEditingFallback.js +3 -3
  15. package/dist/features/preview/components/previewStyles.js +25 -1
  16. package/dist/features/renderer/RendererApp.js +55 -37
  17. package/dist/features/routes/pageRuntime.d.ts +1 -1
  18. package/dist/features/runtime/RuntimeChrome.js +4 -4
  19. package/dist/features/studio/components/AgentSidebar.js +56 -0
  20. package/dist/features/studio/components/ChatWidget.js +219 -0
  21. package/dist/features/studio/components/DraftsControl.js +17 -17
  22. package/dist/features/studio/components/Patrol.js +676 -0
  23. package/dist/features/studio/components/ReviewDraftSheet.js +38 -38
  24. package/dist/features/studio/components/Squareling.js +171 -84
  25. package/dist/features/studio/components/ThreadMessages.js +256 -136
  26. package/dist/features/studio/localeOptions.js +7 -3
  27. package/dist/features/studio/reportSentence.js +75 -0
  28. package/dist/features/studio/routes.js +2 -1
  29. package/dist/features/studio/showInCanvas.js +9 -2
  30. package/dist/features/studio/studioStore.js +5 -5
  31. package/dist/features/studio/workingSentence.js +55 -0
  32. package/dist/lib/queries.js +1 -1
  33. package/dist/lib/studio-reads.d.ts +1 -0
  34. package/dist/lib/studio-reads.js +5 -0
  35. package/dist/lib/use-thread.js +156 -190
  36. package/dist/package.js +1 -1
  37. package/dist/studio.css +1 -1
  38. package/package.json +4 -4
  39. package/skills/camox/SKILL.md +3 -10
  40. package/skills/camox/references/artifacts.md +2 -2
  41. package/skills/camox/references/block-definitions.md +1 -1
  42. package/skills/camox/references/layout-definitions.md +1 -1
  43. package/skills/camox/references/routed-layouts.md +2 -2
  44. package/skills/camox-cli/SKILL.md +15 -0
  45. package/skills/{camox → camox-cli}/references/cli-common.md +1 -1
  46. package/skills/{camox → camox-cli}/references/cli-content.md +2 -2
  47. package/skills/{camox → camox-cli}/references/cli-publishing.md +4 -4
  48. package/skills/camox-expand/SKILL.md +1 -1
  49. package/skills/camoxify/SKILL.md +1 -1
  50. package/dist/features/studio/components/ChatSidebar.js +0 -346
@@ -0,0 +1,219 @@
1
+ import { AuthContext } from "../../../lib/auth.js";
2
+ import { useCurrentDraftId, useDraftScope } from "../../../lib/draft-scope.js";
3
+ import { useNavigate } from "../../navigation/navigation.js";
4
+ import { reads, useReadQuery } from "../../../lib/studio-reads.js";
5
+ import { cn } from "../../../lib/utils.js";
6
+ import { BOTTOM_CARD_EDGES, CARD_BODY_EDGES } from "../../preview/components/SidebarStack.js";
7
+ import { FollowAgentContext } from "../followAgentContext.js";
8
+ import { useThread } from "../../../lib/use-thread.js";
9
+ import { ThreadComposer } from "./ThreadComposer.js";
10
+ import { ThreadMessages } from "./ThreadMessages.js";
11
+ import { c } from "react/compiler-runtime";
12
+ import * as React from "react";
13
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
14
+ import { EMPTY_THREAD_VIEW } from "@camox/api-contract/threads";
15
+
16
+ //#region src/features/studio/components/ChatWidget.tsx
17
+ /**
18
+ * The Agent Sidebar's Chat widget, where an editor works with Camox's agent in a thread. Elsewhere in the
19
+ * studio it is only hidden: the studio keeps following the editor's runs there. It follows
20
+ * where the studio is: the editor's own Live thread on Live, and the draft's thread in a draft.
21
+ * When the agent on Live hands the editor's request off to a draft, the studio that asked enters
22
+ * it, if it still shows Live; the card the Live turn ends on opens it too.
23
+ */
24
+ function ChatWidget(t0) {
25
+ const $ = c(6);
26
+ const { className } = t0;
27
+ let t1;
28
+ if ($[0] !== className) {
29
+ t1 = cn("flex flex-col", className);
30
+ $[0] = className;
31
+ $[1] = t1;
32
+ } else t1 = $[1];
33
+ let t2;
34
+ let t3;
35
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
36
+ t2 = /* @__PURE__ */ jsx("header", {
37
+ className: cn("bg-background flex h-11 min-w-0 shrink-0 items-center justify-center px-3", BOTTOM_CARD_EDGES),
38
+ children: /* @__PURE__ */ jsx("h2", {
39
+ className: "truncate text-sm font-medium",
40
+ children: "Agent"
41
+ })
42
+ });
43
+ t3 = /* @__PURE__ */ jsx("div", {
44
+ className: cn("bg-background flex min-h-0 flex-1 flex-col", CARD_BODY_EDGES),
45
+ children: /* @__PURE__ */ jsx(CurrentThread, {})
46
+ });
47
+ $[2] = t2;
48
+ $[3] = t3;
49
+ } else {
50
+ t2 = $[2];
51
+ t3 = $[3];
52
+ }
53
+ let t4;
54
+ if ($[4] !== t1) {
55
+ t4 = /* @__PURE__ */ jsxs("section", {
56
+ "aria-label": "Chat",
57
+ "data-chat-widget": true,
58
+ className: t1,
59
+ children: [t2, t3]
60
+ });
61
+ $[4] = t1;
62
+ $[5] = t4;
63
+ } else t4 = $[5];
64
+ return t4;
65
+ }
66
+ function CurrentThread() {
67
+ const $ = c(14);
68
+ const { apiUrl, projectUuid } = React.useContext(AuthContext);
69
+ let t0;
70
+ if ($[0] !== projectUuid) {
71
+ t0 = reads.project({ projectUuid });
72
+ $[0] = projectUuid;
73
+ $[1] = t0;
74
+ } else t0 = $[1];
75
+ const { data: project } = useReadQuery(t0);
76
+ const draftId = useCurrentDraftId();
77
+ const draftScope = useDraftScope();
78
+ const navigate = useNavigate();
79
+ let t1;
80
+ if ($[2] !== draftScope) {
81
+ t1 = (started) => draftScope.enterStarted(started);
82
+ $[2] = draftScope;
83
+ $[3] = t1;
84
+ } else t1 = $[3];
85
+ const enterDraft = t1;
86
+ let t2;
87
+ if ($[4] !== navigate) {
88
+ t2 = (next) => void navigate({
89
+ to: window.location.href,
90
+ draft: next
91
+ });
92
+ $[4] = navigate;
93
+ $[5] = t2;
94
+ } else t2 = $[5];
95
+ const openDraft = t2;
96
+ if (!project) {
97
+ let t3;
98
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
99
+ t3 = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ThreadMessages, { view: EMPTY_THREAD_VIEW }), /* @__PURE__ */ jsx(ThreadComposer, { disabled: true })] });
100
+ $[6] = t3;
101
+ } else t3 = $[6];
102
+ return t3;
103
+ }
104
+ const t3 = `${project.id}:${draftId ?? "live"}`;
105
+ let t4;
106
+ if ($[7] !== apiUrl || $[8] !== draftId || $[9] !== enterDraft || $[10] !== openDraft || $[11] !== project.id || $[12] !== t3) {
107
+ t4 = /* @__PURE__ */ jsx(Thread, {
108
+ apiUrl,
109
+ projectId: project.id,
110
+ draftId,
111
+ onEnterDraft: enterDraft,
112
+ onOpenDraft: openDraft
113
+ }, t3);
114
+ $[7] = apiUrl;
115
+ $[8] = draftId;
116
+ $[9] = enterDraft;
117
+ $[10] = openDraft;
118
+ $[11] = project.id;
119
+ $[12] = t3;
120
+ $[13] = t4;
121
+ } else t4 = $[13];
122
+ return t4;
123
+ }
124
+ function Thread(t0) {
125
+ const $ = c(26);
126
+ const { apiUrl, projectId, draftId, onEnterDraft, onOpenDraft } = t0;
127
+ let t1;
128
+ if ($[0] !== onEnterDraft) {
129
+ t1 = { onEnterDraft };
130
+ $[0] = onEnterDraft;
131
+ $[1] = t1;
132
+ } else t1 = $[1];
133
+ const { view, sending, send, stop, error, touched } = useThread(apiUrl, projectId, draftId, t1);
134
+ const follow = React.use(FollowAgentContext);
135
+ let t2;
136
+ if ($[2] !== follow) {
137
+ t2 = (batch) => follow?.receive(batch);
138
+ $[2] = follow;
139
+ $[3] = t2;
140
+ } else t2 = $[3];
141
+ const followTouched = React.useEffectEvent(t2);
142
+ let t3;
143
+ if ($[4] !== followTouched || $[5] !== touched) {
144
+ t3 = () => {
145
+ if (touched) followTouched(touched.batch);
146
+ };
147
+ $[4] = followTouched;
148
+ $[5] = touched;
149
+ $[6] = t3;
150
+ } else t3 = $[6];
151
+ let t4;
152
+ if ($[7] !== touched) {
153
+ t4 = [touched];
154
+ $[7] = touched;
155
+ $[8] = t4;
156
+ } else t4 = $[8];
157
+ React.useEffect(t3, t4);
158
+ let t5;
159
+ if ($[9] !== follow || $[10] !== send) {
160
+ t5 = (text) => {
161
+ follow?.resume();
162
+ send(text);
163
+ };
164
+ $[9] = follow;
165
+ $[10] = send;
166
+ $[11] = t5;
167
+ } else t5 = $[11];
168
+ const sendFollowing = t5;
169
+ let t6;
170
+ if ($[12] !== onOpenDraft || $[13] !== sending || $[14] !== view) {
171
+ t6 = /* @__PURE__ */ jsx(ThreadMessages, {
172
+ view,
173
+ sending,
174
+ onOpenDraft
175
+ });
176
+ $[12] = onOpenDraft;
177
+ $[13] = sending;
178
+ $[14] = view;
179
+ $[15] = t6;
180
+ } else t6 = $[15];
181
+ let t7;
182
+ if ($[16] !== error) {
183
+ t7 = error && /* @__PURE__ */ jsx("p", {
184
+ role: "alert",
185
+ className: "text-destructive px-2 pt-2 text-sm",
186
+ children: error
187
+ });
188
+ $[16] = error;
189
+ $[17] = t7;
190
+ } else t7 = $[17];
191
+ let t8;
192
+ if ($[18] !== sendFollowing || $[19] !== stop || $[20] !== view.running) {
193
+ t8 = /* @__PURE__ */ jsx(ThreadComposer, {
194
+ onSend: sendFollowing,
195
+ onStop: stop,
196
+ running: view.running
197
+ });
198
+ $[18] = sendFollowing;
199
+ $[19] = stop;
200
+ $[20] = view.running;
201
+ $[21] = t8;
202
+ } else t8 = $[21];
203
+ let t9;
204
+ if ($[22] !== t6 || $[23] !== t7 || $[24] !== t8) {
205
+ t9 = /* @__PURE__ */ jsxs(Fragment, { children: [
206
+ t6,
207
+ t7,
208
+ t8
209
+ ] });
210
+ $[22] = t6;
211
+ $[23] = t7;
212
+ $[24] = t8;
213
+ $[25] = t9;
214
+ } else t9 = $[25];
215
+ return t9;
216
+ }
217
+
218
+ //#endregion
219
+ export { ChatWidget };
@@ -7,7 +7,7 @@ import { cn } from "../../../lib/utils.js";
7
7
  import { studioStore } from "../studioStore.js";
8
8
  import { draftLabel, plural, timeAgo } from "../draftLabel.js";
9
9
  import { RenameDraftDialog } from "./RenameDraftDialog.js";
10
- import { DiscardDraftDialog, ReviewDraftSheet, useLeaveDraft } from "./ReviewDraftSheet.js";
10
+ import { DeleteDraftDialog, ReviewDraftSheet, useLeaveDraft } from "./ReviewDraftSheet.js";
11
11
  import { c } from "react/compiler-runtime";
12
12
  import * as React from "react";
13
13
  import { useSelector } from "@xstate/store-react";
@@ -99,7 +99,7 @@ function useDrafts() {
99
99
  * Picks what the studio is viewing, Live or a draft (#203). Live is read-only; the first edit
100
100
  * starts a draft. The localhost studio works only in the development draft, so it shows that
101
101
  * draft alone, with nothing to switch to (ADR 0006). The command palette offers the same actions,
102
- * and the picker hosts the draft's review and discard confirmation they open. A `disabled` picker
102
+ * and the picker hosts the draft's review and delete confirmation they open. A `disabled` picker
103
103
  * still names what the studio is viewing.
104
104
  */
105
105
  function DraftPicker(t0) {
@@ -110,7 +110,7 @@ function DraftPicker(t0) {
110
110
  const navigate = useNavigate();
111
111
  const leaveDraft = useLeaveDraft();
112
112
  const review = useSelector(studioStore, _temp);
113
- const discarding = useSelector(studioStore, _temp2);
113
+ const deleting = useSelector(studioStore, _temp2);
114
114
  const [menuOpen, setMenuOpen] = React.useState(false);
115
115
  const [renaming, setRenaming] = React.useState(null);
116
116
  let t2;
@@ -316,20 +316,20 @@ function DraftPicker(t0) {
316
316
  $[46] = t20;
317
317
  } else t20 = $[46];
318
318
  let t21;
319
- if ($[47] !== discarding || $[48] !== draftId || $[49] !== leaveDraft || $[50] !== projectId || $[51] !== review) {
319
+ if ($[47] !== deleting || $[48] !== draftId || $[49] !== leaveDraft || $[50] !== projectId || $[51] !== review) {
320
320
  t21 = draftId && projectId && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ReviewDraftSheet, {
321
321
  projectId,
322
322
  draftId,
323
323
  open: review.open,
324
324
  startRenaming: review.startRenaming,
325
325
  onOpenChange: _temp7
326
- }), /* @__PURE__ */ jsx(DiscardDraftDialog, {
326
+ }), /* @__PURE__ */ jsx(DeleteDraftDialog, {
327
327
  projectId,
328
- open: discarding,
328
+ open: deleting,
329
329
  onOpenChange: _temp8,
330
- onDiscarded: leaveDraft
330
+ onDeleted: leaveDraft
331
331
  })] });
332
- $[47] = discarding;
332
+ $[47] = deleting;
333
333
  $[48] = draftId;
334
334
  $[49] = leaveDraft;
335
335
  $[50] = projectId;
@@ -351,7 +351,7 @@ function DraftPicker(t0) {
351
351
  return t22;
352
352
  }
353
353
  function _temp8(open_1) {
354
- if (!open_1) studioStore.send({ type: "closeDiscardDraftDialog" });
354
+ if (!open_1) studioStore.send({ type: "closeDeleteDraftDialog" });
355
355
  }
356
356
  function _temp7(open_0) {
357
357
  if (!open_0) studioStore.send({ type: "closeReviewDraftSheet" });
@@ -364,20 +364,20 @@ function _temp5() {
364
364
  }
365
365
  function _temp4() {
366
366
  studioStore.send({ type: "closeReviewDraftSheet" });
367
- studioStore.send({ type: "closeDiscardDraftDialog" });
367
+ studioStore.send({ type: "closeDeleteDraftDialog" });
368
368
  }
369
369
  function _temp3(t0) {
370
370
  const { move } = t0;
371
371
  if (move === "started") toast.success("Started a new draft");
372
372
  }
373
373
  function _temp2(state_0) {
374
- return state_0.context.isDiscardDraftDialogOpen;
374
+ return state_0.context.isDeleteDraftDialogOpen;
375
375
  }
376
376
  function _temp(state) {
377
377
  return state.context.reviewDraftSheet;
378
378
  }
379
379
  /**
380
- * The current draft's pending changes, which open its review to publish or discard them. Live
380
+ * The current draft's pending changes, which open its review to publish or delete them. Live
381
381
  * has none, so it shows nothing there.
382
382
  */
383
383
  function PendingChanges() {
@@ -418,8 +418,8 @@ function _temp9() {
418
418
  return studioStore.send({ type: "openReviewDraftSheet" });
419
419
  }
420
420
  /**
421
- * The drafts controls' actions in the command palette, offered where the controls offer them. The palette only opens the review and the discard confirmation; it never publishes or
422
- * discards by itself.
421
+ * The drafts controls' actions in the command palette, offered where the controls offer them. The palette only opens the review and the delete confirmation; it never publishes or
422
+ * deletes by itself.
423
423
  */
424
424
  function useDraftsActions(t0) {
425
425
  const $ = c(7);
@@ -446,8 +446,8 @@ function useDraftsActions(t0) {
446
446
  execute: _temp10
447
447
  },
448
448
  {
449
- id: "discard-draft",
450
- label: "Discard draft…",
449
+ id: "delete-draft",
450
+ label: "Delete draft…",
451
451
  aliases: [
452
452
  "Delete draft",
453
453
  "Throw away changes",
@@ -546,7 +546,7 @@ function _temp12() {
546
546
  });
547
547
  }
548
548
  function _temp11() {
549
- return studioStore.send({ type: "openDiscardDraftDialog" });
549
+ return studioStore.send({ type: "openDeleteDraftDialog" });
550
550
  }
551
551
  function _temp10() {
552
552
  return studioStore.send({ type: "openReviewDraftSheet" });