@valbuild/shared 0.150.12 → 0.150.16

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 (24) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/client/dist/valbuild-shared-client.cjs.dev.js +2 -1
  3. package/client/dist/valbuild-shared-client.cjs.prod.js +2 -1
  4. package/client/dist/valbuild-shared-client.esm.js +1 -1
  5. package/dist/declarations/src/client/index.d.ts +1 -0
  6. package/dist/declarations/src/internal/ApiRoutes.d.ts +375 -94
  7. package/dist/declarations/src/internal/aiTools/toolNames.d.ts +1 -1
  8. package/dist/declarations/src/internal/index.d.ts +3 -0
  9. package/dist/declarations/src/internal/localeAt.d.ts +86 -1
  10. package/dist/declarations/src/internal/localeRelocation.d.ts +46 -0
  11. package/dist/declarations/src/internal/pageScreenshot.d.ts +40 -0
  12. package/dist/declarations/src/internal/server/types.d.ts +3 -3
  13. package/dist/declarations/src/internal/sketchpad/sketchFormat.d.ts +118 -0
  14. package/dist/declarations/src/internal/valCanvasProtocol.d.ts +21 -0
  15. package/dist/declarations/src/internal/zod/History.d.ts +7 -7
  16. package/dist/declarations/src/internal/zod/Patch.d.ts +1 -0
  17. package/dist/declarations/src/internal/zod/SerializedSchema.d.ts +20 -2
  18. package/dist/{getSitemapTree-97b3166f.esm.js → getSitemapTree-7c848c94.esm.js} +137 -2
  19. package/dist/{getSitemapTree-5354ce90.cjs.prod.js → getSitemapTree-97713490.cjs.prod.js} +155 -1
  20. package/dist/{getSitemapTree-d934ff9c.cjs.dev.js → getSitemapTree-98642b57.cjs.dev.js} +155 -1
  21. package/internal/dist/valbuild-shared-internal.cjs.dev.js +837 -15
  22. package/internal/dist/valbuild-shared-internal.cjs.prod.js +837 -15
  23. package/internal/dist/valbuild-shared-internal.esm.js +821 -17
  24. package/package.json +2 -1
@@ -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"];
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"];
2
2
  export type ToolName = (typeof toolNames)[number];
@@ -21,14 +21,17 @@ export * from "./getNextAppRouterSourceFolder.js";
21
21
  export * from "./routeValidation.js";
22
22
  export * from "./resolveSchemaSourceFixes.js";
23
23
  export * from "./localeAt.js";
24
+ export * from "./localeRelocation.js";
24
25
  export * from "./getErrorMessageFromUnknownJson.js";
25
26
  export * from "./zod/SerializedSchema.js";
26
27
  export * from "./valCanvasProtocol.js";
27
28
  export * from "./elementPicker.js";
28
29
  export * from "./pageInspection.js";
30
+ export * from "./pageScreenshot.js";
29
31
  export * from "./quickPreview.js";
30
32
  export * from "./emptyOf.js";
31
33
  export * from "./aiTools/toolNames.js";
34
+ export * from "./sketchpad/sketchFormat.js";
32
35
  export * from "./aiTools/aiImageToolPatches.js";
33
36
  export * from "./aiTools/aiSourceToolPatches.js";
34
37
  export * from "./validation/partitionValidationErrors.js";
@@ -1,4 +1,4 @@
1
- import { type SerializedEnumSchema, type SerializedSchema, type SourcePath } from "@valbuild/core";
1
+ import { type Json, type JsonObject, type ModuleFilePath, type SerializedEnumSchema, type SerializedSchema, type SourcePath } from "@valbuild/core";
2
2
  import { type SchemaSourceSnapshot } from "./resolveSchemaSourceFixes.js";
3
3
  /**
4
4
  * Which of the project's languages governs a path, or `null` for none.
@@ -18,6 +18,52 @@ import { type SchemaSourceSnapshot } from "./resolveSchemaSourceFixes.js";
18
18
  * in most projects, and for every project that has not declared any languages.
19
19
  */
20
20
  export declare function localeAt(path: SourcePath, snapshot: SchemaSourceSnapshot): string | null;
