camox 0.63.0 → 0.65.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 (41) hide show
  1. package/dist/core/createApp.d.ts +28 -28
  2. package/dist/core/createLayout.d.ts +1 -1
  3. package/dist/core/derivedRoutes.js +3 -30
  4. package/dist/core/editing/createEditableBlock.d.ts +604 -604
  5. package/dist/features/canvas/canvasCamera.js +11 -2
  6. package/dist/features/canvas/useCanvasCamera.js +14 -10
  7. package/dist/features/page/CuratedPageContent.js +2 -1
  8. package/dist/features/page/UnplacedBlockContent.js +52 -0
  9. package/dist/features/preview/components/PreviewPanel.js +40 -12
  10. package/dist/features/preview/components/SidebarStack.js +78 -9
  11. package/dist/features/preview/strayCaretGuard.js +34 -0
  12. package/dist/features/provider/CoreCamoxProvider.js +5 -3
  13. package/dist/features/routes/pageRuntime.d.ts +2 -0
  14. package/dist/features/routes/pageRuntime.js +8 -5
  15. package/dist/features/runtime/pageApp.js +111 -74
  16. package/dist/features/runtime/pageClient.js +22 -2
  17. package/dist/features/runtime/runtime.d.ts +10 -0
  18. package/dist/features/runtime/runtime.js +314 -4
  19. package/dist/features/runtime/runtimeRoutes.d.ts +5 -0
  20. package/dist/features/runtime/runtimeRoutes.js +5 -0
  21. package/dist/features/studio/components/ChatWidget.js +88 -62
  22. package/dist/features/studio/components/ConnectAgent.js +313 -0
  23. package/dist/features/studio/components/Patrol.js +455 -205
  24. package/dist/features/studio/components/ReviewDraftSheet.js +431 -334
  25. package/dist/features/studio/components/Squareling.js +74 -41
  26. package/dist/features/studio/components/ThreadComposer.js +130 -107
  27. package/dist/features/studio/components/ThreadMessages.js +82 -13
  28. package/dist/features/studio/components/clientLogoPaths.js +10 -0
  29. package/dist/features/studio/findingSentence.js +37 -0
  30. package/dist/features/studio/reportSentence.js +15 -0
  31. package/dist/features/studio/studioStore.js +23 -1
  32. package/dist/features/studio/workingSentence.js +8 -0
  33. package/dist/lib/api-client.d.ts +1 -0
  34. package/dist/lib/auth.js +34 -32
  35. package/dist/lib/queries.js +9 -1
  36. package/dist/lib/server-auth-cookie.js +17 -4
  37. package/dist/lib/studio-reads.d.ts +1 -1
  38. package/dist/lib/studio-reads.js +5 -1
  39. package/dist/package.js +1 -1
  40. package/dist/studio.css +1 -1
  41. package/package.json +15 -4
@@ -26,6 +26,21 @@ const PHRASES = {
26
26
  publishedCatchUp: {
27
27
  done: "Published the caught-up translations",
28
28
  failed: "Couldn't publish the caught-up translations"
29
+ },
30
+ removedLink: {
31
+ done: "Removed a link in",
32
+ failed: "Couldn't remove a link in",
33
+ locale: "in"
34
+ },
35
+ fixedLink: {
36
+ done: "Fixed a link in",
37
+ failed: "Couldn't fix a link in",
38
+ locale: "in"
39
+ },
40
+ fixedMistake: {
41
+ done: "Fixed a typo in",
42
+ failed: "Couldn't fix a typo in",
43
+ locale: "in"
29
44
  }
30
45
  };
31
46
  /** A report as a sentence: "Wrote SEO for Pricing in German", or the text an AI wrote. */
@@ -11,7 +11,9 @@ const studioStore = createStore({
11
11
  },
12
12
  isDeleteDraftDialogOpen: false,
13
13
  localeDialog: null,
14
- websiteLocation: null
14
+ websiteLocation: null,
15
+ agentAsk: null,
16
+ agentAsks: 0
15
17
  },
