@ggui-ai/project-config 0.1.0-rc.3 → 0.2.0-alpha.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/README.md +1 -1
- package/dist/schema.d.ts +105 -19
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +80 -21
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -59,7 +59,7 @@ if (path) {
|
|
|
59
59
|
|
|
60
60
|
`protocol` MUST match `PROTOCOL_VERSION` exported by `@ggui-ai/protocol` in the version installed.
|
|
61
61
|
|
|
62
|
-
Optional blocks: `storage` (
|
|
62
|
+
Optional blocks: `storage` (renders / vectors / threads via `memory` or `sqlite`), `theme`, `primitives`, `blueprints`, `mcpMounts`, and `operator`. See the exported Zod schema for the full, authoritative shape.
|
|
63
63
|
|
|
64
64
|
## License
|
|
65
65
|
|
package/dist/schema.d.ts
CHANGED
|
@@ -123,9 +123,9 @@ declare const StorageSurfaceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
123
123
|
path: z.ZodString;
|
|
124
124
|
}, z.core.$strict>], "driver">;
|
|
125
125
|
declare const StorageSchema: z.ZodObject<{
|
|
126
|
-
/**
|
|
127
|
-
*
|
|
128
|
-
|
|
126
|
+
/** Render persistence (events + identity). Absent = in-memory
|
|
127
|
+
* (renders reset on restart). */
|
|
128
|
+
renders: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
129
129
|
driver: z.ZodLiteral<"memory">;
|
|
130
130
|
}, z.core.$strict>, z.ZodObject<{
|
|
131
131
|
driver: z.ZodLiteral<"sqlite">;
|
|
@@ -150,7 +150,7 @@ declare const StorageSchema: z.ZodObject<{
|
|
|
150
150
|
* deployment Portal's self-hosted flow talks to). Pair with
|
|
151
151
|
* `driver: 'sqlite'` + a `path` for durable local storage; the
|
|
152
152
|
* `@ggui-ai/mcp-server-core/sqlite#SqliteThreadStore` reference
|
|
153
|
-
* impl consumes the same file-per-surface layout the
|
|
153
|
+
* impl consumes the same file-per-surface layout the renders/
|
|
154
154
|
* vectors drivers already use. */
|
|
155
155
|
threads: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
156
156
|
driver: z.ZodLiteral<"memory">;
|
|
@@ -163,13 +163,56 @@ declare const StorageSchema: z.ZodObject<{
|
|
|
163
163
|
}, z.core.$strict>], "driver">>;
|
|
164
164
|
}, z.core.$strict>;
|
|
165
165
|
/**
|
|
166
|
-
* Public type alias for one storage surface's config (
|
|
166
|
+
* Public type alias for one storage surface's config (renders or
|
|
167
167
|
* vectors). Callers instantiating adapters from a parsed manifest
|
|
168
168
|
* pattern-match on `driver`.
|
|
169
169
|
*/
|
|
170
170
|
export type StorageSurfaceConfig = z.infer<typeof StorageSurfaceSchema>;
|
|
171
171
|
/** Public type alias for the full storage block. */
|
|
172
172
|
export type StorageConfig = z.infer<typeof StorageSchema>;
|
|
173
|
+
/**
|
|
174
|
+
* Explicit LLM-route selection for UI generation. The operator
|
|
175
|
+
* declares which `(provider, model)` the OSS `ggui serve` runs
|
|
176
|
+
* against — eliminates the surprise where exporting `OPENAI_API_KEY`
|
|
177
|
+
* silently picks the OpenAI default model.
|
|
178
|
+
*
|
|
179
|
+
* `model` accepts EITHER serialization:
|
|
180
|
+
* - **Canonical** — `provider:model` (e.g. `anthropic:claude-haiku-4-5-20251001`)
|
|
181
|
+
* - **LiteLLM compat** — `provider/model` (e.g. `anthropic/claude-haiku-4-5`)
|
|
182
|
+
*
|
|
183
|
+
* Parsed at schema-load time via `parseAnyLlmRoute` and surfaced
|
|
184
|
+
* as a typed `LlmRoute` for downstream consumers (zero string
|
|
185
|
+
* threading through the dispatch path).
|
|
186
|
+
*/
|
|
187
|
+
declare const GenerationSchema: z.ZodObject<{
|
|
188
|
+
/**
|
|
189
|
+
* Typed LLM route — `(provider, model)` parsed at the schema
|
|
190
|
+
* boundary into a discriminated `LlmRoute`. See
|
|
191
|
+
* `docs/principles/model-string-convention.md`.
|
|
192
|
+
*/
|
|
193
|
+
model: z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
194
|
+
provider: "anthropic";
|
|
195
|
+
model: "claude-haiku-4-5-20251001" | "claude-sonnet-4-6" | "claude-opus-4-7" | "claude-opus-4-6";
|
|
196
|
+
} | {
|
|
197
|
+
provider: "openai";
|
|
198
|
+
model: "gpt-5.5" | "gpt-5.5-2026-04-23" | "gpt-5.5-pro" | "gpt-5.5-pro-2026-04-23" | "gpt-5.4" | "gpt-5.4-2026-03-05" | "gpt-5.4-mini" | "gpt-5.4-mini-2026-03-17" | "gpt-5.4-nano" | "gpt-5.4-nano-2026-03-17" | "gpt-5.3-codex";
|
|
199
|
+
} | {
|
|
200
|
+
provider: "google";
|
|
201
|
+
model: "gemini-3.5-flash" | "gemini-flash-latest" | "gemini-3.1-flash-lite" | "gemini-3.1-pro-preview" | "gemini-3.1-flash-lite-preview" | "gemini-3-flash-preview";
|
|
202
|
+
} | {
|
|
203
|
+
provider: "bedrock";
|
|
204
|
+
model: (string & {}) | "us.anthropic.claude-haiku-4-5-20251001-v1:0" | "eu.anthropic.claude-haiku-4-5-20251001-v1:0" | "apac.anthropic.claude-haiku-4-5-20251001-v1:0" | "global.anthropic.claude-haiku-4-5-20251001-v1:0" | "us.anthropic.claude-sonnet-4-6" | "eu.anthropic.claude-sonnet-4-6" | "apac.anthropic.claude-sonnet-4-6" | "us.anthropic.claude-opus-4-7" | "eu.anthropic.claude-opus-4-7" | "apac.anthropic.claude-opus-4-7" | "global.anthropic.claude-opus-4-7" | "us.anthropic.claude-opus-4-6-v1";
|
|
205
|
+
} | {
|
|
206
|
+
provider: "openrouter";
|
|
207
|
+
model: (string & {}) | "anthropic/claude-haiku-4.5" | "anthropic/claude-sonnet-4.6" | "anthropic/claude-opus-4.7" | "openai/gpt-5.5" | "openai/gpt-5.5-pro" | "openai/gpt-5.4-mini" | "openai/gpt-5.4-nano" | "google/gemini-3.5-flash" | "google/gemini-3.1-pro-preview" | "google/gemini-3.1-flash-lite" | "x-ai/grok-4.3" | "meta-llama/llama-4-maverick" | "meta-llama/llama-3.3-70b-instruct" | "deepseek/deepseek-v4-pro" | "deepseek/deepseek-r1-0528" | "qwen/qwen3.7-max" | "qwen/qwen3-coder" | "mistralai/mistral-large-2512" | "openai/gpt-oss-120b";
|
|
208
|
+
}, string>>;
|
|
209
|
+
}, z.core.$strict>;
|
|
210
|
+
/**
|
|
211
|
+
* Public type alias for the parsed generation block. `model` is the
|
|
212
|
+
* typed `LlmRoute`, NOT the raw string — schema-side transform fires
|
|
213
|
+
* at parse time so downstream consumers never see the string form.
|
|
214
|
+
*/
|
|
215
|
+
export type GenerationConfig = z.infer<typeof GenerationSchema>;
|
|
173
216
|
/**
|
|
174
217
|
* Public type alias for the resolved theme selection (post-parse).
|
|
175
218
|
*
|
|
@@ -302,17 +345,26 @@ export declare const GguiJsonV1: z.ZodObject<{
|
|
|
302
345
|
*/
|
|
303
346
|
publicEnv: z.ZodOptional<z.ZodReadonly<z.ZodRecord<z.ZodString, z.ZodString>>>;
|
|
304
347
|
/**
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
* (`
|
|
308
|
-
*
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
348
|
+
* App-default display-mode hint stamped on every `ggui_render` from
|
|
349
|
+
* this app via `_meta.ui.displayMode`. Spec-aligned with MCP App
|
|
350
|
+
* display literals (`'inline' | 'fullscreen' | 'pip'`).
|
|
351
|
+
*
|
|
352
|
+
* Honored by hosts as a PRESENTATION preference — `'fullscreen'`
|
|
353
|
+
* says "render as a main view"; `'inline'` says "stack vertically in
|
|
354
|
+
* the chat log"; `'pip'` says "render as picture-in-picture overlay".
|
|
355
|
+
* The wire mechanism is identical regardless of mode (every push
|
|
356
|
+
* stamps its own `_meta.ui.resourceUri` and every iframe goes
|
|
357
|
+
* through the same runtime mount path); display mode controls ONLY
|
|
358
|
+
* how the host arranges the iframes it mounts. Agents can override
|
|
359
|
+
* per push via `ggui_render.input.displayMode`.
|
|
360
|
+
*
|
|
361
|
+
* Absent ⇒ no per-push hint stamped (host falls back to its own
|
|
362
|
+
* default, typically `'inline'`).
|
|
312
363
|
*/
|
|
313
|
-
|
|
364
|
+
defaultDisplayMode: z.ZodOptional<z.ZodEnum<{
|
|
314
365
|
inline: "inline";
|
|
315
|
-
|
|
366
|
+
fullscreen: "fullscreen";
|
|
367
|
+
pip: "pip";
|
|
316
368
|
}>>;
|
|
317
369
|
}, z.core.$strict>;
|
|
318
370
|
/** Operator identity — who's running this server. Optional;
|
|
@@ -398,9 +450,9 @@ export declare const GguiJsonV1: z.ZodObject<{
|
|
|
398
450
|
* — no surface silently creates a file on disk. See
|
|
399
451
|
* {@link StorageConfig}. */
|
|
400
452
|
storage: z.ZodOptional<z.ZodObject<{
|
|
401
|
-
/**
|
|
402
|
-
*
|
|
403
|
-
|
|
453
|
+
/** Render persistence (events + identity). Absent = in-memory
|
|
454
|
+
* (renders reset on restart). */
|
|
455
|
+
renders: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
404
456
|
driver: z.ZodLiteral<"memory">;
|
|
405
457
|
}, z.core.$strict>, z.ZodObject<{
|
|
406
458
|
driver: z.ZodLiteral<"sqlite">;
|
|
@@ -425,7 +477,7 @@ export declare const GguiJsonV1: z.ZodObject<{
|
|
|
425
477
|
* deployment Portal's self-hosted flow talks to). Pair with
|
|
426
478
|
* `driver: 'sqlite'` + a `path` for durable local storage; the
|
|
427
479
|
* `@ggui-ai/mcp-server-core/sqlite#SqliteThreadStore` reference
|
|
428
|
-
* impl consumes the same file-per-surface layout the
|
|
480
|
+
* impl consumes the same file-per-surface layout the renders/
|
|
429
481
|
* vectors drivers already use. */
|
|
430
482
|
threads: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
431
483
|
driver: z.ZodLiteral<"memory">;
|
|
@@ -437,6 +489,40 @@ export declare const GguiJsonV1: z.ZodObject<{
|
|
|
437
489
|
path: z.ZodString;
|
|
438
490
|
}, z.core.$strict>], "driver">>;
|
|
439
491
|
}, z.core.$strict>>;
|
|
492
|
+
/**
|
|
493
|
+
* Explicit UI-generation LLM route. Absent + a boot-time provider
|
|
494
|
+
* key resolves → `ggui serve` hard-fails with an actionable error
|
|
495
|
+
* pointing here. Absent + no key → graceful boot (the
|
|
496
|
+
* Connect-Claude card flow handles per-user keys at request time).
|
|
497
|
+
* Present → use this route verbatim; the schema-side
|
|
498
|
+
* `parseAnyLlmRoute` transform yields a typed `LlmRoute` so the
|
|
499
|
+
* dispatch path never sees a string.
|
|
500
|
+
*
|
|
501
|
+
* See {@link GenerationConfig}.
|
|
502
|
+
*/
|
|
503
|
+
generation: z.ZodOptional<z.ZodObject<{
|
|
504
|
+
/**
|
|
505
|
+
* Typed LLM route — `(provider, model)` parsed at the schema
|
|
506
|
+
* boundary into a discriminated `LlmRoute`. See
|
|
507
|
+
* `docs/principles/model-string-convention.md`.
|
|
508
|
+
*/
|
|
509
|
+
model: z.ZodPipe<z.ZodString, z.ZodTransform<{
|
|
510
|
+
provider: "anthropic";
|
|
511
|
+
model: "claude-haiku-4-5-20251001" | "claude-sonnet-4-6" | "claude-opus-4-7" | "claude-opus-4-6";
|
|
512
|
+
} | {
|
|
513
|
+
provider: "openai";
|
|
514
|
+
model: "gpt-5.5" | "gpt-5.5-2026-04-23" | "gpt-5.5-pro" | "gpt-5.5-pro-2026-04-23" | "gpt-5.4" | "gpt-5.4-2026-03-05" | "gpt-5.4-mini" | "gpt-5.4-mini-2026-03-17" | "gpt-5.4-nano" | "gpt-5.4-nano-2026-03-17" | "gpt-5.3-codex";
|
|
515
|
+
} | {
|
|
516
|
+
provider: "google";
|
|
517
|
+
model: "gemini-3.5-flash" | "gemini-flash-latest" | "gemini-3.1-flash-lite" | "gemini-3.1-pro-preview" | "gemini-3.1-flash-lite-preview" | "gemini-3-flash-preview";
|
|
518
|
+
} | {
|
|
519
|
+
provider: "bedrock";
|
|
520
|
+
model: (string & {}) | "us.anthropic.claude-haiku-4-5-20251001-v1:0" | "eu.anthropic.claude-haiku-4-5-20251001-v1:0" | "apac.anthropic.claude-haiku-4-5-20251001-v1:0" | "global.anthropic.claude-haiku-4-5-20251001-v1:0" | "us.anthropic.claude-sonnet-4-6" | "eu.anthropic.claude-sonnet-4-6" | "apac.anthropic.claude-sonnet-4-6" | "us.anthropic.claude-opus-4-7" | "eu.anthropic.claude-opus-4-7" | "apac.anthropic.claude-opus-4-7" | "global.anthropic.claude-opus-4-7" | "us.anthropic.claude-opus-4-6-v1";
|
|
521
|
+
} | {
|
|
522
|
+
provider: "openrouter";
|
|
523
|
+
model: (string & {}) | "anthropic/claude-haiku-4.5" | "anthropic/claude-sonnet-4.6" | "anthropic/claude-opus-4.7" | "openai/gpt-5.5" | "openai/gpt-5.5-pro" | "openai/gpt-5.4-mini" | "openai/gpt-5.4-nano" | "google/gemini-3.5-flash" | "google/gemini-3.1-pro-preview" | "google/gemini-3.1-flash-lite" | "x-ai/grok-4.3" | "meta-llama/llama-4-maverick" | "meta-llama/llama-3.3-70b-instruct" | "deepseek/deepseek-v4-pro" | "deepseek/deepseek-r1-0528" | "qwen/qwen3.7-max" | "qwen/qwen3-coder" | "mistralai/mistral-large-2512" | "openai/gpt-oss-120b";
|
|
524
|
+
}, string>>;
|
|
525
|
+
}, z.core.$strict>>;
|
|
440
526
|
/**
|
|
441
527
|
* Default plugin-registry URL for this app.
|
|
442
528
|
*
|
|
@@ -468,7 +554,7 @@ export declare const GguiJsonV1: z.ZodObject<{
|
|
|
468
554
|
/**
|
|
469
555
|
* Local MCP tool mounts — the operator-facing seam for declaring
|
|
470
556
|
* additional tool surfaces that aggregate onto `/mcp` alongside
|
|
471
|
-
* ggui-native tools (`
|
|
557
|
+
* ggui-native tools (`ggui_render`, etc.). Each entry is a module
|
|
472
558
|
* specifier:
|
|
473
559
|
*
|
|
474
560
|
* - Relative paths (`./path/to/mount.js`, `../local/mcp.mjs`)
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmHxB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,QAAA,MAAM,cAAc;IAClB;sDACkD;;IAElD;8CAC0C;;IAI1C;;uDAEmD;;IAEnD;;;8CAG0C;;kBAI1C,CAAC;AAEH,gDAAgD;AAChD,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AA+H5D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;oBAI5B,CAAC;AAqEH;;;;;GAKG;AACH,QAAA,MAAM,oBAAoB;;;;IAZxB;;oDAEgD;;8BAahD,CAAC;AAEH,QAAA,MAAM,aAAa;IACjB;qCACiC;;;;;QAnBjC;;wDAEgD;;;IAmBhD;gDAC4C;;;;;QAtB5C;;wDAEgD;;;IAsBhD;;;;;;sCAMkC;;;;;QA9BlC;;wDAEgD;;;kBA8BhD,CAAC;AAEH;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,oDAAoD;AACpD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,gBAAgB;IACpB;;;;OAIG;;;;;;;;;;;;;;;;;kBAoBH,CAAC;AAEH;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,UAAU;IACrB;uEACmE;;IAOnE,iDAAiD;;IAKjD,oBAAoB;;;;QAtbpB;;;;;;;;;;;;;;;WAeG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAIH;;;;;;;;;;;;;;;;;WAiBG;;QAEH;;;;;;;;;;;;;;;;WAgBG;;;;;;;IAqYH;;;kDAG8C;;QA/W9C;0DACkD;;QAElD;kDAC0C;;QAI1C;;2DAEmD;;QAEnD;;;kDAG0C;;;IAqW1C,+DAA+D;;QAhV/D;sDAC8C;;;IAoV9C;qEACiE;;;;;IAQjE;;;;;;;;;;;;;;;;;;OAkBG;;;;;;;;;;;;;;;IAKH;0DACsD;;QAhUtD;;;;;kDAK0C;;;IAgU1C;;;;gCAI4B;;QA5K5B;yCACiC;;;;;YAnBjC;;4DAEgD;;;QAmBhD;oDAC4C;;;;;YAtB5C;;4DAEgD;;;QAsBhD;;;;;;0CAMkC;;;;;YA9BlC;;4DAEgD;;;;IAiMhD;;;;;;;;;;OAUG;;QAlJH;;;;WAIG;;;;;;;;;;;;;;;;;;IAmJH;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;;IAQH;;;;;;;;;;;;;;;;;;;;;;;;6EAwByE;;kBASzE,CAAC;AAEH,yDAAyD;AACzD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,GACX,UAAU,CAAC,OAAO,UAAU,CAAC,SAAS,CAAC,CAEzC"}
|
package/dist/schema.js
CHANGED
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
* schema change, not a drive-by.
|
|
42
42
|
*/
|
|
43
43
|
import { z } from 'zod';
|
|
44
|
-
import { appPublicEnvSchema, strictGadgetDescriptorSchema, } from '@ggui-ai/protocol';
|
|
44
|
+
import { appPublicEnvSchema, parseAnyLlmRoute, strictGadgetDescriptorSchema, } from '@ggui-ai/protocol';
|
|
45
45
|
/**
|
|
46
46
|
* App slug — URL-safe identifier. 2–64 chars, lowercase
|
|
47
47
|
* alphanumeric + hyphens, no leading/trailing hyphen. Used as a
|
|
@@ -123,15 +123,23 @@ const AppSchema = z.strictObject({
|
|
|
123
123
|
*/
|
|
124
124
|
publicEnv: appPublicEnvSchema.optional(),
|
|
125
125
|
/**
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* (`
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
126
|
+
* App-default display-mode hint stamped on every `ggui_render` from
|
|
127
|
+
* this app via `_meta.ui.displayMode`. Spec-aligned with MCP App
|
|
128
|
+
* display literals (`'inline' | 'fullscreen' | 'pip'`).
|
|
129
|
+
*
|
|
130
|
+
* Honored by hosts as a PRESENTATION preference — `'fullscreen'`
|
|
131
|
+
* says "render as a main view"; `'inline'` says "stack vertically in
|
|
132
|
+
* the chat log"; `'pip'` says "render as picture-in-picture overlay".
|
|
133
|
+
* The wire mechanism is identical regardless of mode (every push
|
|
134
|
+
* stamps its own `_meta.ui.resourceUri` and every iframe goes
|
|
135
|
+
* through the same runtime mount path); display mode controls ONLY
|
|
136
|
+
* how the host arranges the iframes it mounts. Agents can override
|
|
137
|
+
* per push via `ggui_render.input.displayMode`.
|
|
138
|
+
*
|
|
139
|
+
* Absent ⇒ no per-push hint stamped (host falls back to its own
|
|
140
|
+
* default, typically `'inline'`).
|
|
133
141
|
*/
|
|
134
|
-
|
|
142
|
+
defaultDisplayMode: z.enum(['inline', 'fullscreen', 'pip']).optional(),
|
|
135
143
|
});
|
|
136
144
|
/**
|
|
137
145
|
* Operator identity — who's running this server. Surfaced on the
|
|
@@ -318,9 +326,9 @@ export const ThemeConfigSchema = z.union([
|
|
|
318
326
|
* adapters; no surface ever silently creates a file on disk without
|
|
319
327
|
* the operator declaring it here.
|
|
320
328
|
*
|
|
321
|
-
* ## Why `{
|
|
329
|
+
* ## Why `{renders, vectors}` together
|
|
322
330
|
*
|
|
323
|
-
*
|
|
331
|
+
* Renders + vectors are the two substantial persistence surfaces
|
|
324
332
|
* the OSS server honors today. Shipping them in the same block from
|
|
325
333
|
* v1 avoids a second schema churn when vectors or a future store
|
|
326
334
|
* (e.g. threads) lands — there's one `storage` shape and each known
|
|
@@ -333,14 +341,14 @@ export const ThemeConfigSchema = z.union([
|
|
|
333
341
|
* Explicit driver makes the choice visible at a glance — both to
|
|
334
342
|
* the operator reading the file and to future adapters that land
|
|
335
343
|
* against the same interfaces (`postgres`, `redis`, `libsql`, …).
|
|
336
|
-
* A flat `
|
|
344
|
+
* A flat `renders: "./path.sqlite"` shape would bake sqlite into
|
|
337
345
|
* the schema and force a breaking redesign the first time another
|
|
338
346
|
* driver landed.
|
|
339
347
|
*
|
|
340
348
|
* ## Why per-surface `path` instead of a shared root
|
|
341
349
|
*
|
|
342
|
-
*
|
|
343
|
-
* files:
|
|
350
|
+
* Renders + vectors can (and typically should) live in separate
|
|
351
|
+
* files: render data is small + hot-path; vector data is large +
|
|
344
352
|
* append-heavy. Coupling them into one file conflates two different
|
|
345
353
|
* IO profiles. Operators who want co-located storage can point both
|
|
346
354
|
* paths at the same file — but the schema doesn't force that.
|
|
@@ -360,7 +368,7 @@ export const ThemeConfigSchema = z.union([
|
|
|
360
368
|
*
|
|
361
369
|
* ## Strictness
|
|
362
370
|
*
|
|
363
|
-
* Root `storage` is strict — unknown surface keys (`
|
|
371
|
+
* Root `storage` is strict — unknown surface keys (`rendrs: …`,
|
|
364
372
|
* `vectros: …`, `blueprints: …`) fail parse. Per-surface shapes
|
|
365
373
|
* are discriminated on `driver`; each variant is strict so typos
|
|
366
374
|
* like `{driver: 'sqlite', paht: './x'}` fail immediately.
|
|
@@ -386,9 +394,9 @@ const StorageSurfaceSchema = z.discriminatedUnion('driver', [
|
|
|
386
394
|
StorageSqliteSchema,
|
|
387
395
|
]);
|
|
388
396
|
const StorageSchema = z.strictObject({
|
|
389
|
-
/**
|
|
390
|
-
*
|
|
391
|
-
|
|
397
|
+
/** Render persistence (events + identity). Absent = in-memory
|
|
398
|
+
* (renders reset on restart). */
|
|
399
|
+
renders: StorageSurfaceSchema.optional(),
|
|
392
400
|
/** Vector index persistence (RAG, blueprint embeddings). Absent =
|
|
393
401
|
* in-memory (index rebuilds on restart). */
|
|
394
402
|
vectors: StorageSurfaceSchema.optional(),
|
|
@@ -397,10 +405,49 @@ const StorageSchema = z.strictObject({
|
|
|
397
405
|
* deployment Portal's self-hosted flow talks to). Pair with
|
|
398
406
|
* `driver: 'sqlite'` + a `path` for durable local storage; the
|
|
399
407
|
* `@ggui-ai/mcp-server-core/sqlite#SqliteThreadStore` reference
|
|
400
|
-
* impl consumes the same file-per-surface layout the
|
|
408
|
+
* impl consumes the same file-per-surface layout the renders/
|
|
401
409
|
* vectors drivers already use. */
|
|
402
410
|
threads: StorageSurfaceSchema.optional(),
|
|
403
411
|
});
|
|
412
|
+
/**
|
|
413
|
+
* Explicit LLM-route selection for UI generation. The operator
|
|
414
|
+
* declares which `(provider, model)` the OSS `ggui serve` runs
|
|
415
|
+
* against — eliminates the surprise where exporting `OPENAI_API_KEY`
|
|
416
|
+
* silently picks the OpenAI default model.
|
|
417
|
+
*
|
|
418
|
+
* `model` accepts EITHER serialization:
|
|
419
|
+
* - **Canonical** — `provider:model` (e.g. `anthropic:claude-haiku-4-5-20251001`)
|
|
420
|
+
* - **LiteLLM compat** — `provider/model` (e.g. `anthropic/claude-haiku-4-5`)
|
|
421
|
+
*
|
|
422
|
+
* Parsed at schema-load time via `parseAnyLlmRoute` and surfaced
|
|
423
|
+
* as a typed `LlmRoute` for downstream consumers (zero string
|
|
424
|
+
* threading through the dispatch path).
|
|
425
|
+
*/
|
|
426
|
+
const GenerationSchema = z.strictObject({
|
|
427
|
+
/**
|
|
428
|
+
* Typed LLM route — `(provider, model)` parsed at the schema
|
|
429
|
+
* boundary into a discriminated `LlmRoute`. See
|
|
430
|
+
* `docs/principles/model-string-convention.md`.
|
|
431
|
+
*/
|
|
432
|
+
model: z
|
|
433
|
+
.string()
|
|
434
|
+
.min(1, 'generation.model must not be empty')
|
|
435
|
+
.transform((raw, ctx) => {
|
|
436
|
+
const parsed = parseAnyLlmRoute(raw);
|
|
437
|
+
if (!parsed) {
|
|
438
|
+
ctx.addIssue({
|
|
439
|
+
code: 'custom',
|
|
440
|
+
message: `generation.model "${raw}" is not a recognized LlmRoute. ` +
|
|
441
|
+
`Use the canonical form "provider:model" (e.g. ` +
|
|
442
|
+
`"anthropic:claude-haiku-4-5-20251001") or the LiteLLM ` +
|
|
443
|
+
`form "provider/model" (e.g. "anthropic/claude-haiku-4-5"). ` +
|
|
444
|
+
`See docs/principles/model-string-convention.md.`,
|
|
445
|
+
});
|
|
446
|
+
return z.NEVER;
|
|
447
|
+
}
|
|
448
|
+
return parsed;
|
|
449
|
+
}),
|
|
450
|
+
});
|
|
404
451
|
/**
|
|
405
452
|
* The authoritative v1 schema. `z.infer<typeof GguiJsonV1>` yields
|
|
406
453
|
* the static TypeScript type. A valid document round-trips cleanly:
|
|
@@ -466,7 +513,19 @@ export const GguiJsonV1 = z.strictObject({
|
|
|
466
513
|
* default). Present means the operator has opted in per surface
|
|
467
514
|
* — no surface silently creates a file on disk. See
|
|
468
515
|
* {@link StorageConfig}. */
|
|
469
|
-
storage: StorageSchema.optional().describe('Per-surface storage adapter declarations. Absent = every persistence surface (
|
|
516
|
+
storage: StorageSchema.optional().describe('Per-surface storage adapter declarations. Absent = every persistence surface (renders, threads, vectors, kv) stays in-memory (zero-config OSS default). Present = opt-in per surface; no surface silently creates a file on disk.'),
|
|
517
|
+
/**
|
|
518
|
+
* Explicit UI-generation LLM route. Absent + a boot-time provider
|
|
519
|
+
* key resolves → `ggui serve` hard-fails with an actionable error
|
|
520
|
+
* pointing here. Absent + no key → graceful boot (the
|
|
521
|
+
* Connect-Claude card flow handles per-user keys at request time).
|
|
522
|
+
* Present → use this route verbatim; the schema-side
|
|
523
|
+
* `parseAnyLlmRoute` transform yields a typed `LlmRoute` so the
|
|
524
|
+
* dispatch path never sees a string.
|
|
525
|
+
*
|
|
526
|
+
* See {@link GenerationConfig}.
|
|
527
|
+
*/
|
|
528
|
+
generation: GenerationSchema.optional().describe('Explicit UI-generation LLM route. `model` accepts canonical `provider:model` or LiteLLM `provider/model` form. Absent + a boot key resolves → server hard-fails (operator must pick a model). Absent + no key → graceful per-user fallback flow.'),
|
|
470
529
|
/**
|
|
471
530
|
* Default plugin-registry URL for this app.
|
|
472
531
|
*
|
|
@@ -501,7 +560,7 @@ export const GguiJsonV1 = z.strictObject({
|
|
|
501
560
|
/**
|
|
502
561
|
* Local MCP tool mounts — the operator-facing seam for declaring
|
|
503
562
|
* additional tool surfaces that aggregate onto `/mcp` alongside
|
|
504
|
-
* ggui-native tools (`
|
|
563
|
+
* ggui-native tools (`ggui_render`, etc.). Each entry is a module
|
|
505
564
|
* specifier:
|
|
506
565
|
*
|
|
507
566
|
* - Relative paths (`./path/to/mount.js`, `../local/mcp.mjs`)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ggui-ai/project-config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-alpha.1",
|
|
4
4
|
"description": "Schema and loader for `ggui.json` — the portable app/agent manifest for the ggui protocol. Vendor-neutral. Consumed by the `ggui` CLI and any host that reconstitutes an agent from the manifest.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ggui",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"tinyglobby": "^0.2.16",
|
|
35
35
|
"zod": "^4.3.6",
|
|
36
|
-
"@ggui-ai/protocol": "0.
|
|
37
|
-
"@ggui-ai/design": "0.
|
|
36
|
+
"@ggui-ai/protocol": "0.2.0-alpha.1",
|
|
37
|
+
"@ggui-ai/design": "0.2.0-alpha.1"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^24.0.0",
|