21
+ /**
22
+ * Where the scope governing a path opens, and how.
23
+ *
24
+ * - `field`: the node `depth` segments down has a locale field. `depth` 0 is the
25
+ * module root.
26
+ * - `record-key`: segment `depth` is a key of a locale-keyed record, which sits
27
+ * `depth` segments down.
28
+ * - `route-key`: segment `depth` is a route whose parameters name the language,
29
+ * in the router `depth` segments down (in practice the module root).
30
+ *
31
+ * The opener is what decides where an editor goes when the Studio's language
32
+ * changes under them — the same entry in another language for a key, the
33
+ * parent for a field. See `relocateForLocale`.
34
+ */
35
+ export type LocaleScope = {
36
+ locale: string;
37
+ depth: number;
38
+ } & ({
39
+ kind: "field";
40
+ } | {
41
+ kind: "record-key";
42
+ keySchema: SerializedSchema;
43
+ } | {
44
+ kind: "route-key";
45
+ router: SerializedSchema & {
46
+ type: "record";
47
+ };
48
+ });
49
+ /**
50
+ * The scope that governs a path, read from that module's schema and source
51
+ * alone, or `null` where none does.
52
+ *
53
+ * {@link localeAt} for a caller that already has the module in hand — the
54
+ * Studio, which has the project's languages from its own provider and would
55
+ * otherwise have to assemble a snapshot of every module to ask about one.
56
+ */
57
+ export declare function localeScopeAt(path: SourcePath, schema: SerializedSchema, source: Json, available: readonly string[]): LocaleScope | null;
58
+ /**
59
+ * The language a whole module is in: the one its root's locale field names, or
60
+ * `null` where its root has none.
61
+ *
62
+ * The only way a module is in one language as a whole — a locale-keyed record
63
+ * or a router at the root is every one of its languages at once. Needs no path,
64
+ * so a list of modules can ask it of each.
65
+ */
66
+ export declare function localeOfModuleRoot(schema: SerializedSchema, source: Json, available: readonly string[]): string | null;
21
67
  /**
22
68
  * The language a locale schema's value MEANS, or `null` if it means none of
23
69
  * the project's.
@@ -44,3 +90,42 @@ export declare function enumLocaleTag(schema: SerializedEnumSchema, value: strin
44
90
  * one.
45
91
  */
46
92
  export declare function isLocaleSchema(schema: SerializedSchema): boolean;