16
18
  on: {
17
19
  openCommandPalette: (context) => {
@@ -88,6 +90,26 @@ const studioStore = createStore({
88
90
  localeDialog: null
89
91
  };
90
92
  },
93
+ askAgent: (context, event) => {
94
+ return {
95
+ ...context,
96
+ reviewDraftSheet: {
97
+ open: false,
98
+ startRenaming: false
99
+ },
100
+ agentAsk: {
101
+ text: event.text,
102
+ id: context.agentAsks + 1
103
+ },
104
+ agentAsks: context.agentAsks + 1
105
+ };
106
+ },
107
+ takeAgentAsk: (context) => {
108
+ return {
109
+ ...context,
110
+ agentAsk: null
111
+ };
112
+ },
91
113
  rememberWebsiteLocation: (context, event) => {
92
114
  const previous = context.websiteLocation;
93
115
  const { locale, path, search, hash } = event.location;
@@ -11,6 +11,14 @@ const PHRASES = {
11
11
  verb: "Writing SEO for",
12
12
  verbFor: { file: "Describing" },
13
13
  locale: "in"
14
+ },
15
+ linkChecker: {
16
+ verb: "Checking links in",
17
+ locale: "in"
18
+ },
19
+ proofreader: {
20
+ verb: "Proofreading",
21
+ locale: "in"
14
22
  }
15
23
  };
16
24
  /** The most locales a burst names; past it, the first are named and the rest counted. */
@@ -1,5 +1,6 @@
1
1
  import "./locale-path.js";
2
2
  import "./draft-scope.js";
3
+ import { createTanstackQueryUtils } from "@orpc/tanstack-query";
3
4
  import { Router } from "@camox/api-contract/router";
4
5
  import { RouterClient } from "@orpc/server";
5
6
  //#region src/lib/api-client.d.ts
package/dist/lib/auth.js CHANGED
@@ -251,58 +251,60 @@ function useSessionState(authClient, track) {
251
251
  return React.useSyncExternalStore(track ? subscribe : noSubscription, getSnapshot, getSnapshot);
252
252
  }
253
253
  function useAuthState() {
254
- const $ = c(9);
255
- const { authClient, initialAuthenticated: t0, exchangingToken: t1 } = useAuthContext();
254
+ const $ = c(10);
255
+ const { authClient, initialAuthenticated: t0, exchangingToken: t1, sessionless: t2 } = useAuthContext();
256
256
  const initialAuthenticated = t0 === void 0 ? false : t0;
257
257
  const exchangingToken = t1 === void 0 ? false : t1;
258
+ const sessionless = t2 === void 0 ? false : t2;
258
259
  const hydrated = React.useSyncExternalStore(subscribeToHydration, _temp2, _temp3);
259
- let t2;
260
- if ($[0] !== hydrated || $[1] !== initialAuthenticated) {
261
- t2 = initialAuthenticated || hydrated && hasStoredAuthCookie();
260
+ let t3;
261
+ if ($[0] !== hydrated || $[1] !== initialAuthenticated || $[2] !== sessionless) {
262
+ t3 = !sessionless && (initialAuthenticated || hydrated && hasStoredAuthCookie());
262
263
  $[0] = hydrated;
263
264
  $[1] = initialAuthenticated;
264
- $[2] = t2;
265
- } else t2 = $[2];
266
- const tracksSession = t2;
265
+ $[2] = sessionless;
266
+ $[3] = t3;
267
+ } else t3 = $[3];
268
+ const tracksSession = t3;
267
269
  const { data: session, isPending } = useSessionState(authClient, tracksSession);
268
270
  if (exchangingToken && !initialAuthenticated) {
269
- let t3;
270
- if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
271
- t3 = {
271
+ let t4;
272
+ if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
273
+ t4 = {
272
274
  isAuthenticated: false,
273
275
  isLoading: true
274
276
  };
275
- $[3] = t3;
276
- } else t3 = $[3];
277
- return t3;
277
+ $[4] = t4;
278
+ } else t4 = $[4];
279
+ return t4;
278
280
  }
279
281
  if (!tracksSession) {
280
- const t3 = !hydrated;
281
- let t4;
282
- if ($[4] !== t3) {
283
- t4 = {
282
+ const t4 = !hydrated;
283
+ let t5;
284
+ if ($[5] !== t4) {
285
+ t5 = {
284
286
  isAuthenticated: false,
285
- isLoading: t3
287
+ isLoading: t4
286
288
  };
287
- $[4] = t3;
288
289
  $[5] = t4;
289
- } else t4 = $[5];
290
- return t4;
290
+ $[6] = t5;
291
+ } else t5 = $[6];
292
+ return t5;
291
293
  }
292
294
  const useInitial = !hydrated || isPending;
293
- const t3 = useInitial ? initialAuthenticated : !!session;
294
- const t4 = useInitial && !initialAuthenticated;
295
- let t5;
296
- if ($[6] !== t3 || $[7] !== t4) {
297
- t5 = {
298
- isAuthenticated: t3,
299
- isLoading: t4
295
+ const t4 = useInitial ? initialAuthenticated : !!session;
296
+ const t5 = useInitial && !initialAuthenticated;
297
+ let t6;
298
+ if ($[7] !== t4 || $[8] !== t5) {
299
+ t6 = {
300
+ isAuthenticated: t4,
301
+ isLoading: t5
300
302
  };
301
- $[6] = t3;
302
303
  $[7] = t4;
303
304
  $[8] = t5;
304
- } else t5 = $[8];
305
- return t5;
305
+ $[9] = t6;
306
+ } else t6 = $[9];
307
+ return t6;
306
308
  }
307
309
  function _temp3() {
308
310
  return false;
@@ -50,6 +50,14 @@ const draftMutations = {
50
50
  /** Drops the draft's copy of an entity it conflicts on, to use Live's version instead. */
51
51
  revertToLive: () => getOrpc().drafts.revertToLive.mutationOptions()
52
52
  };
53
+ /**
54
+ * What members do with a patroller's finding (ADR 0034): apply its fix in the draft viewed, or
55
+ * dismiss it for the whole project.
56
+ */
57
+ const patrolMutations = {
58
+ applyFix: () => getOrpc().patrol.applyFix.mutationOptions(),
59
+ dismissFinding: () => getOrpc().patrol.dismissFinding.mutationOptions()
60
+ };
53
61
  /** Adding and removing locales: content writes, so on Live they start a draft (ADR 0015). */
54
62
  const localeMutations = {
55
63
  add: () => getOrpc().locales.add.mutationOptions(),
@@ -131,4 +139,4 @@ const fileMutations = {
131
139
  };
132
140
 
133
141
  //#endregion
134
- export { blockMutations, collectionMutations, draftMutations, fileMutations, localeMutations, pageMutations, projectMutations, repeatableItemMutations };
142
+ export { blockMutations, collectionMutations, draftMutations, fileMutations, localeMutations, pageMutations, patrolMutations, projectMutations, repeatableItemMutations };
@@ -1,3 +1,5 @@
1
+ import { LOOK_TOKEN_COOKIE } from "@camox/api-contract/drafts";
2
+
1
3
  //#region src/lib/server-auth-cookie.ts
2
4
  const SERVER_AUTH_COOKIE_NAME = "camox_auth_cookie";
3
5
  /** How long the mirror lasts. The API still refuses a session that expired before it. */
@@ -20,14 +22,25 @@ function getServerAuthCookieHeader(headers) {
20
22
  }
21
23
  /** The mirror's session in a `Cookie` header's value, or `document.cookie`. */
22
24
  function readServerAuthCookie(cookieHeader) {
23
- const mirror = cookieHeader.split(";").map((part) => part.trim()).find((part) => part.startsWith(`${SERVER_AUTH_COOKIE_NAME}=`));
24
- if (!mirror) return "";
25
+ return readCookie(cookieHeader, SERVER_AUTH_COOKIE_NAME);
26
+ }
27
+ /**
28
+ * The look token a request carries in `LOOK_TOKEN_COOKIE` (ADR 0032), set by the browser the
29
+ * agent's `look` tool drives for the website's host only. Empty when there's none.
30
+ */
31
+ function getLookToken(headers) {
32
+ return readCookie(headers.get("Cookie") ?? "", LOOK_TOKEN_COOKIE);
33
+ }
34
+ /** The cookie `name`'s value in a `Cookie` header's value, decoded, or empty when there's none. */
35
+ function readCookie(cookieHeader, name) {
36
+ const cookie = cookieHeader.split(";").map((part) => part.trim()).find((part) => part.startsWith(`${name}=`));
37
+ if (!cookie) return "";
25
38
  try {
26
- return decodeURIComponent(mirror.slice(18));
39
+ return decodeURIComponent(cookie.slice(name.length + 1));
27
40
  } catch {
28
41
  return "";
29
42
  }
30
43
  }
31
44
 
32
45
  //#endregion
33
- export { SERVER_AUTH_COOKIE_NAME, buildClearServerAuthCookieHeader, buildServerAuthCookieHeader, getServerAuthCookieHeader, readServerAuthCookie };
46
+ export { SERVER_AUTH_COOKIE_NAME, buildClearServerAuthCookieHeader, buildServerAuthCookieHeader, getLookToken, getServerAuthCookieHeader, readServerAuthCookie };
@@ -6,8 +6,8 @@ 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 { QueryClient } from "@tanstack/react-query";
10
9
  import "@camox/api-contract/patrol";
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"]>>;
13
13
  /** A layout's structure: its blocks before and after the content of its pages. */
@@ -5,6 +5,7 @@ import { collectFileIds } from "./normalized-data.js";
5
5
  import { c } from "react/compiler-runtime";
6
6
  import * as React from "react";
7
7
  import { inScope, queryKeys, scopeOfKey } from "@camox/api-contract/query-keys";
8
+ import { PATROLLER_IDS } from "@camox/api-contract/patrol";
8
9
  import { useQueries, useQuery, useSuspenseQuery } from "@tanstack/react-query";
9
10
 
10
11
  //#region src/lib/studio-reads.ts
@@ -209,7 +210,10 @@ const reads = {
209
210
  patrol: entry({
210
211
  key: ({ projectId }) => [...queryKeys.patrol.get, projectId],
211
212
  everyLocale: true,
212
- fetch: ({ api, signal }, { projectId }) => api.patrol.get({ projectId }, { signal })
213
+ fetch: ({ api, signal }, { projectId }) => api.patrol.get({
214
+ projectId,
215
+ patrollers: [...PATROLLER_IDS]
216
+ }, { signal })
213
217
  }),
214
218
  publishPreview: entry({
215
219
  key: ({ draftId }) => [
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.63.0";
2
+ var version = "0.65.1";
3
3
 
4
4
  //#endregion
5
5
  export { version };