camox 0.71.0 → 0.74.1

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 (104) hide show
  1. package/dist/core/createApp.d.ts +4 -103
  2. package/dist/core/createApp.js +3 -24
  3. package/dist/core/createBlock.d.ts +2 -2
  4. package/dist/core/createBlock.js +41 -185
  5. package/dist/core/createLayout.d.ts +6 -77
  6. package/dist/core/createLayout.js +12 -50
  7. package/dist/core/editing/createEditableBlock.d.ts +9 -75
  8. package/dist/core/editing/createEditableBlock.js +258 -640
  9. package/dist/core/hooks/useIsEditable.js +2 -2
  10. package/dist/core/lib/artifactData.js +8 -3
  11. package/dist/core/lib/contentType.d.ts +23 -38
  12. package/dist/core/lib/contentType.js +34 -62
  13. package/dist/core/lib/iconTypes.d.ts +0 -3
  14. package/dist/core/lib/icons.js +63 -51
  15. package/dist/core/lib/recordScope.js +1 -1
  16. package/dist/features/canvas/CanvasOverlays.js +94 -176
  17. package/dist/features/canvas/CanvasPageFrame.js +62 -68
  18. package/dist/features/canvas/CanvasPreviewPageSlot.js +1 -3
  19. package/dist/features/canvas/canvasOverlayGeometry.js +1 -7
  20. package/dist/features/canvas/sidebar/CuratedPageInspector.js +3 -21
  21. package/dist/features/canvas/sidebar/LayoutPageBlocks.js +1 -2
  22. package/dist/features/canvas/useCanvasCamera.js +1 -1
  23. package/dist/features/canvas/useCanvasFrame.js +1 -1
  24. package/dist/features/content/ContentCollection.js +2 -2
  25. package/dist/features/content/collection-form.js +6 -7
  26. package/dist/features/page/CuratedPageContent.js +15 -24
  27. package/dist/features/page/UnplacedBlockContent.js +1 -6
  28. package/dist/features/preview/CamoxPreview.js +30 -33
  29. package/dist/features/preview/EditablePageContent.js +131 -151
  30. package/dist/features/preview/components/BlockActionsPopover.js +43 -152
  31. package/dist/features/preview/components/CanvasPreview.js +2 -2
  32. package/dist/features/preview/components/Frame.js +3 -3
  33. package/dist/features/preview/components/IconFieldEditor.js +1 -1
  34. package/dist/features/preview/components/ItemFieldsEditor.js +1 -3
  35. package/dist/features/preview/components/Overlays.js +18 -84
  36. package/dist/features/preview/components/PageInfo.js +121 -98
  37. package/dist/features/preview/components/PageTree.js +57 -103
  38. package/dist/features/preview/components/PreviewPanel.js +8 -11
  39. package/dist/features/preview/components/RecordCombobox.js +65 -78
  40. package/dist/features/preview/components/ReferenceFieldEditor.js +1 -19
  41. package/dist/features/preview/components/ReferenceListFieldEditor.js +1 -19
  42. package/dist/features/preview/components/RemovedBlockPlaceholder.js +2 -2
  43. package/dist/features/preview/components/SelectionEditor.js +6 -5
  44. package/dist/features/preview/components/useRepeatableItemActions.js +18 -24
  45. package/dist/features/preview/components/useUpdateBlockPosition.js +1 -1
  46. package/dist/features/preview/overlayMessages.js +1 -4
  47. package/dist/features/preview/previewStore.js +3 -23
  48. package/dist/features/renderer/RendererApp.js +17 -141
  49. package/dist/features/renderer/definitionAnswers.js +1 -8
  50. package/dist/features/renderer/rendererHost.js +1 -31
  51. package/dist/features/renderer/studioConnection.js +1 -25
  52. package/dist/features/routes/pageRuntime.js +15 -4
  53. package/dist/features/runtime/ClaimCard.js +192 -0
  54. package/dist/features/runtime/pageApp.js +5 -4
  55. package/dist/features/runtime/runtime.js +29 -8
  56. package/dist/features/runtime/worker.js +2 -2
  57. package/dist/features/runtime/workerRequest.d.ts +6 -0
  58. package/dist/features/runtime/workerRequest.js +13 -1
  59. package/dist/features/runtime/workerRuntime.d.ts +2 -2
  60. package/dist/features/runtime/workerRuntime.js +2 -2
  61. package/dist/features/studio/components/AgentSidebar.js +7 -7
  62. package/dist/features/studio/components/ChatWidget.js +142 -106
  63. package/dist/features/studio/components/ContentFindings.js +127 -230
  64. package/dist/features/studio/components/DeleteDraftDialog.js +112 -0
  65. package/dist/features/studio/components/DraftBar.js +98 -53
  66. package/dist/features/studio/components/DraftsControl.js +203 -190
  67. package/dist/features/studio/components/ReviewDraftDialog.js +670 -0
  68. package/dist/features/studio/components/{Patrol.js → Specialists.js} +291 -330
  69. package/dist/features/studio/components/Squareling.js +5 -5
  70. package/dist/features/studio/components/ThreadComposer.js +106 -127
  71. package/dist/features/studio/components/ThreadMessages.js +137 -45
  72. package/dist/features/studio/findingSentence.js +14 -12
  73. package/dist/features/studio/fixMessage.js +23 -0
  74. package/dist/features/studio/reportSentence.js +1 -1
  75. package/dist/features/studio/{patrollerBio.js → specialistBio.js} +8 -5
  76. package/dist/features/studio/studioStore.js +29 -15
  77. package/dist/features/studio/workingSentence.js +1 -1
  78. package/dist/features/vite/blockBoilerplate.js +1 -1
  79. package/dist/features/vite/definitionsSync.js +1 -8
  80. package/dist/lib/api-client.js +5 -1
  81. package/dist/lib/queries.js +5 -6
  82. package/dist/lib/studio-definitions.js +0 -2
  83. package/dist/lib/studio-reads.d.ts +1 -1
  84. package/dist/lib/studio-reads.js +5 -10
  85. package/dist/lib/use-thread.js +196 -138
  86. package/dist/package.js +1 -1
  87. package/dist/studio-overlays.css +0 -29
  88. package/dist/studio.css +1 -1
  89. package/package.json +4 -4
  90. package/skills/camox/SKILL.md +1 -1
  91. package/skills/camox/references/artifacts.md +4 -4
  92. package/skills/camox/references/block-definitions.md +21 -25
  93. package/skills/camox/references/dom-integrations.md +1 -1
  94. package/skills/camox/references/layout-definitions.md +3 -12
  95. package/skills/camox/references/routed-layouts.md +2 -2
  96. package/skills/camox-expand/SKILL.md +5 -5
  97. package/skills/camoxify/SKILL.md +4 -4
  98. package/dist/features/canvas/canvasInsertionSeams.js +0 -44
  99. package/dist/features/preview/components/AddBlockSheet.js +0 -314
  100. package/dist/features/preview/components/BlockPeek.js +0 -66
  101. package/dist/features/preview/components/BlockThumbnail.js +0 -281
  102. package/dist/features/preview/components/blockGridNavigation.js +0 -15
  103. package/dist/features/preview/referencePickerFocus.js +0 -29
  104. package/dist/features/studio/components/ReviewDraftSheet.js +0 -1587
