gesso-vite-plugin 0.6.30 → 0.8.0

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,33 @@
1
1
  # gesso-vite-plugin
2
2
 
3
+ ## 0.8.0
4
+
5
+ ### Patch Changes
6
+
7
+ - b80e4ab: The dev server's start says how to connect any agent, not only Claude Code: the endpoint, which any MCP client connects to, and the line to add it in Claude Code, Codex and Gemini CLI. `agentName` names the server in those lines, the root folder's name unless given.
8
+
9
+ ## 0.7.0
10
+
11
+ ### Minor Changes
12
+
13
+ - fe71a86: An application can offer an agent tools of its own, beside its channels' and its screen's: `renderRoot(App).useAgentTools([...])`, and `useAgentTools` on the app builder. A tool is a name, a description, an input schema and a `run` that may answer with text, data and pictures (`agentText`, `agentImages`, `agentError` from `gesso-framework/agent`); its arguments are checked against the schema first. In `gesso-vite-plugin`, `agentInstructions` adds an application's own words to what an agent is told when it connects, and `catalog.exclude` leaves folders of generated code out of the component catalog, so they are not counted as uses.
14
+
15
+ ### Patch Changes
16
+
17
+ - cedb9ff: A call the dev server's agent bridge sent to a page that then closed or reloaded is answered at once, saying the page closed and to call again, rather than left to time out; a tool that waits on purpose would otherwise have kept the agent waiting for its whole wait.
18
+ - 3910bc9: `gesso({ catalog: { root } })` reads another project's components for the agent endpoint, rather than those of the project Vite serves: for an application that designs one, such as a design editor serving the project it works on from another folder. The dev server watches that folder too, so a component saved in a new file there is in the next answer.
19
+ - 4198183: The component catalog reads a project's components through the tsconfig it was given, not whichever one sits beside them, and keeps working when a tsconfig it had seen is deleted while the dev server runs: TypeScript refusing the update is a fresh checker, and a failed read is a warning and an empty catalog, never an unhandled rejection that ended the server.
20
+ - 0e73baa: The dev server's agent endpoint now offers the project's own components, so an AI agent designing a screen uses what is there instead of drawing it again from boxes. `library_overview` lists every component in one line each, `library_search` finds the ones a few words describe, and `library_get` gives one in full: each input's type, default and meaning, examples, and the files that already use it. They are read from the files the project's tsconfig includes, a component saved in a new file is in the next answer, and they are answered on the dev server, so an agent can read them before a page is open. A library's components join only when named: `gesso({ catalog: { libraries: ['gesso-components'] } })`, and `catalog: false` leaves the tools out.
21
+
22
+ `tokens_view` joins the screen tools: the colours, type styles, corner radii, spacing scale and shadows of the theme in force, by name and value, at a control or at the application's outermost content. An agent told the names writes `backgroundColor="surface"` rather than a colour that will not follow the theme into dark mode. `GessoRuntime.themeAt(id)` gives the same theme to anything else that asks.
23
+
24
+ - 4a13fb4: `ContractReader.readComponents(file)` describes every component a module exports, as the channel reader already describes channels: what each one is for, from its JSDoc, and each input as JSON Schema with its TypeScript type, its description, its `@default`, and whether it is required. A callback, a child and a value only code can make are named for what they are rather than rejected. A type several inputs share, such as `UiLength`, is described once under `$defs`, and an input inherited from a shared props type says which one. Point it at a library's index and it reads the whole library: all 55 of `gesso-components` in under half a second. It is the catalog an AI agent designing with the library reads, so that it reaches for `Badge` instead of drawing one from boxes.
25
+
26
+ Every component in `gesso-components` now opens with a one-line JSDoc summary, so hovering one in an editor says what it is. Twelve had their description only in the design note at the top of the file, which attached to whatever was declared under it.
27
+
28
+ - 4894062: The component catalog can be served from a desktop app's main process. `gesso-vite-plugin/catalog` carries it without Vite: `openCatalog({ root, fs })` reads the project's components with the checker and watches `root` with the `fs` it is given, so a component saved in a new file is in the next answer, and answers null when TypeScript 7 is not installed. `serveDesktopAgent` takes it as `catalog` and offers `library_overview`, `library_search` and `library_get` after the channels and the screen, with the catalog's instructions added to the app's, so an agent designing in a desktop app builds with the project's own components.
29
+ - 9c411b1: An application's agent tool can say it waits on purpose, for a person or for its next task, with `waitsUpToMs`: it is listed under MCP's `_meta` as `gesso/waitsUpToMs` (`WAITS_UP_TO`), and the bridges between the agent and the thread, the dev server's and the render worker's, give a call of it that long, where they gave up on every call after two minutes.
30
+
3
31
  ## 0.6.30