93
+ /**
94
+ * Whether a router's URLs name the language each page is in — one of its route
95
+ * parameters is a locale (`s.router(router, { locale: … }, item)`).
96
+ */
97
+ export declare function hasLocaleRouteParam(schema: SerializedSchema): boolean;
98
+ /**
99
+ * The language a router's key is in, where one of its route parameters is a
100
+ * locale — `/nb/blog/hei` is `nb-NO` when `locale` maps `nb` to it.
101
+ *
102
+ * Answered from the key alone, with no content read: which is what lets the
103
+ * Studio's page tree filter every page of a site without loading one of them.
104
+ */
105
+ export declare function localeOfRouteKey(schema: SerializedSchema & {
106
+ type: "record";
107
+ }, moduleFilePath: ModuleFilePath, key: string, available: readonly string[]): string | null;
108
+ /**
109
+ * The route parameters a key gives its router, and which of them is the
110
+ * language — or `null` where the router has no locale parameter or the key is
111
+ * not one of its URLs.
112
+ */
113
+ export declare function localeParamOfRouteKey(schema: SerializedSchema & {
114
+ type: "record";
115
+ }, moduleFilePath: ModuleFilePath, key: string): {
116
+ name: string;
117
+ schema: SerializedSchema;
118
+ value: string | null;
119
+ values: Record<string, string | null>;
120
+ } | null;
121
+ /** The child of a source value at a segment, or `null` where there is none. */
122
+ export declare function childSource(source: Json, segment: string): Json;
123
+ /**
124
+ * Whether `source` is a JSON object rather than an array or a primitive.
125
+ *
126
+ * A type predicate rather than the inline checks, because `Array.isArray` does
127
+ * NOT narrow `JsonArray` out of `Json` — it is `readonly Json[]`, and the
128
+ * built-in guard only narrows mutable arrays. Without this, every read of a
129
+ * property would need an assertion.
130
+ */
131
+ export declare function isJsonObject(source: Json): source is JsonObject;
@@ -0,0 +1,46 @@
1
+ import { type Json, type SerializedSchema, type SourcePath } from "@valbuild/core";
2
+ /**
3
+ * Where an editor goes when the Studio's language changes under them.
4
+ *
5
+ * - `stay`: the path is in that language, or in none.
6
+ * - `path`: the same entry in that language (`counterpart`), or the nearest
7
+ * parent that is not in another language (`parent`).
8
+ * - `home`: neither exists, so the editor goes to the Studio's start, with
9
+ * nothing selected.
10
+ */
11
+ export type LocaleRelocation = {
12
+ type: "stay";
13
+ } | {
14
+ type: "path";
15
+ path: SourcePath;
16
+ reason: "counterpart" | "parent";
17
+ } | {
18
+ type: "home";
19
+ };
20
+ /**
21
+ * Where to move a path to when the Studio is switched to `locale`.
22
+ *
23
+ * The rule, in the order it is tried:
24
+ *
25
+ * 1. **The same entry in `locale`, where Val KNOWS it.** That is two cases:
26
+ * a locale-keyed record, where the counterpart of `"en-US"` is the
27
+ * `"nb-NO"` key of the same record; and a router whose URLs name their
28
+ * language, where `/about` and `/nb/about` differ only in it. Only a key
29
+ * that exists is taken, and the rest of the path is kept as far as it
30
+ * still exists, so an editor on a field lands on that field.
31
+ * 2. **Otherwise the nearest parent that is not in another language.** An
32
+ * English post in a list of posts gives the list, now showing Norwegian.
33
+ * 3. **Otherwise the Studio's start**, which is `home`: nothing selected. That
34
+ * is where an object at the module root opened the scope (the whole module
35
+ * is in another language), and where the parent would be a router: a list
36
+ * of pages is not a page, and the Pages tree is how an editor sees one.
37
+ *
38
+ * Not the site's root page, and not any other page: which language a page is
39
+ * in is the page's own business, and `/` can be in the language the editor
40
+ * just left. The start screen is in no language.
41
+ *
42
+ * Never a guess. Two pages whose URLs differ in more than the language — a
43
+ * Norwegian slug for a Norwegian page — are not known to be translations of
44
+ * each other, so that is `home` rather than whichever page looks closest.
45
+ */
46
+ export declare function relocateForLocale(path: SourcePath, locale: string, schema: SerializedSchema, source: Json, available: readonly string[]): LocaleRelocation;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * A picture of the page, taken in the page: the assistant's
3
+ * `screenshot_page`, so it can see a change it made rather than only read it
4
+ * (`read_page` gives the words and the boxes).
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 --
9
+ * `modern-screenshot` draws the DOM, with its computed styles, fonts and
10
+ * same-origin images, into a canvas -- and hands back a JPEG.
11
+ *
12
+ * It is a rendering of the DOM, not of the screen: an image from another
13
+ * origin that does not allow it, a video frame, a `<canvas>` a script drew
14
+ * and an iframe come out blank. Good enough to see a layout, a colour, a
15
+ * button that wrapped; the tool says what it cannot show.
16
+ *
17
+ * Loaded when asked: the library is not in a page that is never
18
+ * photographed.
19
+ */
20
+ /** What `screenshotPage` answers. */
21
+ export type PageScreenshot = {
22
+ /** A JPEG, as a data URL. */
23
+ dataUrl: string;
24
+ width: number;
25
+ height: number;
26
+ /** The whole page, from the top, rather than what was on screen. */
27
+ fullPage: boolean;
28
+ /** The page went on below what the picture shows. */
29
+ clipped: boolean;
30
+ };
31
+ /**
32
+ * The page in `win`, as it is now: what is on screen, or (`fullPage`) the
33
+ * whole page from the top, cut off at {@link MAX_FULL_PAGE_HEIGHT}. Elements
34
+ * `exclude` says are not the page's -- the picker's highlight -- are left
35
+ * out.
36
+ */
37
+ export declare function screenshotPage(win: Window, options?: {
38
+ fullPage?: boolean;
39
+ exclude?: (element: Element) => boolean;
40
+ }): Promise<PageScreenshot>;
@@ -1,7 +1,7 @@
1
1
  import { Json } from "@valbuild/core";
2
- export declare const VAL_SESSION_COOKIE: any;
3
- export declare const VAL_STATE_COOKIE: any;
4
- export declare const VAL_ENABLE_COOKIE_NAME: any;
2
+ export declare const VAL_SESSION_COOKIE: "val_session";
3
+ export declare const VAL_STATE_COOKIE: "val_state";
4
+ export declare const VAL_ENABLE_COOKIE_NAME: "val_enable";
5
5
  export type VAL_SESSION_COOKIE = typeof VAL_SESSION_COOKIE;
6
6
  export type VAL_STATE_COOKIE = typeof VAL_STATE_COOKIE;
7
7
  export type VAL_ENABLE_COOKIE_NAME = typeof VAL_ENABLE_COOKIE_NAME;