@@ -1,16 +1,16 @@
1
- //#region src/features/studio/patrollerBio.ts
2
- /** What each patroller does, wherever it works. */
1
+ //#region src/features/studio/specialistBio.ts
2
+ /** What each specialist does, wherever it works. */
3
3
  const ABOUT = {
4
4
  seoManager: "Writes what search engines read: each page's SEO, and each file's alt text and filename.",
5
5
  translator: "Translates your website from its default language into every other one, so that each stays complete.",
6
6
  linkChecker: "Looks for links that lead nowhere, to your own pages or elsewhere, and suggests a fix when it can."
7
7
  };
8
- /** What a patroller does, as its profile card introduces it. */
8
+ /** What a specialist does, as its profile card introduces it. */
9
9
  function aboutSentence(id) {
10
10
  return ABOUT[id];
11
11
  }
12
12
  /**
13
- * When a patroller works where the editor is, by its duty there, in a draft or on Live, as its
13
+ * When a specialist works where the editor is, by its duty there, in a draft or on Live, as its
14
14
  * card's tag says it, and whether it runs there at all. In a project with a single locale, the
15
15
  * Translator waits for a second one.
16
16
  */
@@ -23,12 +23,15 @@ function whenTag(id, duty, inDraft, singleLocale) {
23
23
  label: "Runs once you add a language",
24
24
  runs: false
25
25
  };
