@valbuild/shared 0.151.0 → 0.152.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/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # @valbuild/shared
2
2
 
3
+ ## 0.152.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1019](https://github.com/valbuild/val/pull/1019) [`b9089c8`](https://github.com/valbuild/val/commit/b9089c8787da8075722cc4ef3672beb61b288af4) Thanks [@freekh](https://github.com/freekh)! - **What the design tab needed is removed with it.** The page's canvas bridge
8
+ now answers `read_page`, `screenshot_page` and a quick preview only to the
9
+ Studio at the page's own origin, and no longer asks the server whether another
10
+ origin is the site's design tab. The site's server no longer writes a
11
+ proposal's files or offers the `patch-file` route: code and content are
12
+ changed in the proposal's own Studio. The assistant's `build_proposal` no
13
+ longer takes a `reason`.
14
+
15
+ ## 0.152.0
16
+
17
+ ### Minor Changes
18
+
19
+ - [#1015](https://github.com/valbuild/val/pull/1015) [`08a3977`](https://github.com/valbuild/val/commit/08a39779dbe43702a72ae57cbf8cf29b14e64672) Thanks [@freekh](https://github.com/freekh)! - The Sketchpad covers several pages, builds what it shows, and can be linked to the content.
20
+
21
+ - **Route dividers.** A sketchpad is no longer about one page. A `--- /about` line starts the part about a page, so one sketch can cover a page and the pages it links to. Press a route to see that page beside the sketch, in the Studio's own live preview, which follows edits as they are made. A divider's menu changes its page, or adds a new one from a page type the site has (`/blog/[slug]`). A route the site has no page type for is allowed too, and is marked as needing code.
22
+ - **Start from a page.** An empty sketchpad offers to start from a page. The assistant writes that page into it, images and all, and changes nothing.
23
+ - **Build.** The button that sent the sketchpad to the assistant is now **Build**. It sends the sketchpad as a card in the chat (press it to open the sketchpad), with a request to change the pages to match the sketch. It is disabled while the sketch is empty.
24
+ - **Images that exist.** A box shows an image from a gallery, from the site's content, or one uploaded to the chat, and the picker offers exactly those, with search and Upload (which puts the file in the chat first). A box naming any other image says so. When the assistant writes a sketch with an image that is not in the project, the write is refused. Images are named by their content path (`/public/val/hero.webp`) and shown where the site serves them, including uploads that are not published yet.
25
+ - **Block types.** A box's kind is a combobox of the kinds of section the site's pages have, read from the schema. Any other word is allowed, and is marked as a new type that needs code.
26
+ - **Drag.** Blocks, rows, columns and images can be dragged to a new place. Columns share a row equally, so the width controls are gone.
27
+ - **Highlights.** The assistant can point at blocks, in a colour and with a note (for example, the ones that need code), with `highlight_sketchpad_blocks`. The highlights can be cleared, by the person or by the assistant.
28
+ - **Linked text (a try-out).** A heading or paragraph can be linked to a plain text field with `{field: <source path>}`. Typing in it then changes that field, as typing in the field would. The block shows what it is linked to and has an **Unlink** button. When the field was changed elsewhere, the block says so and offers the field's text. A sketchpad the assistant starts from a page links its text this way.
29
+ - **Converting images.** The assistant can convert an image in the chat to WebP, or scale it down, with `convert_session_image`, using the same encoder as the Studio's uploads.
30
+
31
+ ### Patch Changes
32
+
33
+ - [#1013](https://github.com/valbuild/val/pull/1013) [`3bb76d7`](https://github.com/valbuild/val/commit/3bb76d74d82b499aa15023838d63018a70fd7ce7) Thanks [@freekh](https://github.com/freekh)! - A save that the content service fails to take no longer looks like a successful one.
34
+
35
+ Before, when the content service answered a save with a server error (or could not be reached), the Studio treated the edit as invalid and dropped it: the field went back to its old value, and the status bar kept saying "All changes saved". Now:
36
+
37
+ - **Your edit is kept.** The field keeps what you typed.
38
+ - **The Studio says the save failed.** The status bar shows "Could not save" (never "All changes saved" while a save has failed or is still pending), and a notice says which service failed, with the service's own message under **Details**.
39
+ - **Try again** sends the same save again. The Studio also retries by itself in the background, so if you leave the tab open your changes are saved once the service is back.
40
+
41
+ Pressing Publish while a save has failed now says what failed, in the service's words, with a **Save again** button, instead of "Check the connection and try again".
42
+
43
+ Saves that the service refuses because of your plan, and saves that conflict with someone else's change, work as before.
44
+
45
+ Error messages from the content service also stop blaming your network. "Could not get your changes. It is most likely due to a network issue. Check your network connection" was shown even when the service had answered with a 500. These messages now say what actually happened (the service answered with an error, refused the request, or could not be reached from your site's server) and name the service. The status code and the service's response are kept as details for whoever needs to look into it. Publish failures now also show the service's own message, where they used to say "Unknown error".
46
+
3
47
  ## 0.151.0
4
48
 
5
49
  ### Patch Changes
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var getSitemapTree = require('../../dist/getSitemapTree-59c5ed5d.cjs.dev.js');
5
+ var getSitemapTree = require('../../dist/getSitemapTree-dc61b8b6.cjs.dev.js');
6
6
  require('../../dist/createForOfIteratorHelper-f2d7ac6d.cjs.dev.js');
7
7
  require('@valbuild/core');
8
8
 
@@ -31,7 +31,6 @@ exports.getPageRouterSitemapTree = getSitemapTree.getPageRouterSitemapTree;
31
31
  exports.getPageRouterSourceFolder = getSitemapTree.getPageRouterSourceFolder;
32
32
  exports.getPatternFromModuleFilePath = getSitemapTree.getPatternFromModuleFilePath;
33
33
  exports.getTanStackRouterSourceFolder = getSitemapTree.getTanStackRouterSourceFolder;
34
- exports.isDesignTabOrigin = getSitemapTree.isDesignTabOrigin;
35
34
  exports.isQuickPreviewFiles = getSitemapTree.isQuickPreviewFiles;
36
35
  exports.isTanStackRoutesFolder = getSitemapTree.isTanStackRoutesFolder;
37
36
  exports.isValCanvasFrame = getSitemapTree.isValCanvasFrame;
@@ -40,7 +39,6 @@ exports.isValCanvasStudioMessage = getSitemapTree.isValCanvasStudioMessage;
40
39
  exports.modifierLabel = getSitemapTree.modifierLabel;
41
40
  exports.pageLocationOf = getSitemapTree.pageLocationOf;
42
41
  exports.parseRoutePattern = getSitemapTree.parseRoutePattern;
43
- exports.quickPreviewSiteOrigin = getSitemapTree.quickPreviewSiteOrigin;
44
42
  exports.readPageSnapshot = getSitemapTree.readPageSnapshot;
45
43
  exports.restoreScroll = getSitemapTree.restoreScroll;
46
44
  exports.screenshotPage = getSitemapTree.screenshotPage;
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var getSitemapTree = require('../../dist/getSitemapTree-6b9024d1.cjs.prod.js');
5
+ var getSitemapTree = require('../../dist/getSitemapTree-d0942fca.cjs.prod.js');
6
6
  require('../../dist/createForOfIteratorHelper-9ca2078d.cjs.prod.js');
7
7
  require('@valbuild/core');
8
8
 
@@ -31,7 +31,6 @@ exports.getPageRouterSitemapTree = getSitemapTree.getPageRouterSitemapTree;
31
31
  exports.getPageRouterSourceFolder = getSitemapTree.getPageRouterSourceFolder;
32
32
  exports.getPatternFromModuleFilePath = getSitemapTree.getPatternFromModuleFilePath;
33
33
  exports.getTanStackRouterSourceFolder = getSitemapTree.getTanStackRouterSourceFolder;
34
- exports.isDesignTabOrigin = getSitemapTree.isDesignTabOrigin;
35
34
  exports.isQuickPreviewFiles = getSitemapTree.isQuickPreviewFiles;
36
35
  exports.isTanStackRoutesFolder = getSitemapTree.isTanStackRoutesFolder;
37
36
  exports.isValCanvasFrame = getSitemapTree.isValCanvasFrame;
@@ -40,7 +39,6 @@ exports.isValCanvasStudioMessage = getSitemapTree.isValCanvasStudioMessage;
40
39
  exports.modifierLabel = getSitemapTree.modifierLabel;
41
40
  exports.pageLocationOf = getSitemapTree.pageLocationOf;
42
41
  exports.parseRoutePattern = getSitemapTree.parseRoutePattern;
43
- exports.quickPreviewSiteOrigin = getSitemapTree.quickPreviewSiteOrigin;
44
42
  exports.readPageSnapshot = getSitemapTree.readPageSnapshot;
45
43
  exports.restoreScroll = getSitemapTree.restoreScroll;
46
44
  exports.screenshotPage = getSitemapTree.screenshotPage;
@@ -1,3 +1,3 @@
1
- export { D as DEFAULT_CANVAS_SELECTION, e as DEFAULT_CANVAS_SELECTION_SOFT, Q as QUICK_PREVIEW_PARAM, v as QUICK_PREVIEW_RENDER_SCRIPT, u as QUICK_PREVIEW_SERVICE_WORKER_PATH, z as QUICK_PREVIEW_SERVICE_WORKER_SOURCE, x as QUICK_PREVIEW_STORE_MESSAGE, b as VAL_AI_SESSION_STORAGE_KEY, d as VAL_CANVAS_MESSAGE, c as VAL_CANVAS_PARAM, V as VAL_CONFIG_SESSION_STORAGE_KEY, a as VAL_THEME_SESSION_STORAGE_KEY, j as attachElementPicker, k as createPickerOverlay, h as describeElement, l as elementLabel, q as findBySelector, G as formatRoutePattern, H as getNextAppRouterSourceFolder, L as getPageRouterSitemapTree, J as getPageRouterSourceFolder, M as getPatternFromModuleFilePath, I as getTanStackRouterSourceFolder, E as isDesignTabOrigin, y as isQuickPreviewFiles, K as isTanStackRoutesFolder, g as isValCanvasFrame, i as isValCanvasPageMessage, f as isValCanvasStudioMessage, m as modifierLabel, p as pageLocationOf, F as parseRoutePattern, C as quickPreviewSiteOrigin, o as readPageSnapshot, r as restoreScroll, t as screenshotPage, s as startElementPicking, A as storeQuickPreview, n as watchPageLocation, B as withQuickPreviewParam, w as withValCanvasParam } from '../../dist/getSitemapTree-3c1b9e57.esm.js';
1
+ export { D as DEFAULT_CANVAS_SELECTION, e as DEFAULT_CANVAS_SELECTION_SOFT, Q as QUICK_PREVIEW_PARAM, v as QUICK_PREVIEW_RENDER_SCRIPT, u as QUICK_PREVIEW_SERVICE_WORKER_PATH, z as QUICK_PREVIEW_SERVICE_WORKER_SOURCE, x as QUICK_PREVIEW_STORE_MESSAGE, b as VAL_AI_SESSION_STORAGE_KEY, d as VAL_CANVAS_MESSAGE, c as VAL_CANVAS_PARAM, V as VAL_CONFIG_SESSION_STORAGE_KEY, a as VAL_THEME_SESSION_STORAGE_KEY, j as attachElementPicker, k as createPickerOverlay, h as describeElement, l as elementLabel, q as findBySelector, E as formatRoutePattern, F as getNextAppRouterSourceFolder, J as getPageRouterSitemapTree, H as getPageRouterSourceFolder, K as getPatternFromModuleFilePath, G as getTanStackRouterSourceFolder, y as isQuickPreviewFiles, I as isTanStackRoutesFolder, g as isValCanvasFrame, i as isValCanvasPageMessage, f as isValCanvasStudioMessage, m as modifierLabel, p as pageLocationOf, C as parseRoutePattern, o as readPageSnapshot, r as restoreScroll, t as screenshotPage, s as startElementPicking, A as storeQuickPreview, n as watchPageLocation, B as withQuickPreviewParam, w as withValCanvasParam } from '../../dist/getSitemapTree-2b22cf1b.esm.js';
2
2
  import '../../dist/createForOfIteratorHelper-9b80f1a2.esm.js';
3
3
  import '@valbuild/core';
@@ -1265,6 +1265,22 @@ export declare const Api: {
1265
1265
  }, z.core.$strip>]>;
1266
1266
  headVersion: z.ZodOptional<z.ZodNumber>;
1267
1267
  }, z.core.$strip>;
1268
+ }, z.core.$strip>, z.ZodObject<{
1269
+ status: z.ZodLiteral<502>;
1270
+ json: z.ZodObject<{
1271
+ type: z.ZodLiteral<"service-error">;
1272
+ message: z.ZodString;
1273
+ details: z.ZodOptional<z.ZodString>;
1274
+ newPatchIds: z.ZodArray<z.ZodString & z.ZodType<import("@valbuild/core").PatchId, string, z.core.$ZodTypeInternals<import("@valbuild/core").PatchId, string>>>;
1275
+ parentRef: z.ZodUnion<readonly [z.ZodObject<{
1276
+ type: z.ZodLiteral<"head">;
1277
+ headBaseSha: z.ZodString;
1278
+ }, z.core.$strip>, z.ZodObject<{
1279
+ type: z.ZodLiteral<"patch">;
1280
+ patchId: z.ZodString & z.ZodType<import("@valbuild/core").PatchId, string, z.core.$ZodTypeInternals<import("@valbuild/core").PatchId, string>>;
1281
+ }, z.core.$strip>]>;
1282
+ headVersion: z.ZodOptional<z.ZodNumber>;
1283
+ }, z.core.$strip>;
1268
1284
  }, z.core.$strip>, z.ZodObject<{
1269
1285
  status: z.ZodLiteral<200>;
1270
1286
  json: z.ZodObject<{
@@ -1315,6 +1331,7 @@ export declare const Api: {
1315
1331
  error: z.ZodObject<{
1316
1332
  message: z.ZodString;
1317
1333
  }, z.core.$strip>;
1334
+ details: z.ZodOptional<z.ZodString>;
1318
1335
  }, z.core.$strip>;
1319
1336
  }, z.core.$strip>, z.ZodObject<{
1320
1337
  status: z.ZodLiteral<200>;
@@ -1,2 +1,2 @@
1
- export declare const toolNames: readonly ["get_all_schema", "get_source", "search_content", "validate_content", "create_patch", "add_session_image_to_gallery", "remove_image_gallery_entry", "navigate_to", "get_current_context", "get_patches", "get_source_path_from_route", "set_session_name", "show_compare_view", "ask_user_question", "duplicate_source", "empty_at_path", "count_entries", "get_record_keys", "list_sketchpads", "create_sketchpad", "read_sketchpad", "write_sketchpad"];
1
+ export declare const toolNames: readonly ["get_all_schema", "get_source", "search_content", "validate_content", "create_patch", "add_session_image_to_gallery", "remove_image_gallery_entry", "convert_session_image", "navigate_to", "get_current_context", "get_patches", "get_source_path_from_route", "set_session_name", "show_compare_view", "ask_user_question", "duplicate_source", "empty_at_path", "count_entries", "get_record_keys", "list_sketchpads", "create_sketchpad", "read_sketchpad", "write_sketchpad", "highlight_sketchpad_blocks", "clear_sketchpad_highlights"];
2
2
  export type ToolName = (typeof toolNames)[number];
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Pointing at anything on a page, as Lovable's picker does: hover outlines
3
3
  * the element under the pointer, a click picks it, and the assistant is told
4
- * which (valbuild/home `docs/design-tab.md`).
4
+ * which.
5
5
  *
6
- * ANY element, not only what Val marks. The design tab changes code, and the
6
+ * ANY element, not only what Val marks. The assistant changes code, and the
7
7
  * thing a person wants changed is as often a wrapper, a gap or a button as a
8
8
  * field -- so a field's path is extra information when there is one
9
9
  * (`valPath`), never the condition for picking.
@@ -14,9 +14,8 @@
14
14
  *
15
15
  * Plain DOM, nothing of React's or the Studio's, and in `shared` because
16
16
  * both halves need it: the canvas bridge (`@valbuild/next`,
17
- * `@valbuild/tanstack`) runs it inside the proposal's page, which is another
18
- * origin than the design tab and the only place the page's elements can be
19
- * reached; the Studio's stories run it on a page of their own. Only the
17
+ * `@valbuild/tanstack`) runs it inside the page, the only place the page's
18
+ * elements can be reached; the Studio's stories run it on a page of their own. Only the
20
19
  * `PickedElement` crosses the frame (`valCanvasProtocol.ts`).
21
20
  */
22
21
  export type PickedElement = {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Looking at a page from the design tab (valbuild/home `docs/design-tab.md`):
2
+ * Looking at a page from the Studio:
3
3
  * where it is -- its path and scroll, so a new build opens at the same place
4
4
  * -- and what is on it, so the assistant can check its own change
5
5
  * (`read_page`).
@@ -3,9 +3,8 @@
3
3
  * `screenshot_page`, so it can see a change it made rather than only read it
4
4
  * (`read_page` gives the words and the boxes).
5
5
  *
6
- * Taken HERE because nothing else can: the design tab is another origin than
7
- * the proposal's page in its frame, and a browser lets no page photograph a
8
- * frame of another origin. So the bridge renders its own document --
6
+ * Taken HERE, in the page: a browser lets no page photograph a frame, so
7
+ * the bridge renders its own document --
9
8
  * `modern-screenshot` draws the DOM, with its computed styles, fonts and
10
9
  * same-origin images, into a canvas -- and hands back a JPEG.
11
10
  *
@@ -1,11 +1,10 @@
1
1
  /**
2
2
  * A quick preview: a proposal's page, running the proposal's CLIENT code
3
- * built in the design tab, without a build being uploaded or served
4
- * (valbuild/home `docs/design-tab.md`).
3
+ * built in the Studio, without a build being uploaded or served.
5
4
  *
6
5
  * A full build of a proposal bundles the app for the server and the browser,
7
6
  * uploads it, and has the platform render every page before it is served --
8
- * minutes. Most of what the design tab changes is components and styles,
7
+ * minutes. Most of what the assistant changes is components and styles,
9
8
  * which the browser half alone shows. So the tab bundles the app in its
10
9
  * builder worker, and a service worker on the proposal's address hands the
11
10
  * page that bundle instead of the served one:
@@ -23,7 +22,7 @@
23
22
  * 4. It takes it over by RENDERING it, not by hydrating it. Hydration keeps
24
23
  * the markup the server sent wherever only an attribute differs -- React
25
24
  * mends text, never a `className` -- so a change to classes and props,
26
- * which is most of what the design tab changes, hydrated into the old
25
+ * which is most of what the assistant changes, hydrated into the old
27
26
  * page and showed nothing. The worker adds a script to the end of that
28
27
  * document's `<body>` ({@link QUICK_PREVIEW_RENDER_SCRIPT}) that takes the
29
28
  * server's markup out before the app's scripts run, so hydration finds
@@ -82,26 +81,3 @@ export declare function storeQuickPreview(id: string, files: QuickPreviewFiles,
82
81
  }): Promise<void>;
83
82
  /** The address of a page as a quick preview `id`. */
84
83
  export declare function withQuickPreviewParam(url: string, id: string): string;
85
- /**
86
- * The one origin allowed to send this page a quick preview: the site's, where
87
- * the design tab is, as this page's own Val server says it (the proposals
88
- * list's `siteUrl`). `null` when it does not say.
89
- *
90
- * A quick preview is code that runs on this address, so the bridge takes one
91
- * only from its parent, and only when that parent is the site: a page that
92
- * framed this one could otherwise post a script into the worker and open
93
- * the frame on it.
94
- */
95
- export declare function quickPreviewSiteOrigin(api: string, fetchImpl?: typeof fetch): Promise<string | null>;
96
- /**
97
- * Whether `origin` may ask this page for what only the design tab should
98
- * have -- what is on it (`readPage`), or code to run (`quickPreview`): this
99
- * page's own origin (the Studio's canvas), or the site's, where the design
100
- * tab is ({@link quickPreviewSiteOrigin}). Asked of the server once, and
101
- * again only while it has not said.
102
- */
103
- export declare function isDesignTabOrigin(origin: string, options: {
104
- api: string;
105
- own: string;
106
- fetchImpl?: typeof fetch;
107
- }): Promise<boolean>;
@@ -2,18 +2,24 @@
2
2
  * A page sketch: a page written as indented text, with four primitives.
3
3
  *
4
4
  * ```
5
+ * --- /about a route: what follows is the page at /about
5
6
  * # Our people text (a heading: #, ## or ###)
6
7
  * We are 40 people in Oslo. text (a paragraph)
8
+ * ## Hi {field: /x.val.ts?p="t"} text linked to a content field: typing
9
+ * in it writes the field
7
10
  * [image: Team photo] placeholder: [kind] or [kind: label]
8
11
  * [hero: Roof](image: /a.jpg) a placeholder with an image (or video) in it
9
12
  * icon hero M3 5h18v14H3z how every [hero] box is drawn: SVG path data
10
13
  * row its children side by side
11
- * col 2 its children stacked; 2 shares of the row
12
- * ## Design
14
+ * col its children stacked; columns share a row
15
+ * ## Design equally
13
16
  * col
14
17
  * [button: Join us]
15
18
  * ```
16
19
  *
20
+ * A sketchpad is not one page's: a route divider starts the part about a
21
+ * page, so one sketch can cover a page and the two it links to.
22
+ *
17
23
  * It is a scratch pad, not a layout language: it says WHAT is on a page and
18
24
  * roughly WHERE, so an assistant and a person can agree on a page's content
19
25
  * before anyone worries about how it looks. The person never sees this text,
@@ -31,17 +37,23 @@
31
37
  * image. Media put in a box is written into the text too, so the assistant
32
38
  * that builds the page reads it exactly as the person left it.
33
39
  */
34
- export type SketchNode = SketchRow | SketchCol | SketchText | SketchPlaceholder;
40
+ export type SketchNode = SketchRoute | SketchRow | SketchCol | SketchText | SketchPlaceholder;
41
+ /** The start of the part about one page. Only at the top level. */
42
+ export type SketchRoute = {
43
+ type: "route";
44
+ line: number;
45
+ /** The page's route as the site serves it: `/about`, `/blog/[slug]`. */
46
+ route: string;
47
+ };
35
48
  export type SketchRow = {
36
49
  type: "row";
37
50
  line: number;
38
51
  children: SketchNode[];
39
52
  };
53
+ /** Columns share their row equally: a sketch says what, not how wide. */
40
54
  export type SketchCol = {
41
55
  type: "col";
42
56
  line: number;
43
- /** Shares of the enclosing row this column takes. */
44
- weight: number;
45
57
  children: SketchNode[];
46
58
  };
47
59
  export type SketchText = {
@@ -50,6 +62,13 @@ export type SketchText = {
50
62
  /** 0 is a paragraph; 1-3 are headings. */
51
63
  level: 0 | 1 | 2 | 3;
52
64
  text: string;
65
+ /**
66
+ * The content field this text is linked to, as a source path
67
+ * (`/content/home.val.ts?p="hero"."title"`): typing in the block writes
68
+ * the field. Written `{field: <source path>}` at the end of the line. One
69
+ * block per field: a second link to the same field is not one.
70
+ */
71
+ field?: string;
53
72
  };
54
73
  export type SketchPlaceholder = {
55
74
  type: "placeholder";
@@ -58,10 +77,18 @@ export type SketchPlaceholder = {
58
77
  label: string | null;
59
78
  media: SketchMedia | null;
60
79
  };
80
+ /**
81
+ * `src` names a file the project has, never a guess: its `path` exactly as
82
+ * the content has it (`/public/val/hero.webp`, or its remote URL), or an
83
+ * image uploaded to the assistant's session, `session:<key>`. Which files
84
+ * those are is the Studio's to check; the text only holds the name.
85
+ */
61
86
  export type SketchMedia = {
62
87
  type: "image" | "video";
63
88
  src: string;
64
89
  };
90
+ /** The prefix of a `src` that is an image in the assistant's session. */
91
+ export declare const SESSION_MEDIA_PREFIX = "session:";
65
92
  export type SketchError = {
66
93
  /** 1-based, like an editor's gutter. */
67
94
  line: number;
@@ -82,7 +109,7 @@ export declare function parseSketch(source: string): ParsedSketch;
82
109
  * The line a text block is written as. Line breaks become spaces, and a
83
110
  * paragraph that would read as something else is kept as text with `\`.
84
111
  */
85
- export declare function formatSketchText(level: SketchText["level"], text: string): string;
112
+ export declare function formatSketchText(level: SketchText["level"], text: string, field?: string): string;
86
113
  /** The line a placeholder is written as. */
87
114
  export declare function formatSketchBox(placeholder: Pick<SketchPlaceholder, "kind" | "label" | "media">): string;
88
115
  /**
@@ -95,6 +122,14 @@ export declare function formatSketchBox(placeholder: Pick<SketchPlaceholder, "ki
95
122
  * it is not on the page.
96
123
  */
97
124
  export declare function formatSketch(blocks: SketchNode[], icons: Record<string, string>): string;
125
+ /**
126
+ * The text of every block linked to a field, by field: what the Studio
127
+ * writes to the content when a linked block changes. The first block wins,
128
+ * as `formatSketch` keeps only its link.
129
+ */
130
+ export declare function sketchFieldTexts(blocks: SketchNode[]): Map<string, string>;
131
+ /** The pages a sketch is about, in the order it gives them. */
132
+ export declare function sketchRoutes(blocks: SketchNode[]): string[];
98
133
  /**
99
134
  * What a list names a sketch by: its first top-level heading, the biggest
100
135
  * one first. Null for a sketch with no heading, which a list then names by
@@ -213,8 +213,8 @@ export type ValCanvasPageMessage = {
213
213
  type: "elementPickingStopped";
214
214
  } | ({
215
215
  /**
216
- * Where the page is: its path and scroll, as it moves. The design tab
217
- * opens a new build there (`scrollTo`), so a new version replaces the
216
+ * Where the page is: its path and scroll, as it moves. A new build
217
+ * is opened there (`scrollTo`), so a new version replaces the
218
218
  * page in place rather than starting over at the top of the front page.
219
219
  */
220
220
  val: typeof VAL_CANVAS_MESSAGE;
@@ -358,7 +358,7 @@ export type ValCanvasStudioMessage = {
358
358
  picking: boolean;
359
359
  } | {
360
360
  /**
361
- * Picking ANY element, as the design tab does (`elementPicker.ts`),
361
+ * Picking ANY element (`elementPicker.ts`),
362
362
  * rather than the fields Val tagged, as `setPicking` does.
363
363
  *
364
364
  * While `enabled`, holding `modifier` outlines what is under the
@@ -7,12 +7,11 @@ var VAL_AI_SESSION_STORAGE_KEY = "val-ai-session";
7
7
 
8
8
  /**
9
9
  * A quick preview: a proposal's page, running the proposal's CLIENT code
10
- * built in the design tab, without a build being uploaded or served
11
- * (valbuild/home `docs/design-tab.md`).
10
+ * built in the Studio, without a build being uploaded or served.
12
11
  *
13
12
  * A full build of a proposal bundles the app for the server and the browser,
14
13
  * uploads it, and has the platform render every page before it is served --
15
- * minutes. Most of what the design tab changes is components and styles,
14
+ * minutes. Most of what the assistant changes is components and styles,
16
15
  * which the browser half alone shows. So the tab bundles the app in its
17
16
  * builder worker, and a service worker on the proposal's address hands the
18
17
  * page that bundle instead of the served one:
@@ -30,7 +29,7 @@ var VAL_AI_SESSION_STORAGE_KEY = "val-ai-session";
30
29
  * 4. It takes it over by RENDERING it, not by hydrating it. Hydration keeps
31
30
  * the markup the server sent wherever only an attribute differs -- React
32
31
  * mends text, never a `className` -- so a change to classes and props,
33
- * which is most of what the design tab changes, hydrated into the old
32
+ * which is most of what the assistant changes, hydrated into the old
34
33
  * page and showed nothing. The worker adds a script to the end of that
35
34
  * document's `<body>` ({@link QUICK_PREVIEW_RENDER_SCRIPT}) that takes the
36
35
  * server's markup out before the app's scripts run, so hydration finds
@@ -185,114 +184,6 @@ function withQuickPreviewParam(url, id) {
185
184
  return parsed.toString();
186
185
  }
187
186
 
188
- /**
189
- * The one origin allowed to send this page a quick preview: the site's, where
190
- * the design tab is, as this page's own Val server says it (the proposals
191
- * list's `siteUrl`). `null` when it does not say.
192
- *
193
- * A quick preview is code that runs on this address, so the bridge takes one
194
- * only from its parent, and only when that parent is the site: a page that
195
- * framed this one could otherwise post a script into the worker and open
196
- * the frame on it.
197
- */
198
- function quickPreviewSiteOrigin(_x4) {
199
- return _quickPreviewSiteOrigin.apply(this, arguments);
200
- }
201
-
202
- /** The site's origin, as this page's server named it: asked once per page. */
203
- function _quickPreviewSiteOrigin() {
204
- _quickPreviewSiteOrigin = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(api) {
205
- var fetchImpl,
206
- res,
207
- body,
208
- siteUrl,
209
- _args2 = arguments;
210
- return _regenerator().w(function (_context2) {
211
- while (1) switch (_context2.p = _context2.n) {
212
- case 0:
213
- fetchImpl = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : fetch;
214
- _context2.n = 1;
215
- return fetchImpl("".concat(api.replace(/\/+$/, ""), "/proposals-api"), {
216
- credentials: "same-origin",
217
- headers: {
218
- Accept: "application/json"
219
- }
220
- });
221
- case 1:
222
- res = _context2.v;
223
- if (res.ok) {
224
- _context2.n = 2;
225
- break;
226
- }
227
- return _context2.a(2, null);
228
- case 2:
229
- _context2.n = 3;
230
- return res.json();
231
- case 3:
232
- body = _context2.v;
233
- if (!(_typeof(body) !== "object" || body === null || !("siteUrl" in body))) {
234
- _context2.n = 4;
235
- break;
236
- }
237
- return _context2.a(2, null);
238
- case 4:
239
- siteUrl = body.siteUrl;
240
- if (!(typeof siteUrl !== "string")) {
241
- _context2.n = 5;
242
- break;
243
- }
244
- return _context2.a(2, null);
245
- case 5:
246
- _context2.p = 5;
247
- return _context2.a(2, new URL(siteUrl).origin);
248
- case 6:
249
- _context2.p = 6;
250
- _context2.v;
251
- return _context2.a(2, null);
252
- }
253
- }, _callee2, null, [[5, 6]]);
254
- }));
255
- return _quickPreviewSiteOrigin.apply(this, arguments);
256
- }
257
- var siteOriginOnce = null;
258
-
259
- /**
260
- * Whether `origin` may ask this page for what only the design tab should
261
- * have -- what is on it (`readPage`), or code to run (`quickPreview`): this
262
- * page's own origin (the Studio's canvas), or the site's, where the design
263
- * tab is ({@link quickPreviewSiteOrigin}). Asked of the server once, and
264
- * again only while it has not said.
265
- */
266
- function isDesignTabOrigin(_x5, _x6) {
267
- return _isDesignTabOrigin.apply(this, arguments);
268
- }
269
- function _isDesignTabOrigin() {
270
- _isDesignTabOrigin = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(origin, options) {
271
- var site;
272
- return _regenerator().w(function (_context3) {
273
- while (1) switch (_context3.n) {
274
- case 0:
275
- if (!(origin === options.own)) {
276
- _context3.n = 1;
277
- break;
278
- }
279
- return _context3.a(2, true);
280
- case 1:
281
- siteOriginOnce !== null && siteOriginOnce !== void 0 ? siteOriginOnce : siteOriginOnce = quickPreviewSiteOrigin(options.api, options.fetchImpl)["catch"](function () {
282
- return null;
283
- });
284
- _context3.n = 2;
285
- return siteOriginOnce;
286
- case 2:
287
- site = _context3.v;
288
- if (site === null) siteOriginOnce = null;
289
- return _context3.a(2, site !== null && site === origin);
290
- }
291
- }, _callee3);
292
- }));
293
- return _isDesignTabOrigin.apply(this, arguments);
294
- }
295
-
296
187
  /** Marks a page load as the studio's canvas frame. */
297
188
  var VAL_CANVAS_PARAM = "val_canvas";
298
189
 
@@ -465,9 +356,9 @@ function withValCanvasParam(url) {
465
356
  /**
466
357
  * Pointing at anything on a page, as Lovable's picker does: hover outlines
467
358
  * the element under the pointer, a click picks it, and the assistant is told
468
- * which (valbuild/home `docs/design-tab.md`).
359
+ * which.
469
360
  *
470
- * ANY element, not only what Val marks. The design tab changes code, and the
361
+ * ANY element, not only what Val marks. The assistant changes code, and the
471
362
  * thing a person wants changed is as often a wrapper, a gap or a button as a
472
363
  * field -- so a field's path is extra information when there is one
473
364
  * (`valPath`), never the condition for picking.
@@ -478,9 +369,8 @@ function withValCanvasParam(url) {
478
369
  *
479
370
  * Plain DOM, nothing of React's or the Studio's, and in `shared` because
480
371
  * both halves need it: the canvas bridge (`@valbuild/next`,
481
- * `@valbuild/tanstack`) runs it inside the proposal's page, which is another
482
- * origin than the design tab and the only place the page's elements can be
483
- * reached; the Studio's stories run it on a page of their own. Only the
372
+ * `@valbuild/tanstack`) runs it inside the page, the only place the page's
373
+ * elements can be reached; the Studio's stories run it on a page of their own. Only the
484
374
  * `PickedElement` crosses the frame (`valCanvasProtocol.ts`).
485
375
  */
486
376
 
@@ -1179,9 +1069,8 @@ function selectorOf(element, root) {
1179
1069
  * `screenshot_page`, so it can see a change it made rather than only read it
1180
1070
  * (`read_page` gives the words and the boxes).
1181
1071
  *
1182
- * Taken HERE because nothing else can: the design tab is another origin than
1183
- * the proposal's page in its frame, and a browser lets no page photograph a
1184
- * frame of another origin. So the bridge renders its own document --
1072
+ * Taken HERE, in the page: a browser lets no page photograph a frame, so
1073
+ * the bridge renders its own document --
1185
1074
  * `modern-screenshot` draws the DOM, with its computed styles, fonts and
1186
1075
  * same-origin images, into a canvas -- and hands back a JPEG.
1187
1076
  *
@@ -1546,4 +1435,4 @@ function getPatternFromModuleFilePath(moduleFilePath, srcFolder) {
1546
1435
  .replace("/page.val.ts", "").replace("/page.val.js", "");
1547
1436
  }
1548
1437
 
1549
- export { storeQuickPreview as A, withQuickPreviewParam as B, quickPreviewSiteOrigin as C, DEFAULT_CANVAS_SELECTION as D, isDesignTabOrigin as E, parseRoutePattern as F, formatRoutePattern as G, getNextAppRouterSourceFolder as H, getTanStackRouterSourceFolder as I, getPageRouterSourceFolder as J, isTanStackRoutesFolder as K, getPageRouterSitemapTree as L, getPatternFromModuleFilePath as M, QUICK_PREVIEW_PARAM as Q, VAL_CONFIG_SESSION_STORAGE_KEY as V, VAL_THEME_SESSION_STORAGE_KEY as a, VAL_AI_SESSION_STORAGE_KEY as b, VAL_CANVAS_PARAM as c, VAL_CANVAS_MESSAGE as d, DEFAULT_CANVAS_SELECTION_SOFT as e, isValCanvasStudioMessage as f, isValCanvasFrame as g, describeElement as h, isValCanvasPageMessage as i, attachElementPicker as j, createPickerOverlay as k, elementLabel as l, modifierLabel as m, watchPageLocation as n, readPageSnapshot as o, pageLocationOf as p, findBySelector as q, restoreScroll as r, startElementPicking as s, screenshotPage as t, QUICK_PREVIEW_SERVICE_WORKER_PATH as u, QUICK_PREVIEW_RENDER_SCRIPT as v, withValCanvasParam as w, QUICK_PREVIEW_STORE_MESSAGE as x, isQuickPreviewFiles as y, QUICK_PREVIEW_SERVICE_WORKER_SOURCE as z };
1438
+ export { storeQuickPreview as A, withQuickPreviewParam as B, parseRoutePattern as C, DEFAULT_CANVAS_SELECTION as D, formatRoutePattern as E, getNextAppRouterSourceFolder as F, getTanStackRouterSourceFolder as G, getPageRouterSourceFolder as H, isTanStackRoutesFolder as I, getPageRouterSitemapTree as J, getPatternFromModuleFilePath as K, QUICK_PREVIEW_PARAM as Q, VAL_CONFIG_SESSION_STORAGE_KEY as V, VAL_THEME_SESSION_STORAGE_KEY as a, VAL_AI_SESSION_STORAGE_KEY as b, VAL_CANVAS_PARAM as c, VAL_CANVAS_MESSAGE as d, DEFAULT_CANVAS_SELECTION_SOFT as e, isValCanvasStudioMessage as f, isValCanvasFrame as g, describeElement as h, isValCanvasPageMessage as i, attachElementPicker as j, createPickerOverlay as k, elementLabel as l, modifierLabel as m, watchPageLocation as n, readPageSnapshot as o, pageLocationOf as p, findBySelector as q, restoreScroll as r, startElementPicking as s, screenshotPage as t, QUICK_PREVIEW_SERVICE_WORKER_PATH as u, QUICK_PREVIEW_RENDER_SCRIPT as v, withValCanvasParam as w, QUICK_PREVIEW_STORE_MESSAGE as x, isQuickPreviewFiles as y, QUICK_PREVIEW_SERVICE_WORKER_SOURCE as z };