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.
- package/dist/core/createApp.d.ts +28 -28
- package/dist/core/createLayout.d.ts +1 -1
- package/dist/core/derivedRoutes.js +3 -30
- package/dist/core/editing/createEditableBlock.d.ts +604 -604
- package/dist/features/canvas/canvasCamera.js +11 -2
- package/dist/features/canvas/useCanvasCamera.js +14 -10
- package/dist/features/page/CuratedPageContent.js +2 -1
- package/dist/features/page/UnplacedBlockContent.js +52 -0
- package/dist/features/preview/components/PreviewPanel.js +40 -12
- package/dist/features/preview/components/SidebarStack.js +78 -9
- package/dist/features/preview/strayCaretGuard.js +34 -0
- package/dist/features/provider/CoreCamoxProvider.js +5 -3
- package/dist/features/routes/pageRuntime.d.ts +2 -0
- package/dist/features/routes/pageRuntime.js +8 -5
- package/dist/features/runtime/pageApp.js +111 -74
- package/dist/features/runtime/pageClient.js +22 -2
- package/dist/features/runtime/runtime.d.ts +10 -0
- package/dist/features/runtime/runtime.js +314 -4
- package/dist/features/runtime/runtimeRoutes.d.ts +5 -0
- package/dist/features/runtime/runtimeRoutes.js +5 -0
- package/dist/features/studio/components/ChatWidget.js +88 -62
- package/dist/features/studio/components/ConnectAgent.js +313 -0
- package/dist/features/studio/components/Patrol.js +455 -205
- package/dist/features/studio/components/ReviewDraftSheet.js +431 -334
- package/dist/features/studio/components/Squareling.js +74 -41
- package/dist/features/studio/components/ThreadComposer.js +130 -107
- package/dist/features/studio/components/ThreadMessages.js +82 -13
- package/dist/features/studio/components/clientLogoPaths.js +10 -0
- package/dist/features/studio/findingSentence.js +37 -0
- package/dist/features/studio/reportSentence.js +15 -0
- package/dist/features/studio/studioStore.js +23 -1
- package/dist/features/studio/workingSentence.js +8 -0
- package/dist/lib/api-client.d.ts +1 -0
- package/dist/lib/auth.js +34 -32
- package/dist/lib/queries.js +9 -1
- package/dist/lib/server-auth-cookie.js +17 -4
- package/dist/lib/studio-reads.d.ts +1 -1
- package/dist/lib/studio-reads.js +5 -1
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- 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. */
|
package/dist/lib/api-client.d.ts
CHANGED
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(
|
|
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
|
|
260
|
-
if ($[0] !== hydrated || $[1] !== initialAuthenticated) {
|
|
261
|
-
|
|
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] =
|
|
265
|
-
|
|
266
|
-
|
|
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
|
|
270
|
-
if ($[
|
|
271
|
-
|
|
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
|
-
$[
|
|
276
|
-
} else
|
|
277
|
-
return
|
|
277
|
+
$[4] = t4;
|
|
278
|
+
} else t4 = $[4];
|
|
279
|
+
return t4;
|
|
278
280
|
}
|
|
279
281
|
if (!tracksSession) {
|
|
280
|
-
const
|
|
281
|
-
let
|
|
282
|
-
if ($[
|
|
283
|
-
|
|
282
|
+
const t4 = !hydrated;
|
|
283
|
+
let t5;
|
|
284
|
+
if ($[5] !== t4) {
|
|
285
|
+
t5 = {
|
|
284
286
|
isAuthenticated: false,
|
|
285
|
-
isLoading:
|
|
287
|
+
isLoading: t4
|
|
286
288
|
};
|
|
287
|
-
$[4] = t3;
|
|
288
289
|
$[5] = t4;
|
|
289
|
-
|
|
290
|
-
|
|
290
|
+
$[6] = t5;
|
|
291
|
+
} else t5 = $[6];
|
|
292
|
+
return t5;
|
|
291
293
|
}
|
|
292
294
|
const useInitial = !hydrated || isPending;
|
|
293
|
-
const
|
|
294
|
-
const
|
|
295
|
-
let
|
|
296
|
-
if ($[
|
|
297
|
-
|
|
298
|
-
isAuthenticated:
|
|
299
|
-
isLoading:
|
|
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
|
-
|
|
305
|
-
|
|
305
|
+
$[9] = t6;
|
|
306
|
+
} else t6 = $[9];
|
|
307
|
+
return t6;
|
|
306
308
|
}
|
|
307
309
|
function _temp3() {
|
|
308
310
|
return false;
|
package/dist/lib/queries.js
CHANGED
|
@@ -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
|
-
|
|
24
|
-
|
|
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(
|
|
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. */
|
package/dist/lib/studio-reads.js
CHANGED
|
@@ -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({
|
|
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