26
- if (duty === "atPublish") return runs("Runs when you publish");
27
26
  if (duty === "asYouGo") {
28
27
  if (inDraft) return runs("Runs as you edit");
29
28
  if (id === "linkChecker") return runs("Runs every 6 hours");
30
29
  return runs("Runs while a release is translated");
31
30
  }
31
+ if (inDraft) return {
32
+ label: "Runs on Live only",
33
+ runs: false
34
+ };
32
35
  return {
33
36
  label: "Doesn't run on Live",
34
37
  runs: false
@@ -5,12 +5,13 @@ const studioStore = createStore({
5
5
  context: {
6
6
  isCommandPaletteOpen: false,
7
7
  commandPalettePages: [],
8
- isReviewDraftSheetOpen: false,
8
+ isReviewDraftDialogOpen: false,
9
9
  isDeleteDraftDialogOpen: false,
10
10
  localeDialog: null,
11
11
  websiteLocation: null,
12
- agentAsk: null,
13
- agentAsks: 0
12
+ agentMessages: [],
13
+ agentMessagesSent: 0,
14
+ agentWorkingIn: null
14
15
  },
15
16
  on: {
16
17
  openCommandPalette: (context) => {
@@ -45,16 +46,16 @@ const studioStore = createStore({
45
46
  commandPalettePages: context.commandPalettePages.slice(0, -1)
46
47
  };
47
48
  },
48
- openReviewDraftSheet: (context) => {
49
+ openReviewDraftDialog: (context) => {
49
50
  return {
50
51
  ...context,
51
- isReviewDraftSheetOpen: true
52
+ isReviewDraftDialogOpen: true
52
53
  };
53
54
  },
54
- closeReviewDraftSheet: (context) => {
55
+ closeReviewDraftDialog: (context) => {
55
56
  return {
56
57
  ...context,
57
- isReviewDraftSheetOpen: false
58
+ isReviewDraftDialogOpen: false
58
59
  };
59
60
  },
60
61
  openDeleteDraftDialog: (context) => {
@@ -81,21 +82,34 @@ const studioStore = createStore({
81
82
  localeDialog: null
82
83
  };
83
84
  },
84
- askAgent: (context, event) => {
85
+ sendToAgent: (context, event) => {
86
+ const id = context.agentMessagesSent + 1;
85
87
  return {
86
88
  ...context,
87
- isReviewDraftSheetOpen: false,
88
- agentAsk: {
89
+ isReviewDraftDialogOpen: false,
90
+ agentMessages: [...context.agentMessages, {
89
91
  text: event.text,
90
- id: context.agentAsks + 1
91
- },
92
- agentAsks: context.agentAsks + 1
92
+ id
93
+ }],
94
+ agentMessagesSent: id
93
95
  };
94
96
  },
95
- takeAgentAsk: (context) => {
97
+ takeAgentMessage: (context, event) => {
98
+ if (!context.agentMessages.some((message) => message.id === event.id)) return context;
96
99
  return {
97
100
  ...context,
98
- agentAsk: null
101
+ agentMessages: context.agentMessages.filter((message) => message.id !== event.id)
102
+ };
103
+ },
104
+ agentWorking: (context, event) => {
105
+ if (event.working) return {
106
+ ...context,
107
+ agentWorkingIn: event.draftId
108
+ };
109
+ if (context.agentWorkingIn !== event.draftId) return context;
110
+ return {
111
+ ...context,
112
+ agentWorkingIn: null
99
113
  };
100
114
  },
101
115
  rememberWebsiteLocation: (context, event) => {
@@ -35,7 +35,7 @@ function inLocales(locales, preposition) {
35
35
  return listed(parts);
36
36
  }
37
37
  /**
38
- * What a patroller is working on: "Translating hero into Spanish" for one subject, "Translating
38
+ * What a specialist is working on: "Translating hero into Spanish" for one subject, "Translating
39
39
  * 38 items into German and 12 into Spanish" for a burst, counted in each locale.
40
40
  */
41
41
  function workingSentence(id, working) {
@@ -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({ default: "Title" }),
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
- const { homepage } = definitionSet;
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";
@@ -61,6 +61,10 @@ function createStudioClient(apiUrl, draftHeaders) {
61
61
  });
62
62
  return createORPCClient(link);
63
63
  }
64
+ function getApiClient() {
65
+ if (!_client) throw new Error("API client not initialized — call initApiClient first");
66
+ return _client;
67
+ }
64
68
  function getOrpc() {
65
69
  if (!_orpc) throw new Error("API client not initialized — call initApiClient first");
66
70
  return _orpc;
@@ -79,4 +83,4 @@ function getContentWriteHeaders() {
79
83
  }
80
84
 
81
85
  //#endregion
82
- export { getApiUrl, getContentWriteHeaders, getDraftReadClient, getOrpc, initApiClient };
86
+ export { getApiClient, getApiUrl, getContentWriteHeaders, getDraftReadClient, getOrpc, initApiClient };
@@ -51,12 +51,12 @@ const draftMutations = {
51
51
  revertToLive: () => getOrpc().drafts.revertToLive.mutationOptions()
52
52
  };
53
53
  /**
54
- * What members do with a patroller's finding (ADR 0034): apply its fix in the draft viewed, or
54
+ * What members do with a specialist's finding (ADR 0034): apply its fix in the draft viewed, or
55
55
  * dismiss it for the whole project.
56
56
  */
57
- const patrolMutations = {
58
- applyFix: () => getOrpc().patrol.applyFix.mutationOptions(),
59
- dismissFinding: () => getOrpc().patrol.dismissFinding.mutationOptions()
57
+ const specialistMutations = {
58
+ applyFix: () => getOrpc().specialists.applyFix.mutationOptions(),
59
+ dismissFinding: () => getOrpc().specialists.dismissFinding.mutationOptions()
60
60
  };
61
61
  /** Adding and removing locales: content writes, so on Live they start a draft (ADR 0015). */
62
62
  const localeMutations = {
@@ -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(),
@@ -139,4 +138,4 @@ const fileMutations = {
139
138
  };
140
139
 
141
140
  //#endregion
142
- export { blockMutations, collectionMutations, draftMutations, fileMutations, localeMutations, pageMutations, patrolMutations, projectMutations, repeatableItemMutations };
141
+ export { blockMutations, collectionMutations, draftMutations, fileMutations, localeMutations, pageMutations, projectMutations, repeatableItemMutations, specialistMutations };
@@ -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
  }));
@@ -6,7 +6,7 @@ import { ApiClient } from "./api-client.js";
6
6
  import "./queries.js";
7
7
  import "react";
8
8
  import "@camox/api-contract/query-keys";
9
- import "@camox/api-contract/patrol";
9
+ import "@camox/api-contract/specialists";
10
10
  import { QueryClient } from "@tanstack/react-query";
11
11
  //#region src/lib/studio-reads.d.ts
12
12
  type LayoutRead = Awaited<ReturnType<ApiClient["layouts"]["get"]>>;
@@ -6,7 +6,7 @@ import { useSwitchHold } from "./view-switch.js";
6
6
  import { c } from "react/compiler-runtime";
7
7
  import * as React from "react";
8
8
  import { inScope, queryKeys, scopeOfKey } from "@camox/api-contract/query-keys";
9
- import { PATROLLER_IDS } from "@camox/api-contract/patrol";
9
+ import { SPECIALIST_IDS } from "@camox/api-contract/specialists";
10
10
  import { useQueries, useQuery, useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
11
11
 
12
12
  //#region src/lib/studio-reads.ts
@@ -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,
@@ -208,12 +203,12 @@ const reads = {
208
203
  fetch: ({ apiIn, signal }, { projectId, draftId }) => apiIn(draftId).drafts.get({ projectId }, { signal }),
209
204
  staleTime: Infinity
210
205
  }),
211
- patrol: entry({
212
- key: ({ projectId }) => [...queryKeys.patrol.get, projectId],
206
+ specialists: entry({
207
+ key: ({ projectId }) => [...queryKeys.specialists.get, projectId],
213
208
  everyLocale: true,
214
- fetch: ({ api, signal }, { projectId }) => api.patrol.get({
209
+ fetch: ({ api, signal }, { projectId }) => api.specialists.get({
215
210
  projectId,
216
- patrollers: [...PATROLLER_IDS]
211
+ specialists: [...SPECIALIST_IDS]
217
212
  }, { signal })
218
213
  }),
219
214
  publishPreview: entry({