@@ -0,0 +1,118 @@
1
+ /**
2
+ * A page sketch: a page written as indented text, with four primitives.
3
+ *
4
+ * ```
5
+ * # Our people text (a heading: #, ## or ###)
6
+ * We are 40 people in Oslo. text (a paragraph)
7
+ * [image: Team photo] placeholder: [kind] or [kind: label]
8
+ * [hero: Roof](image: /a.jpg) a placeholder with an image (or video) in it
9
+ * icon hero M3 5h18v14H3z how every [hero] box is drawn: SVG path data
10
+ * row its children side by side
11
+ * col 2 its children stacked; 2 shares of the row
12
+ * ## Design
13
+ * col
14
+ * [button: Join us]
15
+ * ```
16
+ *
17
+ * It is a scratch pad, not a layout language: it says WHAT is on a page and
18
+ * roughly WHERE, so an assistant and a person can agree on a page's content
19
+ * before anyone worries about how it looks. The person never sees this text,
20
+ * only the page it describes; the assistant never sees the page, only this.
21
+ * So the two have to be the same thing, and the format is STRICT: there is
22
+ * exactly one way to write what is on the screen. `checkSketch` is that
23
+ * rule, and the server refuses a write that breaks it, with the line to fix.
24
+ *
25
+ * Parsing is still forgiving, so a sketch that breaks the rule shows what it
26
+ * can rather than nothing; that is for reading, never for accepting.
27
+ *
28
+ * A placeholder's kind is any word, and nothing here knows what one means. The
29
+ * assistant that writes the sketch also draws each kind's icon, as path data
30
+ * in a 24 by 24 box, so a kind nobody thought of looks as deliberate as an
31
+ * image. Media put in a box is written into the text too, so the assistant
32
+ * that builds the page reads it exactly as the person left it.
33
+ */
34
+ export type SketchNode = SketchRow | SketchCol | SketchText | SketchPlaceholder;
35
+ export type SketchRow = {
36
+ type: "row";
37
+ line: number;
38
+ children: SketchNode[];
39
+ };
40
+ export type SketchCol = {
41
+ type: "col";
42
+ line: number;
43
+ /** Shares of the enclosing row this column takes. */
44
+ weight: number;
45
+ children: SketchNode[];
46
+ };
47
+ export type SketchText = {
48
+ type: "text";
49
+ line: number;
50
+ /** 0 is a paragraph; 1-3 are headings. */
51
+ level: 0 | 1 | 2 | 3;
52
+ text: string;
53
+ };
54
+ export type SketchPlaceholder = {
55
+ type: "placeholder";
56
+ line: number;
57
+ kind: string;
58
+ label: string | null;
59
+ media: SketchMedia | null;
60
+ };
61
+ export type SketchMedia = {
62
+ type: "image" | "video";
63
+ src: string;
64
+ };
65
+ export type SketchError = {
66
+ /** 1-based, like an editor's gutter. */
67
+ line: number;
68
+ message: string;
69
+ };
70
+ export type ParsedSketch = {
71
+ /** The page itself is a column. */
72
+ blocks: SketchNode[];
73
+ /**
74
+ * SVG path data by kind, lower case. Drawn as a 24 by 24 line icon: stroked
75
+ * in the text colour, not filled.
76
+ */
77
+ icons: Record<string, string>;
78
+ errors: SketchError[];
79
+ };
80
+ export declare function parseSketch(source: string): ParsedSketch;
81
+ /**
82
+ * The line a text block is written as. Line breaks become spaces, and a
83
+ * paragraph that would read as something else is kept as text with `\`.
84
+ */
85
+ export declare function formatSketchText(level: SketchText["level"], text: string): string;
86
+ /** The line a placeholder is written as. */
87
+ export declare function formatSketchBox(placeholder: Pick<SketchPlaceholder, "kind" | "label" | "media">): string;
88
+ /**
89
+ * The ONE way of writing `blocks` and `icons`: what `checkSketch` holds every
90
+ * other text to, and what the Studio's editor writes (its own serializer is
91
+ * tested against this one). Two spaces per level; an empty row gets an empty
92
+ * col, so it has somewhere to type; a col outside a row is written as its
93
+ * contents, which is all it shows; the icons last, after one blank line, and
94
+ * no blank line anywhere else; a final newline. Empty text is not written --
95
+ * it is not on the page.
96
+ */
97
+ export declare function formatSketch(blocks: SketchNode[], icons: Record<string, string>): string;
98
+ /**
99
+ * What a list names a sketch by: its first top-level heading, the biggest
100
+ * one first. Null for a sketch with no heading, which a list then names by
101
+ * its page.
102
+ */
103
+ export declare function sketchTitle(blocks: SketchNode[]): string | null;
104
+ /**
105
+ * Everything wrong with `source`, or nothing when it is a sketch exactly as
106
+ * `formatSketch` writes it.
107
+ *
108
+ * Strict on purpose. The person sees the page and the assistant sees the
109
+ * text, so a text with two spellings of one page -- a tab or two spaces, an
110
+ * icon line here or there, a blank line or none -- is a text the assistant
111
+ * cannot trust to be what is on the screen, and that would show it a change
112
+ * nobody made the next time the Studio writes it back. Holding every write
113
+ * to the one spelling rules all of that out at once.
114
+ *
115
+ * The parse errors come first; past those, the first line that is spelled
116
+ * differently, with how it should be spelled.
117
+ */
118
+ export declare function checkSketch(source: string): SketchError[];
@@ -22,6 +22,7 @@
22
22
  import type { ModuleFilePath, SourcePath } from "@valbuild/core";