4
32
 
5
33
  ## 0.6.29
@@ -0,0 +1,305 @@
1
+ import * as TsApi from "typescript/unstable/sync";
2
+ //#region src/contracts.d.ts
3
+ /**
4
+ * Channel contracts, read by the type checker and written back as JSON
5
+ * Schema.
6
+ *
7
+ * A contract module already says everything an agent driving the
8
+ * application would need to know: the view's keys and their types, each
9
+ * command's parameters and their types, and, where the author wrote
10
+ * them, what each one is for. All of it is types and comments, and
11
+ * both are gone by the time the module runs. This puts them back, as a
12
+ * `describeChannel(token, schema)` call appended to the module, so the
13
+ * token carries its own description wherever it is imported.
14
+ *
15
+ * The checker rather than the syntax, because a contract names its
16
+ * types where it likes: `ProductRow` from another file, a status union
17
+ * behind an alias, a view written as an object literal whose type is
18
+ * inferred. Only the checker resolves all of those the way the compiler
19
+ * that checked the application did. TypeScript 7's checker runs in a
20
+ * separate process behind an API its package calls unstable, so all of
21
+ * it is in this file, and the rest of the plugin sees one function.
22
+ *
23
+ * What the comments carry:
24
+ *
25
+ * - The JSDoc on the exported token is the channel's description, on
26
+ * a view key is that key's, and on a command is the command's.
27
+ * - `@param name text` describes a parameter.
28
+ * - `@destructive`, `@idempotent`, `@confirm` and `@hidden` on a
29
+ * command are its annotations; `CommandSchema` says what each means.
30
+ * - `@hidden` on a view key keeps that key from an agent; see
31
+ * `ChannelSchema.hidden`. On the token, it keeps the whole channel
32
+ * from one; see `ChannelSchema.internal`.
33
+ *
34
+ * And what it will not describe: a value that is not plain data, which
35
+ * cannot cross a channel anyway. A function, a `Date`, a `Map`, a class
36
+ * instance. Each is reported, by its path in the contract, and
37
+ * described as `{}` so the rest of the schema still stands.
38
+ */
39
+ /** The parts of `typescript/unstable/sync` this file uses, values included. */
40
+ type TypeScriptApi = typeof TsApi;
41
+ /** A channel's description, in the shape `describeChannel` takes. */
42
+ interface ChannelSchemaOut {
43
+ description?: string;
44
+ internal?: true;
45
+ view: JsonSchema;
46
+ hidden?: string[];
47
+ commands: Record<string, CommandSchemaOut>;
48
+ }
49
+ interface CommandSchemaOut {
50
+ description?: string;
51
+ parameters: string[];
52
+ rest?: true;
53
+ input: JsonSchema;
54
+ destructive?: true;
55
+ idempotent?: true;
56
+ confirm?: true;
57
+ hidden?: true;
58
+ }
59
+ type JsonSchema = Record<string, unknown>;
60
+ /**
61
+ * A component's description: what it is for, and what each of its
62
+ * inputs takes. The catalog an agent designing with the library reads,
63
+ * so that it uses `Badge` rather than drawing one from boxes.
64
+ */
65
+ interface ComponentSchemaOut {
66
+ /** The first paragraph of its JSDoc: what it is, for a list of many. */
67
+ summary?: string;
68
+ /** The whole JSDoc, for the one component being used. */
69
+ description?: string;
70
+ /**
71
+ * Its inputs, as an object schema. Each input says its TypeScript
72
+ * type as `x-gesso-type`, which an agent writing TSX reads more
73
+ * readily than the schema; an input declared on a shared props type
74
+ * (`ControlLayoutProps`) says which as `x-gesso-from`; a callback is
75
+ * `x-gesso-callback` and a child `x-gesso-child`.
76
+ */
77
+ inputs: JsonSchema;
78
+ /** The `@example` blocks, as written. */
79
+ examples?: string[];
80
+ /** The `@deprecated` text, or true when it gives none. */
81
+ deprecated?: string | true;
82
+ }
83
+ /** Every component a module exports, and what could not be described. */
84
+ interface ComponentReading {
85
+ /** Export name to schema, in declaration order. */
86
+ readonly components: ReadonlyMap<string, ComponentSchemaOut>;
87
+ readonly warnings: readonly string[];
88
+ }
89
+ /** Every channel a module exports, and what could not be described. */
90
+ interface ContractReading {
91
+ /** Export name to schema, in declaration order. */
92
+ readonly channels: ReadonlyMap<string, ChannelSchemaOut>;
93
+ /** One sentence per value that could not be described, naming where it is. */
94
+ readonly warnings: readonly string[];
95
+ }
96
+ /**
97
+ * A module that describes channels when it is imported, for a bundle
98
+ * this plugin never sees.
99
+ *
100
+ * The plugin describes a contract by appending to it as Vite bundles
101
+ * it. An Electrobun main process is bundled by Electrobun's own build,
102
+ * which takes no plugins, so there the description is written ahead of
103
+ * time instead: `gesso-channels` reads the contracts with the same
104
+ * checker and writes this module, and the main process imports it once.
105
+ * A token is imported from its contract, so the schema lands on the
106
+ * same object the application serves.
107
+ *
108
+ * `outFile` and every `file` are absolute POSIX paths.
109
+ */
110
+ declare function describedModule(contracts: readonly {
111
+ readonly file: string;
112
+ readonly channels: ReadonlyMap<string, ChannelSchemaOut>;
113
+ }[], outFile: string): string;
114
+ /**
115
+ * The checker, held open across reads.
116
+ *
117
+ * Spawning it and loading a project costs about a hundred
118
+ * milliseconds; a question after that costs well under one. So one
119
+ * reader lives as long as the dev server or the build, is told which
120
+ * files changed between reads, and is closed at the end, because the
121
+ * process it holds would otherwise keep the build from exiting.
122
+ */
123
+ declare class ContractReader {
124
+ private api;
125
+ private readonly changed;
126
+ private readonly created;
127
+ private readonly deleted;
128
+ /** Each contract's tsconfig, found once. */
129
+ private readonly configs;
130
+ /**
131
+ * @param fs Callbacks the checker reads through before the disk, for
132
+ * a spec that keeps its project in memory.
133
+ */
134
+ private readonly ts;
135
+ private readonly cwd;
136
+ private readonly fs;
137
+ constructor(ts: TypeScriptApi, cwd: string, fs?: TsApi.APIOptions['fs']);
138
+ /**
139
+ * A file changed on disk since the last read. A new or deleted one is
140
+ * said so, because a program's list of files only changes for those:
141
+ * a component in a new file is otherwise not in the catalog.
142
+ */
143
+ invalidate(file: string, event?: 'update' | 'create' | 'delete'): void;
144
+ /**
145
+ * A snapshot of the projects, with what changed since the last one.
146
+ *
147
+ * The checker keeps every project it has opened, and asked to update
148
+ * one whose tsconfig has since been deleted it refuses the whole
149
+ * update ("project not found for update"). That was a dev server gone
150
+ * with it: a project's tsconfig removed while the server ran threw out
151
+ * of the catalog's read and took the process down. A refused update is
152
+ * a checker started afresh, which reads the disk as it now is and
153
+ * opens only what is asked of it again.
154
+ */
155
+ private snapshot;
156
+ /** What changed since the last snapshot, emptied for the next. */
157
+ private takeChanges;
158
+ /** Every channel `file` exports, described. */
159
+ read(file: string): ContractReading;
160
+ /**
161
+ * Every component `file` exports, described: a function whose first
162
+ * parameter is `Inputs<P>`, or a class extending `Component`, whose
163
+ * inputs are its `InputCell` fields. A library's index re-exports its
164
+ * components, and reading it reads all of them.
165
+ */
166
+ readComponents(file: string, config?: string): ComponentReading;
167
+ /**
168
+ * The source files of the project `config` describes, with their
169
+ * text: what the project itself wrote, so neither its dependencies
170
+ * nor declaration files. The project's own tsconfig decides what that
171
+ * is, which is the answer the person already gave their editor.
172
+ */
173
+ sources(config: string): {
174
+ readonly file: string;
175
+ readonly text: string;
176
+ }[];
177
+ /** The inputs a component's type declares, or undefined when it is not a component. */
178
+ private inputsOf;
179
+ /** Whether a function returning `type` returns a child: `UiChild`, an element, or a union of them. */
180
+ private drawable;
181
+ private extendsComponent;
182
+ /**
183
+ * The checker and the module's exports, or why there are none: read
184
+ * in the project `preferred` names when it includes the file (the
185
+ * catalog's own tsconfig, which may resolve its imports differently
186
+ * from any beside it), else the project TypeScript finds for it.
187
+ */
188
+ private open;
189
+ close(): void;
190
+ }
191
+ //#endregion
192
+ //#region src/catalog.d.ts
193
+ /**
194
+ * The project's components, as tools an AI agent designs with.
195
+ *
196
+ * An agent asked for a settings screen will draw one from boxes unless
197
+ * it knows the project already has a `SettingsRow`, a `Toggle` and a
198
+ * `PageHeader`, what each takes, and where the others are used. Those
199
+ * are the project's own: what its designers and its agents made, not a
200
+ * kit the framework ships. So the catalog is read from the project's
201
+ * source, by the checker that already describes its channels, and a
202
+ * library joins it only when the project names one.
203
+ *
204
+ * Three tools, from cheap to complete, so an agent reads only what it
205
+ * needs:
206
+ *
207
+ * library_overview every component, one line each
208
+ * library_search the ones a few words find
209
+ * library_get one, with every input it takes and where it is used
210
+ *
211
+ * They are answered on the dev server rather than in the page, because
212
+ * the checker runs here and a page need not be open for an agent to
213
+ * learn what it can build with.
214
+ */
215
+ /** One component in the catalog. */
216
+ interface CatalogEntry {
217
+ readonly name: string;
218
+ /**
219
+ * Where to import it from: the module's path from the project root
220
+ * without its extension (`src/ui/Picker`), or the library's name.
221
+ */
222
+ readonly from: string;
223
+ /** The library it came from, when it is not the project's own. */
224
+ readonly library?: string;
225
+ readonly schema: ComponentSchemaOut;
226
+ /** Project files that write it as a tag, from the root, its own file left out. */
227
+ readonly usedIn: readonly string[];
228
+ }
229
+ interface CatalogLibrary {
230
+ /** The name it is imported by, such as `gesso-components`. */
231
+ readonly name: string;
232
+ /** The module that exports its components: its entry, resolved. */
233
+ readonly file: string;
234
+ }
235
+ interface ComponentCatalogOptions {
236
+ /** The tsconfig whose files are the project's source. */
237
+ readonly tsconfig: string;
238
+ /**
239
+ * Libraries whose components join the project's own, resolved when the
240
+ * catalog is first read. None by default.
241
+ */
242
+ readonly libraries?: () => Promise<readonly CatalogLibrary[]>;
243
+ /**
244
+ * Folders under the root whose files are not the project's
245
+ * components nor uses of them, from the root: generated code, say,
246
+ * which names the same components in another framework.
247
+ */
248
+ readonly exclude?: readonly string[];
249
+ }
250
+ /** A tool, in the shape MCP's `tools/list` returns. */
251
+ interface CatalogTool {
252
+ readonly name: string;
253
+ readonly title: string;
254
+ readonly description: string;
255
+ readonly inputSchema: Record<string, unknown>;
256
+ readonly annotations: {
257
+ readonly readOnlyHint: true;
258
+ readonly openWorldHint: false;
259
+ };
260
+ }
261
+ /** A tool's answer, in the shape MCP's `tools/call` returns. */
262
+ interface CatalogResult {
263
+ readonly content: readonly {
264
+ readonly type: 'text';
265
+ readonly text: string;
266
+ }[];
267
+ readonly structuredContent?: Record<string, unknown>;
268
+ readonly isError: boolean;
269
+ }
270
+ /** What tells an agent, when it connects, that the catalog is here and to use it. */
271
+ declare const CATALOG_INSTRUCTIONS: string;
272
+ declare const CATALOG_TOOLS: readonly CatalogTool[];
273
+ declare class ComponentCatalog {
274
+ private cached;
275
+ private readonly reader;
276
+ private readonly root;
277
+ private readonly options;
278
+ constructor(reader: () => Promise<ContractReader | null>, root: string, options: ComponentCatalogOptions);
279
+ /**
280
+ * Something in the project changed. The whole catalog is read again
281
+ * on the next call: a project's components read in a tenth of a
282
+ * second, and a save can move a component between files, rename it,
283
+ * or start using it somewhere else.
284
+ */
285
+ invalidate(): void;
286
+ /**
287
+ * The components, read once until something changes. A read that
288
+ * fails (TypeScript refusing a project mid-change) is a warning and an
289
+ * empty catalog, tried again on the next call, never a rejection left
290
+ * for nobody to catch, which ends the dev server.
291
+ */
292
+ entries(): Promise<readonly CatalogEntry[]>;
293
+ call(name: string, args?: Readonly<Record<string, unknown>>): Promise<CatalogResult>;
294
+ private read;
295
+ }
296
+ /**
297
+ * Whether a module could declare a component, without asking the
298
+ * checker: it imports from `gesso-framework` and names `Inputs` or
299
+ * `Component`. Most of a project's files are neither, and each one the
300
+ * checker is spared is a round trip to its process.
301
+ */
302
+ declare function mayDeclareComponent(text: string): boolean;
303
+ //#endregion
304
+ export { CatalogResult as a, ComponentCatalogOptions as c, ComponentSchemaOut as d, ContractReader as f, describedModule as h, CatalogLibrary as i, mayDeclareComponent as l, TypeScriptApi as m, CATALOG_TOOLS as n, CatalogTool as o, ContractReading as p, CatalogEntry as r, ComponentCatalog as s, CATALOG_INSTRUCTIONS as t, ComponentReading as u };
305
+ //# sourceMappingURL=catalog-CbeOrdxD.d.ts.map