23
23
  import type { PickedElement, PickModifier } from "./elementPicker.js";
24
24
  import type { PageLocation, PageSnapshot } from "./pageInspection.js";
25
+ import type { PageScreenshot } from "./pageScreenshot.js";
25
26
  import { type QuickPreviewFiles } from "./quickPreview.js";
26
27
  /** Marks a page load as the studio's canvas frame. */
27
28
  export declare const VAL_CANVAS_PARAM = "val_canvas";
@@ -205,6 +206,16 @@ export type ValCanvasPageMessage = {
205
206
  requestId: string;
206
207
  snapshot: PageSnapshot | null;
207
208
  error?: string;
209
+ } | {
210
+ /**
211
+ * What `screenshotPage` asked for: the page as a JPEG data URL, or why
212
+ * it could not be taken (`pageScreenshot.ts`).
213
+ */
214
+ val: typeof VAL_CANVAS_MESSAGE;
215
+ type: "pageScreenshot";
216
+ requestId: string;
217
+ screenshot: PageScreenshot | null;
218
+ error?: string;
208
219
  } | {
209
220
  /**
210
221
  * A quick preview's files are stored in the page's worker, and a page
@@ -334,6 +345,16 @@ export type ValCanvasStudioMessage = {
334
345
  requestId: string;
335
346
  selector?: string;
336
347
  maxItems?: number;
348
+ } | {
349
+ /**
350
+ * Take a picture of the page (`screenshotPage`): the assistant's
351
+ * `screenshot_page`. Answered with `pageScreenshot` and the same
352
+ * `requestId`; a bridge that predates it never answers.
353
+ */
354
+ val: typeof VAL_CANVAS_MESSAGE;
355
+ type: "screenshotPage";
356
+ requestId: string;
357
+ fullPage?: boolean;
337
358
  } | {
338
359
  /**
339
360
  * Store a quick preview's files in this origin's worker
@@ -64,9 +64,9 @@ export declare const BinaryFileRef: z.ZodObject<{
64
64
  }, z.core.$strip>;
65
65
  export type BinaryFileRef = z.infer<typeof BinaryFileRef>;
66
66
  export declare const HistoricalModule: z.ZodObject<{
67
- source: z.ZodNullable<z.ZodType<JSONValueT, unknown, z.core.$ZodTypeInternals<JSONValueT, unknown>>>;
68
- schema: z.ZodNullable<z.ZodType<SerializedSchemaT, unknown, z.core.$ZodTypeInternals<SerializedSchemaT, unknown>>>;
69
- patchIds: z.ZodArray<z.ZodString & z.ZodType<PatchIdT, string, z.core.$ZodTypeInternals<PatchIdT, string>>>;
67
+ source: z.ZodNullable<z.ZodType<import("@valbuild/core/patch").JSONValue, unknown, z.core.$ZodTypeInternals<import("@valbuild/core/patch").JSONValue, unknown>>>;
68
+ schema: z.ZodNullable<z.ZodType<import("@valbuild/core").SerializedSchema, unknown, z.core.$ZodTypeInternals<import("@valbuild/core").SerializedSchema, unknown>>>;
69
+ patchIds: z.ZodArray<z.ZodString & z.ZodType<import("@valbuild/core").PatchId, string, z.core.$ZodTypeInternals<import("@valbuild/core").PatchId, string>>>;
70
70
  changedPaths: z.ZodArray<z.ZodString>;
71
71
  failures: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
72
72
  kind: z.ZodLiteral<"commit-not-found">;
@@ -109,9 +109,9 @@ export declare const HistoricalPatchSet: z.ZodObject<{
109
109
  hasArchive: z.ZodBoolean;
110
110
  }, z.core.$strip>;
111
111
  modules: z.ZodRecord<z.ZodString, z.ZodObject<{
112
- source: z.ZodNullable<z.ZodType<JSONValueT, unknown, z.core.$ZodTypeInternals<JSONValueT, unknown>>>;
113
- schema: z.ZodNullable<z.ZodType<SerializedSchemaT, unknown, z.core.$ZodTypeInternals<SerializedSchemaT, unknown>>>;
114
- patchIds: z.ZodArray<z.ZodString & z.ZodType<PatchIdT, string, z.core.$ZodTypeInternals<PatchIdT, string>>>;
112
+ source: z.ZodNullable<z.ZodType<import("@valbuild/core/patch").JSONValue, unknown, z.core.$ZodTypeInternals<import("@valbuild/core/patch").JSONValue, unknown>>>;
113
+ schema: z.ZodNullable<z.ZodType<import("@valbuild/core").SerializedSchema, unknown, z.core.$ZodTypeInternals<import("@valbuild/core").SerializedSchema, unknown>>>;
114
+ patchIds: z.ZodArray<z.ZodString & z.ZodType<import("@valbuild/core").PatchId, string, z.core.$ZodTypeInternals<import("@valbuild/core").PatchId, string>>>;
115
115
  changedPaths: z.ZodArray<z.ZodString>;
116
116
  failures: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
117
117
  kind: z.ZodLiteral<"commit-not-found">;
@@ -139,7 +139,7 @@ export declare const HistoricalPatchSet: z.ZodObject<{
139
139
  }, z.core.$strip>], "kind">>;
140
140
  }, z.core.$strip>>;
141
141
  patches: z.ZodArray<z.ZodObject<{
142
- patchId: z.ZodString & z.ZodType<PatchIdT, string, z.core.$ZodTypeInternals<PatchIdT, string>>;
142
+ patchId: z.ZodString & z.ZodType<import("@valbuild/core").PatchId, string, z.core.$ZodTypeInternals<import("@valbuild/core").PatchId, string>>;
143
143
  moduleFilePath: z.ZodString;
144
144
  patch: z.ZodUnknown;
145
145
  authorId: z.ZodNullable<z.ZodString>;
@@ -1,4 +1,5 @@
1
1
  import type { JSONValue as JSONValueT, PatchJSON as PatchJSONT, PatchBlock as PatchBlockT, ParentRef as ParentRefT } from "@valbuild/core/patch";
2
+ import type { PatchId as PatchIdT } from "@valbuild/core";
2
3
  import { z } from "zod";
3
4
  /**
4
5
  * JSON, recursively — the shape of a Source over the wire.
@@ -66,7 +66,25 @@ export declare const ColorOptions: z.ZodObject<{
66
66
  export declare const SerializedColorSchema: z.ZodType<SerializedColorSchemaT>;
67
67
  export declare const CodeOptions: z.ZodObject<{
68
68
  language: z.ZodOptional<z.ZodEnum<{
69
- [x: string]: any;
69
+ html: "html";
70
+ css: "css";
71
+ json: "json";
72
+ typescript: "typescript";
73
+ javascript: "javascript";
74
+ javascriptreact: "javascriptreact";
75
+ typescriptreact: "typescriptreact";
76
+ java: "java";
77
+ xml: "xml";
78
+ markdown: "markdown";
79
+ sql: "sql";
80
+ python: "python";
81
+ rust: "rust";
82
+ php: "php";
83
+ go: "go";
84
+ cpp: "cpp";
85
+ sass: "sass";
86
+ vue: "vue";
87
+ angular: "angular";
70
88
  }>>;
71
89
  }, z.core.$strip>;
72
90
  export declare const SerializedCodeSchema: z.ZodType<SerializedCodeSchemaT>;
@@ -83,7 +101,7 @@ export declare const SerializedSettingsSchema: z.ZodType<SerializedSettingsSchem
83
101
  */
84
102
  export declare const SerializedValViewSchema: z.ZodObject<{
85
103
  type: z.ZodLiteral<"view">;
86
- moduleFilePath: z.ZodType<ModuleFilePathT, unknown, z.core.$ZodTypeInternals<ModuleFilePathT, unknown>>;
104
+ moduleFilePath: z.ZodType<import("@valbuild/core").ModuleFilePath, unknown, z.core.$ZodTypeInternals<import("@valbuild/core").ModuleFilePath, unknown>>;
87
105
  opt: z.ZodLiteral<false>;
88
106
  readonly: z.ZodOptional<z.ZodBoolean>;
89
107
  hidden: z.ZodOptional<z.ZodBoolean>;
@@ -322,7 +322,7 @@ function isValCanvasPageMessage(data) {
322
322
  if (_typeof(data) !== "object" || data === null) return false;
323
323
  var message = data;
324
324
  if (message.val !== VAL_CANVAS_MESSAGE) return false;
325
- return message.type === "ready" || message.type === "elements" || message.type === "clicked" || message.type === "pinch" || message.type === "zoom" || message.type === "refreshing" || message.type === "elementPickingStopped" || message.type === "elementPicked" && isPickedElement(data.element) || message.type === "location" && isPageLocation(data) || message.type === "pageRead" && typeof data.requestId === "string" || message.type === "quickPreviewStored" && typeof data.id === "string";
325
+ return message.type === "ready" || message.type === "elements" || message.type === "clicked" || message.type === "pinch" || message.type === "zoom" || message.type === "refreshing" || message.type === "elementPickingStopped" || message.type === "elementPicked" && isPickedElement(data.element) || message.type === "location" && isPageLocation(data) || message.type === "pageRead" && typeof data.requestId === "string" || message.type === "pageScreenshot" && typeof data.requestId === "string" || message.type === "quickPreviewStored" && typeof data.id === "string";
326
326
  }
327
327
  function isPageLocation(value) {
328
328
  var location = value;
@@ -379,6 +379,10 @@ function isValCanvasStudioMessage(data) {
379
379
  var preview = data;
380
380
  return typeof preview.id === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(preview.id) && isQuickPreviewFiles(preview.files);
381
381
  }
382
+ if (message.type === "screenshotPage") {
383
+ var asked = data;
384
+ return typeof asked.requestId === "string" && (asked.fullPage === undefined || typeof asked.fullPage === "boolean");
385
+ }
382
386
  if (message.type === "readPage") {
383
387
  var read = data;
384
388
  return typeof read.requestId === "string" && (read.selector === undefined || typeof read.selector === "string") && (read.maxItems === undefined || typeof read.maxItems === "number");
@@ -1137,6 +1141,137 @@ function selectorOf(element, root) {
1137
1141
  return parts.join(" > ");
1138
1142
  }
1139
1143
 
1144
+ /**
1145
+ * A picture of the page, taken in the page: the assistant's
1146
+ * `screenshot_page`, so it can see a change it made rather than only read it
1147
+ * (`read_page` gives the words and the boxes).
1148
+ *
1149
+ * Taken HERE because nothing else can: the design tab is another origin than
1150
+ * the proposal's page in its frame, and a browser lets no page photograph a
1151
+ * frame of another origin. So the bridge renders its own document --
1152
+ * `modern-screenshot` draws the DOM, with its computed styles, fonts and
1153
+ * same-origin images, into a canvas -- and hands back a JPEG.
1154
+ *
1155
+ * It is a rendering of the DOM, not of the screen: an image from another
1156
+ * origin that does not allow it, a video frame, a `<canvas>` a script drew
1157
+ * and an iframe come out blank. Good enough to see a layout, a colour, a
1158
+ * button that wrapped; the tool says what it cannot show.
1159
+ *
1160
+ * Loaded when asked: the library is not in a page that is never
1161
+ * photographed.
1162
+ */
1163
+
1164
+ /** What `screenshotPage` answers. */
1165
+
1166
+ /** Wider than this is scaled down: a model reads a page no better larger. */
1167
+ var MAX_WIDTH = 1280;
1168
+ /** A whole page longer than this, in CSS pixels, is cut off below it. */
1169
+ var MAX_FULL_PAGE_HEIGHT = 4000;
1170
+ var JPEG_QUALITY = 0.85;
1171
+ /** How long an image or a font on the page is waited for. */
1172
+ var LOAD_TIMEOUT_MS = 8000;
1173
+
1174
+ /**
1175
+ * The page in `win`, as it is now: what is on screen, or (`fullPage`) the
1176
+ * whole page from the top, cut off at {@link MAX_FULL_PAGE_HEIGHT}. Elements
1177
+ * `exclude` says are not the page's -- the picker's highlight -- are left
1178
+ * out.
1179
+ */
1180
+ function screenshotPage(_x) {
1181
+ return _screenshotPage.apply(this, arguments);
1182
+ }
1183
+
1184
+ /** What the page is drawn on: the body's background, else the root's, else white. */
1185
+ function _screenshotPage() {
1186
+ _screenshotPage = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(win) {
1187
+ var _doc$body$scrollHeigh, _doc$body;
1188
+ var options,
1189
+ _yield$import,
1190
+ domToCanvas,
1191
+ doc,
1192
+ root,
1193
+ fullPage,
1194
+ pageWidth,
1195
+ pageHeight,
1196
+ top,
1197
+ height,
1198
+ exclude,
1199
+ drawn,
1200
+ scale,
1201
+ out,
1202
+ context,
1203
+ _args = arguments;
1204
+ return _regenerator().w(function (_context) {
1205
+ while (1) switch (_context.n) {
1206
+ case 0:
1207
+ options = _args.length > 1 && _args[1] !== undefined ? _args[1] : {};
1208
+ _context.n = 1;
1209
+ return import('modern-screenshot');
1210
+ case 1:
1211
+ _yield$import = _context.v;
1212
+ domToCanvas = _yield$import.domToCanvas;
1213
+ doc = win.document;
1214
+ root = doc.documentElement;
1215
+ fullPage = options.fullPage === true;
1216
+ pageWidth = root.clientWidth || win.innerWidth;
1217
+ pageHeight = Math.max(root.scrollHeight, (_doc$body$scrollHeigh = (_doc$body = doc.body) === null || _doc$body === void 0 ? void 0 : _doc$body.scrollHeight) !== null && _doc$body$scrollHeigh !== void 0 ? _doc$body$scrollHeigh : 0);
1218
+ top = fullPage ? 0 : win.scrollY;
1219
+ height = fullPage ? Math.min(pageHeight, MAX_FULL_PAGE_HEIGHT) : Math.min(win.innerHeight, pageHeight - top);
1220
+ exclude = options.exclude; // Drawn to the bottom of what is wanted, and no further: the cost is the
1221
+ // page's size, so a viewport near the top is cheap.
1222
+ _context.n = 2;
1223
+ return domToCanvas(root, _objectSpread2({
1224
+ width: pageWidth,
1225
+ height: top + height,
1226
+ scale: 1,
1227
+ backgroundColor: pageBackground(win),
1228
+ timeout: LOAD_TIMEOUT_MS
1229
+ }, exclude !== undefined ? {
1230
+ filter: function filter(node) {
1231
+ return !(isElement(node) && exclude(node));
1232
+ }
1233
+ } : {}));
1234
+ case 2:
1235
+ drawn = _context.v;
1236
+ scale = Math.min(1, MAX_WIDTH / pageWidth);
1237
+ out = doc.createElement("canvas");
1238
+ out.width = Math.round(pageWidth * scale);
1239
+ out.height = Math.round(height * scale);
1240
+ context = out.getContext("2d");
1241
+ if (!(context === null)) {
1242
+ _context.n = 3;
1243
+ break;
1244
+ }
1245
+ throw new Error("This browser would not draw the picture.");
1246
+ case 3:
1247
+ context.drawImage(drawn, 0, top, pageWidth, height, 0, 0, out.width, out.height);
1248
+ return _context.a(2, {
1249
+ dataUrl: out.toDataURL("image/jpeg", JPEG_QUALITY),
1250
+ width: out.width,
1251
+ height: out.height,
1252
+ fullPage: fullPage,
1253
+ clipped: top + height < pageHeight
1254
+ });
1255
+ }
1256
+ }, _callee);
1257
+ }));
1258
+ return _screenshotPage.apply(this, arguments);
1259
+ }
1260
+ function pageBackground(win) {
1261
+ for (var _i = 0, _arr = [win.document.body, win.document.documentElement]; _i < _arr.length; _i++) {
1262
+ var element = _arr[_i];
1263
+ if (element === null) continue;
1264
+ var color = win.getComputedStyle(element).backgroundColor;
1265
+ if (color && color !== "transparent" && color !== "rgba(0, 0, 0, 0)") {
1266
+ return color;
1267
+ }
1268
+ }
1269
+ return "#ffffff";
1270
+ }
1271
+ function isElement(node) {
1272
+ return node.nodeType === 1;
1273
+ }
1274
+
1140
1275
  function parseRoutePattern(pattern) {
1141
1276
  if (pattern === "" || pattern === "/") {
1142
1277
  return [];
@@ -1378,4 +1513,4 @@ function getPatternFromModuleFilePath(moduleFilePath, srcFolder) {
1378
1513
  .replace("/page.val.ts", "").replace("/page.val.js", "");
1379
1514
  }
1380
1515
 
1381
- export { quickPreviewSiteOrigin as A, isDesignTabOrigin 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, QUICK_PREVIEW_SERVICE_WORKER_PATH as t, QUICK_PREVIEW_STORE_MESSAGE as u, isQuickPreviewFiles as v, withValCanvasParam as w, QUICK_PREVIEW_SERVICE_WORKER_SOURCE as x, storeQuickPreview as y, withQuickPreviewParam as z };
1516
+ export { withQuickPreviewParam as A, quickPreviewSiteOrigin as B, isDesignTabOrigin as C, DEFAULT_CANVAS_SELECTION as D, parseRoutePattern as E, formatRoutePattern as F, getNextAppRouterSourceFolder as G, getTanStackRouterSourceFolder as H, getPageRouterSourceFolder as I, isTanStackRoutesFolder as J, getPageRouterSitemapTree as K, getPatternFromModuleFilePath as L, 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_STORE_MESSAGE as v, withValCanvasParam as w, isQuickPreviewFiles as x, QUICK_PREVIEW_SERVICE_WORKER_SOURCE as y, storeQuickPreview as z };