@ggui-ai/dev-stack 0.9.0 → 0.11.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.
@@ -19685,7 +19685,7 @@ var __export2 = (target, all) => {
19685
19685
  };
19686
19686
 
19687
19687
  // ../protocol/dist/version.js
19688
- var PROTOCOL_VERSION = "draft-2026-06-12";
19688
+ var PROTOCOL_VERSION = "draft-2026-08-19";
19689
19689
  var PROTOCOL_SCHEMA_VERSION = PROTOCOL_VERSION;
19690
19690
  var CLIENT_SUPPORTED_VERSIONS = Object.freeze([
19691
19691
  PROTOCOL_SCHEMA_VERSION
@@ -34212,7 +34212,7 @@ config(en_default());
34212
34212
 
34213
34213
  // ../protocol/dist/gadgets/stdlib-gadgets.js
34214
34214
  var STDLIB_GADGETS_PACKAGE = "@ggui-ai/gadgets";
34215
- var STDLIB_GADGETS_VERSION = "0.9.0";
34215
+ var STDLIB_GADGETS_VERSION = "0.11.0";
34216
34216
  var STDLIB_GADGETS = [
34217
34217
  {
34218
34218
  package: STDLIB_GADGETS_PACKAGE,
@@ -34363,15 +34363,24 @@ var jsonValueSchema = external_exports.lazy(() => external_exports.union([
34363
34363
  // surface as `undefined` at runtime which JSON.stringify drops.
34364
34364
  external_exports.record(external_exports.string(), jsonValueSchema)
34365
34365
  ]));
34366
+ var jsonSchemaTypeNameSchema = external_exports.enum([
34367
+ "string",
34368
+ "number",
34369
+ "integer",
34370
+ "boolean",
34371
+ "array",
34372
+ "object",
34373
+ "null"
34374
+ ]);
34366
34375
  var jsonSchemaSchema = external_exports.lazy(() => external_exports.object({
34367
- type: external_exports.enum([
34368
- "string",
34369
- "number",
34370
- "integer",
34371
- "boolean",
34372
- "array",
34373
- "object",
34374
- "null"
34376
+ // Single type OR a draft-07 type array (`['string','null']` —
34377
+ // the canonical nullability form the enforced-props-schema
34378
+ // emission produces). Mirrors `JsonSchemaTypeName | JsonSchemaTypeName[]`
34379
+ // on the TS type — the zod and TS sides are an SSoT pair; widen
34380
+ // both or neither.
34381
+ type: external_exports.union([
34382
+ jsonSchemaTypeNameSchema,
34383
+ external_exports.array(jsonSchemaTypeNameSchema)
34375
34384
  ]).optional(),
34376
34385
  description: external_exports.string().optional(),
34377
34386
  enum: external_exports.array(jsonValueSchema).optional(),
@@ -34539,12 +34548,12 @@ var clientCapabilitiesSpecSchema = external_exports.object({
34539
34548
  }).strict();
34540
34549
  var appPublicEnvSchema = external_exports.record(external_exports.string().regex(PUBLIC_ENV_APP_KEY_RE), external_exports.string()).readonly();
34541
34550
  var dataContractSchema = external_exports.object({
34542
- propsSpec: propsSpecSchema.optional(),
34543
- actionSpec: actionSpecSchema.optional(),
34544
- streamSpec: streamSpecSchema.optional(),
34545
- contextSpec: contextSpecSchema.optional(),
34546
- agentCapabilities: agentCapabilitiesSpecSchema.optional(),
34547
- clientCapabilities: clientCapabilitiesSpecSchema.optional()
34551
+ propsSpec: propsSpecSchema.optional().describe("Initial render data: {description?, properties: {<name>: {schema: <JSON Schema>, required?: boolean, description?, default?, example?}}}. A prop is required at the wire gate ONLY when `required: true`; omitted \u21D2 optional (declare `required: true` for props the render must always pass)."),
34552
+ actionSpec: actionSpecSchema.optional().describe("User gestures the agent reacts to on its next turn: {<action>: {label: string (REQUIRED \u2014 button copy / accessible name), schema?: <payload JSON Schema>, description?, example?, icon?, confirm?, nextStep?: '<agentCapabilities.tools key>'}}. Every action is agent-routed; `nextStep` is a hint, not a dispatch."),
34553
+ streamSpec: streamSpecSchema.optional().describe("Live update channels the agent emits into: {<channel>: {schema: <JSON Schema>, description?, example?, mode?: append|replace, replay?: latest|all|none, complete?, source?: {tool, args?}}}. `source.tool` must be declared in agentCapabilities.tools."),
34554
+ contextSpec: contextSpecSchema.optional().describe("Observable client state the agent reads alongside each action: {<slot>: {schema: <JSON Schema>, description?, default?, debounceMs?, example?}}. State that needs no next-turn reasoning belongs here, not in actionSpec."),
34555
+ agentCapabilities: agentCapabilitiesSpecSchema.optional().describe("MCP tools the AGENT may call: {tools: {<bareToolName>: {toolInfo: {inputSchema (REQUIRED), description?, outputSchema?}, serverInfo?: {name, version?}, usage?, example?: {input, output}}}}. Key by the BARE tool name (after any `mcp__<server>__` prefix); the component never calls these."),
34556
+ clientCapabilities: clientCapabilitiesSpecSchema.optional().describe("Browser-capability gadgets the COMPONENT imports: {gadgets: {<npm package>: {<exportName>: {description?, usage?}}}} \u2014 `use`-prefixed export keys are hooks, PascalCase keys are components; version and transport resolve from the app's registered catalog, never on the wire.")
34548
34557
  }).passthrough();
34549
34558
 
34550
34559
  // ../protocol/dist/schemas/blueprint.js
@@ -34560,11 +34569,17 @@ var blueprintSourceSchema = external_exports.union([
34560
34569
  userBlueprintSourceSchema,
34561
34570
  curatedBlueprintSourceSchema
34562
34571
  ]);
34572
+ var BLUEPRINT_VARIANCE_KEYS = ["persona", "aesthetic", "context", "seedPrompt"];
34563
34573
  var blueprintVarianceSchema = external_exports.object({
34564
34574
  persona: external_exports.string().optional().describe('Design persona, e.g. "minimalist" / "data-dense". Part of cache identity.'),
34565
34575
  aesthetic: external_exports.string().optional().describe('Visual aesthetic, e.g. "calm" / "ornate". Part of cache identity.'),
34566
34576
  context: external_exports.record(external_exports.string(), jsonValueSchema).optional().describe('Deliberate design-shaping signals (e.g. {situation:"sad"}) \u2014 part of cache identity. NOT for per-user runtime data; put that in propsSpec/contextSpec.'),
34567
34577
  seedPrompt: external_exports.string().optional().describe("Generation seed directive. Part of cache identity.")
34578
+ }, {
34579
+ // A rejection that teaches (ggui#523 item 2): the first live guest
34580
+ // turn sent `mood` and got a bare "Unrecognized key" — name the
34581
+ // legal set and where the misplaced intent belongs.
34582
+ error: (issue2) => issue2.code === "unrecognized_keys" ? `variance: unknown key(s) ${issue2.keys.map((k) => JSON.stringify(k)).join(", ")} \u2014 variance is EXACTLY {${BLUEPRINT_VARIANCE_KEYS.join(", ")}}; put tonal intent in \`aesthetic\`, and per-user runtime data in props / contextSpec, never in variance` : void 0
34568
34583
  }).strict();
34569
34584
  var blueprintSchema = external_exports.object({
34570
34585
  blueprintId: external_exports.string().min(1),
@@ -34625,15 +34640,17 @@ var jsonPatchOpSchema = external_exports.union([
34625
34640
  }).strict()
34626
34641
  ]);
34627
34642
  var jsonPatchSchema = external_exports.array(jsonPatchOpSchema);
34643
+ var BLUEPRINT_DRAFT_KEYS = ["contract", "variance", "generator"];
34628
34644
  var blueprintDraftObjectSchema = external_exports.object({
34629
34645
  contract: dataContractSchema,
34630
- variance: external_exports.object({
34631
- persona: external_exports.string().optional(),
34632
- aesthetic: external_exports.string().optional(),
34633
- context: external_exports.record(external_exports.string(), jsonValueSchema).optional(),
34634
- seedPrompt: external_exports.string().optional()
34635
- }).strict().optional(),
34646
+ // ONE declaration of the variance shape, protocol-wide: the same
34647
+ // schema (with its `.describe()` teaching and its legal-set
34648
+ // rejection message) that `blueprintMeta.variance` projects on the
34649
+ // way back out (ggui#523 item 1 — the mirror-of-a-mirror is gone).
34650
+ variance: blueprintVarianceSchema.optional(),
34636
34651
  generator: external_exports.string().optional()
34652
+ }, {
34653
+ error: (issue2) => issue2.code === "unrecognized_keys" ? `blueprintDraft: unknown key(s) ${issue2.keys.map((k) => JSON.stringify(k)).join(", ")} \u2014 a draft is EXACTLY {${BLUEPRINT_DRAFT_KEYS.join(", ")}}; \`intent\` is a top-level ggui_handshake field, not a draft field, and the four specs live INSIDE \`contract\`` : void 0
34637
34654
  }).strict();
34638
34655
  var blueprintDraftSchema = blueprintDraftObjectSchema;
34639
34656
  var blueprintMetaSchema = external_exports.object({
@@ -34695,6 +34712,10 @@ var getSessionInputShape = {
34695
34712
  sessionId: external_exports.string().min(1).describe("GguiSession opaque id (UUID) \u2014 returned by ggui_render.")
34696
34713
  };
34697
34714
  var getSessionInputSchema = external_exports.object(getSessionInputShape);
34715
+ var getRenderSourceInputShape = {
34716
+ sessionId: external_exports.string().min(1).describe("GguiSession opaque id (UUID) \u2014 returned by ggui_render.")
34717
+ };
34718
+ var getRenderSourceInputSchema = external_exports.object(getRenderSourceInputShape);
34698
34719
  var listFeaturedBlueprintsInputShape = {};
34699
34720
  var listFeaturedBlueprintsInputSchema = external_exports.object(listFeaturedBlueprintsInputShape);
34700
34721
  var searchBlueprintsInputShape = {
@@ -34729,7 +34750,7 @@ var handshakeInputSchema = external_exports.object({
34729
34750
  * and the contract validators; variance feeds the variance axis
34730
34751
  * and rides through to the suggestion's `blueprintMeta`.
34731
34752
  */
34732
- blueprintDraft: blueprintDraftSchema.describe("Agent's draft: contract (required) + optional variance + optional generator slug hint. The server combines this with cached blueprints + validator outcomes to produce a three-mode suggestion (cache / agent / synth)."),
34753
+ blueprintDraft: blueprintDraftSchema.describe(`Agent's draft \u2014 a JSON OBJECT, never a JSON-encoded string (pass {contract: {...}}, not "{\\"contract\\":...}"; a string fails input validation with -32602). Fields: contract (required) + optional variance + optional generator slug hint. The server combines this with cached blueprints + validator outcomes to produce a three-mode suggestion (cache / agent / synth).`),
34733
34754
  /**
34734
34755
  * Skip blueprint-search on step-2 and route straight to validation
34735
34756
  * + (if validation passes) agent-mode suggestion against the draft.
@@ -35135,87 +35156,13 @@ var appThemeSchema = external_exports.object({
35135
35156
  // ../protocol/dist/registry/canonicalize-contract.js
35136
35157
  var import_canonicalize = __toESM(require_canonicalize(), 1);
35137
35158
 
35159
+ // ../protocol/dist/validation/enforced-props-schema.js
35160
+ var import_canonicalize2 = __toESM(require_canonicalize(), 1);
35161
+
35138
35162
  // ../protocol/dist/types/data-contract.js
35139
35163
  var CONTEXT_SLOT_VALUE_MAX_BYTES = 16 * 1024;
35140
35164
  var CONTEXT_SNAPSHOT_MAX_BYTES = 64 * 1024;
35141
35165
 
35142
- // ../protocol/dist/schemas/ops-blueprint.js
35143
- var opsGenerateBlueprintInputSchema = external_exports.object({
35144
- contract: dataContractSchema,
35145
- generator: external_exports.string().min(1).optional().describe("Generator slug (e.g. `ui-gen-default-haiku-4-5`). When omitted, dispatches through `GeneratorRegistry.defaultGenerator()`."),
35146
- persona: external_exports.string().optional().describe("Free-form persona tag (e.g. 'minimalist', 'data-dense'). Normalized via lowercase+trim before persistence; logged as a warning when within Levenshtein distance < 2 of an existing tag for the same appId."),
35147
- aesthetic: external_exports.string().optional().describe("Free-form aesthetic tag (e.g. 'glassmorphic', 'brutalist', 'editorial'). Persisted on `Blueprint.variance.aesthetic`. Distinct from persona \u2014 persona names the user mental model; aesthetic names the visual treatment."),
35148
- context: external_exports.record(external_exports.string(), jsonValueSchema).optional().describe("Small structured signal carried alongside the persona. Persisted on `Blueprint.variance.context`."),
35149
- seedPrompt: external_exports.string().optional().describe("The raw operator prompt that produced this variant. Round-trip input for the variant-selector + audit trail."),
35150
- setAsOperatorDefault: external_exports.boolean().optional().describe("When true, pins the new blueprint as the operator default for its `(appId, contractHash)` group, clearing any prior default in the same group.")
35151
- }).strict();
35152
- var opsGenerateBlueprintOutputSchema = external_exports.object({
35153
- blueprintId: external_exports.string().min(1),
35154
- codeHash: external_exports.string().optional().describe("Content hash of the generated code body. Absent when the generator returned a non-`ok` result and persistence skipped \u2014 the failure mode is surfaced through generator-level error reporting elsewhere."),
35155
- validatorScore: external_exports.number().min(0).max(1).optional().describe("Advanced generator's iterative-loop validator score (0-1). Absent for default-generator output."),
35156
- source: llmBlueprintSourceSchema.describe("Provenance stamped on the persisted `Blueprint.source` \u2014 always the `llm` arm on this path: `generator` is the engine slug the dispatch resolved to (stamped from the engine's own metadata claim); `model` is the LLM model id the engine called.")
35157
- }).strict();
35158
- var opsRegisterBlueprintInputSchema = external_exports.object({
35159
- contract: dataContractSchema,
35160
- componentCode: external_exports.string().min(1).describe("Verbatim component-code body to persist. Stored as-is \u2014 no LLM call, no validator pass. Operator owns correctness; the handler computes the canonical sha256 codeHash and routes the bytes through the same persistence seams as `*_generate_*`."),
35161
- persona: external_exports.string().optional().describe("Free-form persona tag (e.g. 'minimalist', 'data-dense'). Normalized via lowercase+trim before persistence; logged as a warning when within Levenshtein distance < 2 of an existing tag for the same appId."),
35162
- aesthetic: external_exports.string().optional().describe("Free-form aesthetic tag. Persisted on `Blueprint.variance.aesthetic`."),
35163
- context: external_exports.record(external_exports.string(), jsonValueSchema).optional().describe("Small structured signal carried alongside the persona. Persisted on `Blueprint.variance.context`."),
35164
- seedPrompt: external_exports.string().optional().describe("Optional originating prompt for audit + round-tripping (e.g. the prose the operator originally fed into `*_generate_*` before exporting)."),
35165
- setAsOperatorDefault: external_exports.boolean().optional().describe("When true, pins the new blueprint as the operator default for its `(appId, contractHash)` group, clearing any prior default in the same group.")
35166
- }).strict();
35167
- var opsRegisterBlueprintOutputSchema = external_exports.object({
35168
- blueprintId: external_exports.string().min(1),
35169
- codeHash: external_exports.string().min(1).describe("Content hash of the persisted code body (full sha256 hex)."),
35170
- source: userBlueprintSourceSchema.describe('Provenance stamped on the persisted `Blueprint.source` \u2014 always `{kind: "user"}` on this path: operator-supplied bytes, no LLM dispatch, no engine claim to record.')
35171
- }).strict();
35172
- var opsListBlueprintsInputSchema = external_exports.object({
35173
- contractHash: external_exports.string().min(1).optional().describe("Filter to a single `(appId, contractHash)` group. Combine with `generator` / `persona` to narrow within the group."),
35174
- generator: external_exports.string().min(1).optional().describe('Filter to engine-generated blueprints (`source.kind === "llm"`) whose `source.generator` equals this slug. `user`-sourced rows never match (they carry no engine provenance).'),
35175
- persona: external_exports.string().optional().describe("Filter on `variance.persona`. Normalized to match persisted form (lowercase+trim)."),
35176
- intentKeywords: external_exports.array(external_exports.string().min(1)).optional().describe("Semantic-search tokens. When set, dispatches through `BlueprintSearch.search()` rather than indexed `list()`.")
35177
- }).strict();
35178
- var opsListBlueprintsOutputSchema = external_exports.object({
35179
- blueprints: external_exports.array(blueprintSchema)
35180
- }).strict();
35181
- var opsUpdateBlueprintInputSchema = external_exports.object({
35182
- blueprintId: external_exports.string().min(1),
35183
- isOperatorDefault: external_exports.literal(true).optional().describe("When `true`, pins this blueprint as the operator default for its `(appId, contractHash)` group. Clears any prior default. Cannot set to `false` \u2014 to unpin, set another blueprint in the same group as default, or delete this one."),
35184
- variance: blueprintVarianceSchema.optional().describe('Partial-merge into the existing variance. Supplied keys overwrite; omitted keys preserve. Pass `{persona: ""}` to clear a persona (handler treats empty string as removal).')
35185
- }).strict();
35186
- var opsUpdateBlueprintOutputSchema = external_exports.object({
35187
- blueprintId: external_exports.string().min(1),
35188
- updatedAt: external_exports.string().min(1)
35189
- }).strict();
35190
- var opsDeleteBlueprintInputSchema = external_exports.object({
35191
- blueprintId: external_exports.string().min(1)
35192
- }).strict();
35193
- var opsDeleteBlueprintOutputSchema = external_exports.object({
35194
- deleted: external_exports.literal(true)
35195
- }).strict();
35196
-
35197
- // ../protocol/dist/envelopes/builders.js
35198
- function resolveSchemaVersion(parts) {
35199
- if ("schemaVersion" in parts) {
35200
- return parts.schemaVersion;
35201
- }
35202
- return PROTOCOL_SCHEMA_VERSION;
35203
- }
35204
- function makeActionEnvelope(parts) {
35205
- const envelope = {
35206
- sessionId: parts.sessionId,
35207
- type: parts.type
35208
- };
35209
- if (parts.payload !== void 0)
35210
- envelope.payload = parts.payload;
35211
- if (parts.clientSeq !== void 0)
35212
- envelope.clientSeq = parts.clientSeq;
35213
- const stamp = resolveSchemaVersion(parts);
35214
- if (stamp !== void 0)
35215
- envelope.schemaVersion = stamp;
35216
- return envelope;
35217
- }
35218
-
35219
35166
  // ../protocol/dist/validation/ajv-runtime.js
35220
35167
  var import_ajv = __toESM(require_ajv(), 1);
35221
35168
  var import_ajv_formats = __toESM(require_dist(), 1);
@@ -35258,8 +35205,20 @@ if (!standaloneAjv.getKeyword("example")) {
35258
35205
  if (!standaloneAjv.getKeyword("nullable")) {
35259
35206
  standaloneAjv.addKeyword({ keyword: "nullable" });
35260
35207
  }
35208
+ var standaloneCjsAjv = new import_ajv.default({
35209
+ ...AJV_OPTIONS,
35210
+ code: { source: true }
35211
+ });
35212
+ (0, import_ajv_formats.default)(standaloneCjsAjv);
35213
+ if (!standaloneCjsAjv.getKeyword("example")) {
35214
+ standaloneCjsAjv.addKeyword({ keyword: "example" });
35215
+ }
35216
+ if (!standaloneCjsAjv.getKeyword("nullable")) {
35217
+ standaloneCjsAjv.addKeyword({ keyword: "nullable" });
35218
+ }
35261
35219
  function injectClosedShape(schema) {
35262
- const isObjectNode = schema.type === "object" || schema.properties !== void 0;
35220
+ const typeSet = new Set(Array.isArray(schema.type) ? schema.type : schema.type ? [schema.type] : []);
35221
+ const isObjectNode = typeSet.has("object") || schema.properties !== void 0;
35263
35222
  if (isObjectNode) {
35264
35223
  const out = { ...schema };
35265
35224
  if (out.properties) {
@@ -35280,7 +35239,7 @@ function injectClosedShape(schema) {
35280
35239
  out.anyOf = out.anyOf.map(injectClosedShape);
35281
35240
  return out;
35282
35241
  }
35283
- if (schema.type === "array" && schema.items) {
35242
+ if (typeSet.has("array") && schema.items) {
35284
35243
  return { ...schema, items: injectClosedShape(schema.items) };
35285
35244
  }
35286
35245
  if (schema.oneOf || schema.anyOf) {
@@ -35300,7 +35259,10 @@ function compileForValidation(schema) {
35300
35259
  function mapAjvErrorsToViolations(errors, data) {
35301
35260
  if (!errors)
35302
35261
  return [];
35303
- return errors.map((err) => mapOne(err, data));
35262
+ return errors.map((err) => ({
35263
+ ...mapOne(err, data),
35264
+ ...err.keyword ? { keyword: err.keyword } : {}
35265
+ }));
35304
35266
  }
35305
35267
  function prefixViolations(violations, prefix) {
35306
35268
  if (!prefix)
@@ -35647,6 +35609,88 @@ function validateActionEnvelope(envelope, spec, precompiledActions) {
35647
35609
  return validateActionData(envelope.payload, spec, precompiledActions);
35648
35610
  }
35649
35611
 
35612
+ // ../protocol/dist/schemas/ops-blueprint.js
35613
+ var opsGenerateBlueprintInputSchema = external_exports.object({
35614
+ appId: external_exports.string().min(1).optional().describe("Target app for this curation call. Defaults to the caller's bound app identity; callers not bound to an app must provide it. The deployment's authorization policy decides whether the caller may curate the named app."),
35615
+ contract: dataContractSchema,
35616
+ generator: external_exports.string().min(1).optional().describe("Generator slug (e.g. `ui-gen-default-haiku-4-5`). When omitted, dispatches through `GeneratorRegistry.defaultGenerator()`."),
35617
+ persona: external_exports.string().optional().describe("Free-form persona tag (e.g. 'minimalist', 'data-dense'). Normalized via lowercase+trim before persistence; logged as a warning when within Levenshtein distance < 2 of an existing tag for the same appId."),
35618
+ aesthetic: external_exports.string().optional().describe("Free-form aesthetic tag (e.g. 'glassmorphic', 'brutalist', 'editorial'). Persisted on `Blueprint.variance.aesthetic`. Distinct from persona \u2014 persona names the user mental model; aesthetic names the visual treatment."),
35619
+ context: external_exports.record(external_exports.string(), jsonValueSchema).optional().describe("Small structured signal carried alongside the persona. Persisted on `Blueprint.variance.context`."),
35620
+ seedPrompt: external_exports.string().optional().describe("The raw operator prompt that produced this variant. Round-trip input for the variant-selector + audit trail."),
35621
+ setAsOperatorDefault: external_exports.boolean().optional().describe("When true, pins the new blueprint as the operator default for its `(appId, contractHash)` group, clearing any prior default in the same group.")
35622
+ }).strict();
35623
+ var opsGenerateBlueprintOutputSchema = external_exports.object({
35624
+ blueprintId: external_exports.string().min(1),
35625
+ codeHash: external_exports.string().optional().describe("Content hash of the generated code body. Absent when the generator returned a non-`ok` result and persistence skipped \u2014 the failure mode is surfaced through generator-level error reporting elsewhere."),
35626
+ validatorScore: external_exports.number().min(0).max(1).optional().describe("Advanced generator's iterative-loop validator score (0-1). Absent for default-generator output."),
35627
+ source: llmBlueprintSourceSchema.describe("Provenance stamped on the persisted `Blueprint.source` \u2014 always the `llm` arm on this path: `generator` is the engine slug the dispatch resolved to (stamped from the engine's own metadata claim); `model` is the LLM model id the engine called.")
35628
+ }).strict();
35629
+ var opsRegisterBlueprintInputSchema = external_exports.object({
35630
+ appId: external_exports.string().min(1).optional().describe("Target app for this curation call. Defaults to the caller's bound app identity; callers not bound to an app must provide it. The deployment's authorization policy decides whether the caller may curate the named app."),
35631
+ contract: dataContractSchema,
35632
+ componentCode: external_exports.string().min(1).describe("Verbatim component-code body to persist. Stored as-is \u2014 no LLM call, no validator pass. Operator owns correctness; the handler computes the canonical sha256 codeHash and routes the bytes through the same persistence seams as `*_generate_*`."),
35633
+ persona: external_exports.string().optional().describe("Free-form persona tag (e.g. 'minimalist', 'data-dense'). Normalized via lowercase+trim before persistence; logged as a warning when within Levenshtein distance < 2 of an existing tag for the same appId."),
35634
+ aesthetic: external_exports.string().optional().describe("Free-form aesthetic tag. Persisted on `Blueprint.variance.aesthetic`."),
35635
+ context: external_exports.record(external_exports.string(), jsonValueSchema).optional().describe("Small structured signal carried alongside the persona. Persisted on `Blueprint.variance.context`."),
35636
+ seedPrompt: external_exports.string().optional().describe("Optional originating prompt for audit + round-tripping (e.g. the prose the operator originally fed into `*_generate_*` before exporting)."),
35637
+ setAsOperatorDefault: external_exports.boolean().optional().describe("When true, pins the new blueprint as the operator default for its `(appId, contractHash)` group, clearing any prior default in the same group.")
35638
+ }).strict();
35639
+ var opsRegisterBlueprintOutputSchema = external_exports.object({
35640
+ blueprintId: external_exports.string().min(1),
35641
+ codeHash: external_exports.string().min(1).describe("Content hash of the persisted code body (full sha256 hex)."),
35642
+ source: userBlueprintSourceSchema.describe('Provenance stamped on the persisted `Blueprint.source` \u2014 always `{kind: "user"}` on this path: operator-supplied bytes, no LLM dispatch, no engine claim to record.')
35643
+ }).strict();
35644
+ var opsListBlueprintsInputSchema = external_exports.object({
35645
+ appId: external_exports.string().min(1).optional().describe("Target app for this curation call. Defaults to the caller's bound app identity; callers not bound to an app must provide it. The deployment's authorization policy decides whether the caller may curate the named app."),
35646
+ contractHash: external_exports.string().min(1).optional().describe("Filter to a single `(appId, contractHash)` group. Combine with `generator` / `persona` to narrow within the group."),
35647
+ generator: external_exports.string().min(1).optional().describe('Filter to engine-generated blueprints (`source.kind === "llm"`) whose `source.generator` equals this slug. `user`-sourced rows never match (they carry no engine provenance).'),
35648
+ persona: external_exports.string().optional().describe("Filter on `variance.persona`. Normalized to match persisted form (lowercase+trim)."),
35649
+ intentKeywords: external_exports.array(external_exports.string().min(1)).optional().describe("Semantic-search tokens. When set, dispatches through `BlueprintSearch.search()` rather than indexed `list()`.")
35650
+ }).strict();
35651
+ var opsListBlueprintsOutputSchema = external_exports.object({
35652
+ blueprints: external_exports.array(blueprintSchema)
35653
+ }).strict();
35654
+ var opsUpdateBlueprintInputSchema = external_exports.object({
35655
+ appId: external_exports.string().min(1).optional().describe("Target app for this curation call. Defaults to the caller's bound app identity; callers not bound to an app must provide it. The deployment's authorization policy decides whether the caller may curate the named app. Must match the app the addressed blueprint belongs to."),
35656
+ blueprintId: external_exports.string().min(1),
35657
+ isOperatorDefault: external_exports.literal(true).optional().describe("When `true`, pins this blueprint as the operator default for its `(appId, contractHash)` group. Clears any prior default. Cannot set to `false` \u2014 to unpin, set another blueprint in the same group as default, or delete this one."),
35658
+ variance: blueprintVarianceSchema.optional().describe('Partial-merge into the existing variance. Supplied keys overwrite; omitted keys preserve. Pass `{persona: ""}` to clear a persona (handler treats empty string as removal).')
35659
+ }).strict();
35660
+ var opsUpdateBlueprintOutputSchema = external_exports.object({
35661
+ blueprintId: external_exports.string().min(1),
35662
+ updatedAt: external_exports.string().min(1)
35663
+ }).strict();
35664
+ var opsDeleteBlueprintInputSchema = external_exports.object({
35665
+ appId: external_exports.string().min(1).optional().describe("Target app for this curation call. Defaults to the caller's bound app identity; callers not bound to an app must provide it. The deployment's authorization policy decides whether the caller may curate the named app. Must match the app the addressed blueprint belongs to."),
35666
+ blueprintId: external_exports.string().min(1)
35667
+ }).strict();
35668
+ var opsDeleteBlueprintOutputSchema = external_exports.object({
35669
+ deleted: external_exports.literal(true)
35670
+ }).strict();
35671
+
35672
+ // ../protocol/dist/envelopes/builders.js
35673
+ function resolveSchemaVersion(parts) {
35674
+ if ("schemaVersion" in parts) {
35675
+ return parts.schemaVersion;
35676
+ }
35677
+ return PROTOCOL_SCHEMA_VERSION;
35678
+ }
35679
+ function makeActionEnvelope(parts) {
35680
+ const envelope = {
35681
+ sessionId: parts.sessionId,
35682
+ type: parts.type
35683
+ };
35684
+ if (parts.payload !== void 0)
35685
+ envelope.payload = parts.payload;
35686
+ if (parts.clientSeq !== void 0)
35687
+ envelope.clientSeq = parts.clientSeq;
35688
+ const stamp = resolveSchemaVersion(parts);
35689
+ if (stamp !== void 0)
35690
+ envelope.schemaVersion = stamp;
35691
+ return envelope;
35692
+ }
35693
+
35650
35694
  // ../mcp-apps-react/dist/index.mjs
35651
35695
  var import_react5 = __toESM(require_react(), 1);
35652
35696
  var import_react6 = __toESM(require_react(), 1);
@@ -36185,7 +36229,7 @@ function resolveToneCss(tone) {
36185
36229
  case "warning":
36186
36230
  case "error":
36187
36231
  case "info":
36188
- return `var(--ggui-color-${tone}, ${SEMANTIC_TONE_FALLBACK[tone]})`;
36232
+ return `var(--ggui-color-${tone}-500, ${SEMANTIC_TONE_FALLBACK[tone]})`;
36189
36233
  case "inverse":
36190
36234
  return "var(--ggui-color-surface, #ffffff)";
36191
36235
  case "inherit":
@@ -43796,19 +43840,19 @@ function walkTokens(obj, prefix, out) {
43796
43840
  }
43797
43841
  }
43798
43842
  }
43799
- function buildCssVariables(theme8) {
43843
+ function buildCssVariables(theme9) {
43800
43844
  const lines = [];
43801
- walkTokens(theme8.color, "color", lines);
43802
- walkTokens(theme8.font, "font", lines);
43803
- walkTokens(theme8.spacing, "spacing", lines);
43804
- walkTokens(theme8.shape, "shape", lines);
43845
+ walkTokens(theme9.color, "color", lines);
43846
+ walkTokens(theme9.font, "font", lines);
43847
+ walkTokens(theme9.spacing, "spacing", lines);
43848
+ walkTokens(theme9.shape, "shape", lines);
43805
43849
  walkTokens({
43806
- duration: theme8.motion.duration,
43807
- easing: theme8.motion.easing,
43808
- transition: theme8.motion.transition
43850
+ duration: theme9.motion.duration,
43851
+ easing: theme9.motion.easing,
43852
+ transition: theme9.motion.transition
43809
43853
  }, "motion", lines);
43810
- walkTokens(theme8.accessibility, "accessibility", lines);
43811
- walkTokens(theme8.zIndex, "zIndex", lines);
43854
+ walkTokens(theme9.accessibility, "accessibility", lines);
43855
+ walkTokens(theme9.zIndex, "zIndex", lines);
43812
43856
  return lines.join("\n");
43813
43857
  }
43814
43858
  function expandKeyframe(name, compact) {
@@ -43825,29 +43869,29 @@ function expandKeyframe(name, compact) {
43825
43869
  ${stops.join("\n")}
43826
43870
  }`;
43827
43871
  }
43828
- function buildCssKeyframes(theme8) {
43872
+ function buildCssKeyframes(theme9) {
43829
43873
  const blocks = [];
43830
- for (const [name, token] of Object.entries(theme8.motion.keyframes)) {
43874
+ for (const [name, token] of Object.entries(theme9.motion.keyframes)) {
43831
43875
  if (name.startsWith("$"))
43832
43876
  continue;
43833
43877
  blocks.push(expandKeyframe(name, String(token.$value)));
43834
43878
  }
43835
43879
  return blocks.join("\n\n");
43836
43880
  }
43837
- function parseTheme(id, theme8) {
43838
- const cssVariablesBody = buildCssVariables(theme8);
43881
+ function parseTheme(id, theme9) {
43882
+ const cssVariablesBody = buildCssVariables(theme9);
43839
43883
  const cssVariables = `:root {
43840
43884
  ${cssVariablesBody}
43841
43885
  }`;
43842
- const cssKeyframes = buildCssKeyframes(theme8);
43886
+ const cssKeyframes = buildCssKeyframes(theme9);
43843
43887
  const css = cssKeyframes ? `${cssVariables}
43844
43888
 
43845
43889
  ${cssKeyframes}` : cssVariables;
43846
43890
  return {
43847
43891
  id,
43848
- name: theme8.$name,
43849
- description: theme8.$description,
43850
- metadata: theme8.$metadata,
43892
+ name: theme9.$name,
43893
+ description: theme9.$description,
43894
+ metadata: theme9.$metadata,
43851
43895
  cssVariables,
43852
43896
  cssKeyframes,
43853
43897
  css
@@ -46570,6 +46614,351 @@ var theme7 = {
46570
46614
  light: indigoLight,
46571
46615
  dark: indigoDark
46572
46616
  };
46617
+ var shared8 = {
46618
+ font: {
46619
+ family: {
46620
+ sans: {
46621
+ $value: '"DM Sans", system-ui, -apple-system, sans-serif',
46622
+ $type: "fontFamily"
46623
+ },
46624
+ mono: {
46625
+ $value: '"JetBrains Mono", ui-monospace, monospace',
46626
+ $type: "fontFamily"
46627
+ }
46628
+ },
46629
+ size: {
46630
+ sm: { $value: "0.875rem", $type: "dimension" },
46631
+ base: { $value: "1rem", $type: "dimension" },
46632
+ lg: { $value: "1.125rem", $type: "dimension" },
46633
+ xl: { $value: "1.25rem", $type: "dimension" },
46634
+ "2xl": { $value: "1.5rem", $type: "dimension" }
46635
+ },
46636
+ weight: {
46637
+ normal: { $value: "400", $type: "fontWeight" },
46638
+ medium: { $value: "500", $type: "fontWeight" },
46639
+ semibold: { $value: "600", $type: "fontWeight" },
46640
+ bold: { $value: "700", $type: "fontWeight" }
46641
+ },
46642
+ lineHeight: {
46643
+ tight: { $value: "1.25", $type: "number" },
46644
+ normal: { $value: "1.5", $type: "number" },
46645
+ relaxed: { $value: "1.75", $type: "number" }
46646
+ }
46647
+ },
46648
+ spacing: {
46649
+ "1": { $value: "0.25rem", $type: "dimension" },
46650
+ "2": { $value: "0.5rem", $type: "dimension" },
46651
+ "3": { $value: "0.75rem", $type: "dimension" },
46652
+ "4": { $value: "1rem", $type: "dimension" },
46653
+ "5": { $value: "1.25rem", $type: "dimension" },
46654
+ "6": { $value: "1.5rem", $type: "dimension" },
46655
+ "8": { $value: "2rem", $type: "dimension" },
46656
+ "10": { $value: "2.5rem", $type: "dimension" },
46657
+ "12": { $value: "3rem", $type: "dimension" }
46658
+ },
46659
+ // NOTE: `shape` is per-mode (round 4) — radius is shared via
46660
+ // `sharedRadius` below, but shadows split: dark wants near-none ink
46661
+ // (a visible black blob under a card on a dark surface was the
46662
+ // round-3 "borders looking ugly" residual's shadow half), light
46663
+ // wants classic soft grey.
46664
+ motion: {
46665
+ duration: {
46666
+ fast: { $value: "120ms", $type: "duration" },
46667
+ normal: { $value: "200ms", $type: "duration" },
46668
+ slow: { $value: "400ms", $type: "duration" },
46669
+ ambient: { $value: "2000ms", $type: "duration" }
46670
+ },
46671
+ easing: {
46672
+ default: { $value: "cubic-bezier(0.4, 0, 0.2, 1)", $type: "cubicBezier" },
46673
+ bounce: {
46674
+ $value: "cubic-bezier(0.68, -0.55, 0.27, 1.55)",
46675
+ $type: "cubicBezier"
46676
+ },
46677
+ spring: { $value: "cubic-bezier(0.22, 1, 0.36, 1)", $type: "cubicBezier" }
46678
+ },
46679
+ transition: {
46680
+ fast: { $value: "120ms cubic-bezier(0.4, 0, 0.2, 1)", $type: "transition" },
46681
+ normal: { $value: "200ms cubic-bezier(0.4, 0, 0.2, 1)", $type: "transition" },
46682
+ slow: { $value: "400ms cubic-bezier(0.4, 0, 0.2, 1)", $type: "transition" },
46683
+ colors: {
46684
+ $value: "color 200ms cubic-bezier(0.4, 0, 0.2, 1), background-color 200ms cubic-bezier(0.4, 0, 0.2, 1), border-color 200ms cubic-bezier(0.4, 0, 0.2, 1)",
46685
+ $type: "transition"
46686
+ },
46687
+ opacity: { $value: "opacity 200ms cubic-bezier(0.4, 0, 0.2, 1)", $type: "transition" },
46688
+ transform: { $value: "transform 200ms cubic-bezier(0.22, 1, 0.36, 1)", $type: "transition" }
46689
+ },
46690
+ keyframes: {
46691
+ "fade-in": {
46692
+ $value: "0%{opacity:0}100%{opacity:1}",
46693
+ $type: "keyframes"
46694
+ },
46695
+ "slide-up": {
46696
+ $value: "0%{opacity:0;transform:translateY(8px)}100%{opacity:1;transform:translateY(0)}",
46697
+ $type: "keyframes"
46698
+ },
46699
+ "pulse-soft": {
46700
+ $value: "0%{opacity:1}50%{opacity:0.65}100%{opacity:1}",
46701
+ $type: "keyframes"
46702
+ }
46703
+ }
46704
+ },
46705
+ accessibility: {
46706
+ focusRing: {
46707
+ color: { $value: "#B8FF3A", $type: "color" },
46708
+ width: { $value: "2px", $type: "dimension" },
46709
+ offset: { $value: "2px", $type: "dimension" }
46710
+ },
46711
+ reducedMotion: {
46712
+ duration: { $value: "0ms", $type: "duration" }
46713
+ },
46714
+ highContrast: {
46715
+ borderWidth: { $value: "2px", $type: "dimension" },
46716
+ textColor: { $value: "#FFFFFF", $type: "color" },
46717
+ backgroundColor: { $value: "#000000", $type: "color" },
46718
+ linkColor: { $value: "#CCFF66", $type: "color" }
46719
+ }
46720
+ },
46721
+ zIndex: standardZIndex
46722
+ };
46723
+ var sharedRadius = {
46724
+ sm: { $value: "0.375rem", $type: "dimension" },
46725
+ md: { $value: "0.5rem", $type: "dimension" },
46726
+ lg: { $value: "0.75rem", $type: "dimension" },
46727
+ xl: { $value: "1rem", $type: "dimension" },
46728
+ full: { $value: "9999px", $type: "dimension" }
46729
+ };
46730
+ var darkShadows = {
46731
+ sm: { $value: "0 1px 2px rgba(0, 0, 0, 0.2)", $type: "shadow" },
46732
+ md: { $value: "0 2px 8px rgba(0, 0, 0, 0.25)", $type: "shadow" },
46733
+ lg: { $value: "0 6px 16px rgba(0, 0, 0, 0.28)", $type: "shadow" },
46734
+ xl: { $value: "0 10px 24px rgba(0, 0, 0, 0.3)", $type: "shadow" }
46735
+ };
46736
+ var lightShadows = {
46737
+ sm: { $value: "0 1px 2px rgba(26, 29, 36, 0.06)", $type: "shadow" },
46738
+ md: { $value: "0 2px 8px rgba(26, 29, 36, 0.08)", $type: "shadow" },
46739
+ lg: { $value: "0 6px 16px rgba(26, 29, 36, 0.1)", $type: "shadow" },
46740
+ xl: { $value: "0 12px 28px rgba(26, 29, 36, 0.12)", $type: "shadow" }
46741
+ };
46742
+ var guueyBrandDark = {
46743
+ $name: "guuey-brand-v1",
46744
+ $description: "The guuey product brand (dark) \u2014 slate-ink surfaces, slime #B8FF3A accent, DM Sans.",
46745
+ $metadata: {
46746
+ font: "DM Sans",
46747
+ fontUrl: "https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap",
46748
+ philosophy: "Agent-native. Slime on slate.",
46749
+ // Round 5 (founder-ruled): the guuey host clips the view with its
46750
+ // own rounded rim — the HOST owns the card silhouette; the theme
46751
+ // paints no border on the root layer. Inner hairlines stay.
46752
+ frameless: true
46753
+ },
46754
+ color: {
46755
+ // Inverted dark ladder — 50 darkest, 900 lightest; slime pinned at
46756
+ // 500, the portal's lifted #CCFF66 at the hover stop (600).
46757
+ primary: {
46758
+ "50": { $value: "#141D05", $type: "color" },
46759
+ "100": { $value: "#28390B", $type: "color" },
46760
+ "200": { $value: "#3F5A11", $type: "color" },
46761
+ "300": { $value: "#5F8719", $type: "color" },
46762
+ "400": { $value: "#8CC627", $type: "color" },
46763
+ "500": { $value: "#B8FF3A", $type: "color" },
46764
+ // slime (brand)
46765
+ "600": { $value: "#CCFF66", $type: "color" },
46766
+ // lifted hover (portal)
46767
+ "700": { $value: "#DBFF8F", $type: "color" },
46768
+ // pressed / emphasized
46769
+ "800": { $value: "#E9FFB8", $type: "color" },
46770
+ "900": { $value: "#F6FFE0", $type: "color" }
46771
+ },
46772
+ // Slate-ink foundation from the portal surface family: sunken →
46773
+ // surface → elevated → surfaceVariant, then up through the greys
46774
+ // to paper (#F6F5EE).
46775
+ neutral: {
46776
+ "50": { $value: "#0E1014", $type: "color" },
46777
+ // sunken
46778
+ "100": { $value: "#1A1D24", $type: "color" },
46779
+ // surface
46780
+ "200": { $value: "#232630", $type: "color" },
46781
+ // elevated
46782
+ "300": { $value: "#242938", $type: "color" },
46783
+ // surfaceVariant
46784
+ "400": { $value: "#3B4152", $type: "color" },
46785
+ "500": { $value: "#878C99", $type: "color" },
46786
+ // hint text
46787
+ "600": { $value: "#B7BAC4", $type: "color" },
46788
+ // secondary text
46789
+ "700": { $value: "#D5D6DC", $type: "color" },
46790
+ "800": { $value: "#E8E7E2", $type: "color" },
46791
+ "900": { $value: "#F6F5EE", $type: "color" }
46792
+ // paper (text)
46793
+ },
46794
+ // BRAND RULE: success IS slime — never green. Same family as
46795
+ // primary so an "Available" pill and a slime CTA read as one brand.
46796
+ success: {
46797
+ "50": { $value: "#141D05", $type: "color" },
46798
+ "100": { $value: "#28390B", $type: "color" },
46799
+ "200": { $value: "#3F5A11", $type: "color" },
46800
+ "500": { $value: "#B8FF3A", $type: "color" },
46801
+ // slime (brand rule)
46802
+ "600": { $value: "#CCFF66", $type: "color" },
46803
+ "700": { $value: "#DBFF8F", $type: "color" },
46804
+ "800": { $value: "#E9FFB8", $type: "color" }
46805
+ },
46806
+ warning: {
46807
+ "50": { $value: "#33240A", $type: "color" },
46808
+ "100": { $value: "#5C420F", $type: "color" },
46809
+ "200": { $value: "#8A6318", $type: "color" },
46810
+ "500": { $value: "#FFB020", $type: "color" },
46811
+ // portal warning
46812
+ "600": { $value: "#FFC24D", $type: "color" },
46813
+ "700": { $value: "#FFD37D", $type: "color" },
46814
+ "800": { $value: "#FFE5AE", $type: "color" }
46815
+ },
46816
+ error: {
46817
+ "50": { $value: "#33110E", $type: "color" },
46818
+ "100": { $value: "#5E1F1B", $type: "color" },
46819
+ "200": { $value: "#8F2F2A", $type: "color" },
46820
+ "500": { $value: "#FF5B5B", $type: "color" },
46821
+ // portal error
46822
+ "600": { $value: "#FF7D7A", $type: "color" },
46823
+ "700": { $value: "#FF9F9C", $type: "color" },
46824
+ "800": { $value: "#FFC3C0", $type: "color" }
46825
+ },
46826
+ info: {
46827
+ "50": { $value: "#0A2733", $type: "color" },
46828
+ "100": { $value: "#12455C", $type: "color" },
46829
+ "200": { $value: "#1E6A8A", $type: "color" },
46830
+ "500": { $value: "#3AC8FF", $type: "color" },
46831
+ // portal info
46832
+ "600": { $value: "#66D4FF", $type: "color" },
46833
+ "700": { $value: "#92E0FF", $type: "color" },
46834
+ "800": { $value: "#BFECFF", $type: "color" }
46835
+ },
46836
+ // M3 roles — portal values verbatim.
46837
+ surface: { $value: "#1A1D24", $type: "color" },
46838
+ onSurface: { $value: "#F6F5EE", $type: "color" },
46839
+ surfaceVariant: { $value: "#242938", $type: "color" },
46840
+ onSurfaceVariant: { $value: "#B7BAC4", $type: "color" },
46841
+ container: { $value: "#232630", $type: "color" },
46842
+ // elevated
46843
+ onContainer: { $value: "#F6F5EE", $type: "color" },
46844
+ // Round 4 (portal stops): .14 IS the base hairline; .18 is the
46845
+ // STRONG stop (no DtcgTheme slot — strong/interactive strokes
46846
+ // ride primary borders + the slime focusRing, receipted by the
46847
+ // Select button). Dividers sit softer still.
46848
+ outline: { $value: "rgba(246, 245, 238, 0.14)", $type: "color" },
46849
+ outlineVariant: { $value: "rgba(246, 245, 238, 0.1)", $type: "color" },
46850
+ onPrimary: { $value: "#0E1014", $type: "color" },
46851
+ // ink on slime
46852
+ primaryContainer: { $value: "#242938", $type: "color" },
46853
+ // portal
46854
+ onPrimaryContainer: { $value: "#CCFF66", $type: "color" },
46855
+ // portal
46856
+ onError: { $value: "#33110E", $type: "color" },
46857
+ errorContainer: { $value: "#5E1F1B", $type: "color" },
46858
+ onErrorContainer: { $value: "#FFC3C0", $type: "color" },
46859
+ // Pink accent — the portal's tertiary. (Purple #9B6AFF has no
46860
+ // DtcgTheme slot; see the file docstring.)
46861
+ tertiary: { $value: "#FF4FB0", $type: "color" },
46862
+ onTertiary: { $value: "#0E1014", $type: "color" },
46863
+ tertiaryContainer: { $value: "#451A35", $type: "color" },
46864
+ onTertiaryContainer: { $value: "#FFC1E4", $type: "color" }
46865
+ },
46866
+ ...shared8,
46867
+ shape: { radius: sharedRadius, shadow: darkShadows }
46868
+ };
46869
+ var guueyBrandLight = {
46870
+ $name: "guuey-brand-v1",
46871
+ $description: "The guuey product brand (light, provisional) \u2014 paper surfaces, slime accent held for fills, darkened slime for text emphasis.",
46872
+ $metadata: guueyBrandDark.$metadata,
46873
+ color: {
46874
+ // Normal (non-inverted) ramps; slime stays the 500 fill anchor,
46875
+ // text-emphasis stops (600/700) darken for contrast on paper.
46876
+ primary: {
46877
+ "50": { $value: "#F6FFE0", $type: "color" },
46878
+ "100": { $value: "#E9FFB8", $type: "color" },
46879
+ "200": { $value: "#DBFF8F", $type: "color" },
46880
+ "300": { $value: "#CCFF66", $type: "color" },
46881
+ "400": { $value: "#B8FF3A", $type: "color" },
46882
+ "500": { $value: "#9FE01C", $type: "color" },
46883
+ "600": { $value: "#7DB214", $type: "color" },
46884
+ "700": { $value: "#5C850D", $type: "color" },
46885
+ "800": { $value: "#3F5A11", $type: "color" },
46886
+ "900": { $value: "#28390B", $type: "color" }
46887
+ },
46888
+ neutral: {
46889
+ "50": { $value: "#FBFAF6", $type: "color" },
46890
+ "100": { $value: "#F6F5EE", $type: "color" },
46891
+ "200": { $value: "#E8E7E2", $type: "color" },
46892
+ "300": { $value: "#D5D6DC", $type: "color" },
46893
+ "400": { $value: "#B7BAC4", $type: "color" },
46894
+ "500": { $value: "#6E7380", $type: "color" },
46895
+ "600": { $value: "#4A4F5C", $type: "color" },
46896
+ "700": { $value: "#333846", $type: "color" },
46897
+ "800": { $value: "#242938", $type: "color" },
46898
+ "900": { $value: "#1A1D24", $type: "color" }
46899
+ },
46900
+ success: {
46901
+ "50": { $value: "#F6FFE0", $type: "color" },
46902
+ "100": { $value: "#E9FFB8", $type: "color" },
46903
+ "200": { $value: "#DBFF8F", $type: "color" },
46904
+ "500": { $value: "#7DB214", $type: "color" },
46905
+ "600": { $value: "#5C850D", $type: "color" },
46906
+ "700": { $value: "#476809", $type: "color" },
46907
+ "800": { $value: "#28390B", $type: "color" }
46908
+ },
46909
+ warning: {
46910
+ "50": { $value: "#FFF4DD", $type: "color" },
46911
+ "100": { $value: "#FFE5AE", $type: "color" },
46912
+ "200": { $value: "#FFD37D", $type: "color" },
46913
+ "500": { $value: "#D98A0A", $type: "color" },
46914
+ "600": { $value: "#A96A06", $type: "color" },
46915
+ "700": { $value: "#7C4D04", $type: "color" },
46916
+ "800": { $value: "#523203", $type: "color" }
46917
+ },
46918
+ error: {
46919
+ "50": { $value: "#FFE9E8", $type: "color" },
46920
+ "100": { $value: "#FFC3C0", $type: "color" },
46921
+ "200": { $value: "#FF9F9C", $type: "color" },
46922
+ "500": { $value: "#E23B3B", $type: "color" },
46923
+ "600": { $value: "#B62C2C", $type: "color" },
46924
+ "700": { $value: "#8A1F1F", $type: "color" },
46925
+ "800": { $value: "#5E1F1B", $type: "color" }
46926
+ },
46927
+ info: {
46928
+ "50": { $value: "#E5F7FF", $type: "color" },
46929
+ "100": { $value: "#BFECFF", $type: "color" },
46930
+ "200": { $value: "#92E0FF", $type: "color" },
46931
+ "500": { $value: "#0E93C9", $type: "color" },
46932
+ "600": { $value: "#0B739E", $type: "color" },
46933
+ "700": { $value: "#085572", $type: "color" },
46934
+ "800": { $value: "#12455C", $type: "color" }
46935
+ },
46936
+ surface: { $value: "#FFFFFF", $type: "color" },
46937
+ onSurface: { $value: "#1A1D24", $type: "color" },
46938
+ surfaceVariant: { $value: "#F6F5EE", $type: "color" },
46939
+ onSurfaceVariant: { $value: "#4A4F5C", $type: "color" },
46940
+ container: { $value: "#FBFAF6", $type: "color" },
46941
+ onContainer: { $value: "#1A1D24", $type: "color" },
46942
+ outline: { $value: "rgba(26, 29, 36, 0.18)", $type: "color" },
46943
+ outlineVariant: { $value: "rgba(26, 29, 36, 0.10)", $type: "color" },
46944
+ onPrimary: { $value: "#0E1014", $type: "color" },
46945
+ primaryContainer: { $value: "#E9FFB8", $type: "color" },
46946
+ onPrimaryContainer: { $value: "#28390B", $type: "color" },
46947
+ onError: { $value: "#FFFFFF", $type: "color" },
46948
+ errorContainer: { $value: "#FFE9E8", $type: "color" },
46949
+ onErrorContainer: { $value: "#8A1F1F", $type: "color" },
46950
+ tertiary: { $value: "#D6247F", $type: "color" },
46951
+ onTertiary: { $value: "#FFFFFF", $type: "color" },
46952
+ tertiaryContainer: { $value: "#FFDCEE", $type: "color" },
46953
+ onTertiaryContainer: { $value: "#6B1240", $type: "color" }
46954
+ },
46955
+ ...shared8,
46956
+ shape: { radius: sharedRadius, shadow: lightShadows }
46957
+ };
46958
+ var theme8 = {
46959
+ light: guueyBrandLight,
46960
+ dark: guueyBrandDark
46961
+ };
46573
46962
  var themes = /* @__PURE__ */ new Map([
46574
46963
  ["ggui", theme],
46575
46964
  ["indigo", theme7],
@@ -46577,7 +46966,11 @@ var themes = /* @__PURE__ */ new Map([
46577
46966
  ["premium-cyberpunk", theme2],
46578
46967
  ["premium-zen", theme3],
46579
46968
  ["premium-neon-noir", theme4],
46580
- ["premium-botanical", theme5]
46969
+ ["premium-botanical", theme5],
46970
+ // Registered under the EXACT AppTheme.name the guuey widget stamps,
46971
+ // so the runtime's theme-name→registry binding (ggui#589 ask 3)
46972
+ // selects it as the base ladder with no sender-side change.
46973
+ ["guuey-brand-v1", theme8]
46581
46974
  ]);
46582
46975
  var parsedCache = /* @__PURE__ */ new Map();
46583
46976
  function resolveMode(reg, requested) {
@@ -46679,27 +47072,29 @@ function getScopedCssTokens(scopeClass, mode = "light") {
46679
47072
  return getScopedThemeCss(getDefaultThemeId(), scopeClass, mode);
46680
47073
  }
46681
47074
  function getScopedThemeCss(themeId, scopeClass, mode = "light") {
46682
- const theme8 = getTheme(themeId, mode);
46683
- if (!theme8) {
47075
+ const theme9 = getTheme(themeId, mode);
47076
+ if (!theme9) {
46684
47077
  const defaultId = getDefaultThemeId();
46685
47078
  if (themeId === defaultId)
46686
47079
  return "";
46687
47080
  return getScopedThemeCss(defaultId, scopeClass, mode);
46688
47081
  }
46689
- const primary500 = resolvePrimary500Hex(theme8.cssVariables);
46690
- const scoped = withColorMixFallback(theme8.cssVariables.replace(/^:root\s*\{/, `.${scopeClass} {`), `.${scopeClass}`, primary500);
47082
+ const primary500 = resolvePrimary500Hex(theme9.cssVariables);
47083
+ const scoped = withColorMixFallback(theme9.cssVariables.replace(/^:root\s*\{/, `.${scopeClass} {`), `.${scopeClass}`, primary500);
46691
47084
  const baseInherits = `.${scopeClass} {
46692
47085
  font-family: var(--ggui-font-family-sans);
46693
47086
  color: var(--ggui-color-onSurface);
46694
47087
  background-color: transparent;
46695
47088
  }`;
46696
47089
  const gradientTokens = buildGradientTokens(scopeClass, primary500);
47090
+ const framelessRule = theme9.metadata?.frameless === true ? `
47091
+ .${scopeClass} > :where(:not(style)) { border: none !important; }` : "";
46697
47092
  return `${scoped}
46698
47093
  ${baseInherits}
46699
47094
  ${gradientTokens}
46700
- ${theme8.cssKeyframes}
47095
+ ${theme9.cssKeyframes}
46701
47096
  .${scopeClass} *, .${scopeClass} *::before, .${scopeClass} *::after { box-sizing: border-box; }
46702
- .${scopeClass} h1, .${scopeClass} h2, .${scopeClass} h3, .${scopeClass} h4, .${scopeClass} h5, .${scopeClass} h6, .${scopeClass} button, .${scopeClass} input, .${scopeClass} textarea, .${scopeClass} select { font-family: inherit; }`;
47097
+ .${scopeClass} h1, .${scopeClass} h2, .${scopeClass} h3, .${scopeClass} h4, .${scopeClass} h5, .${scopeClass} h6, .${scopeClass} button, .${scopeClass} input, .${scopeClass} textarea, .${scopeClass} select { font-family: inherit; }${framelessRule}`;
46703
47098
  }
46704
47099
  function buildGradientTokens(scopeClass, primary500Hex) {
46705
47100
  const selector = `.${scopeClass}`;
@@ -46927,19 +47322,26 @@ function replaceSpecifier(code, specifier, replacement) {
46927
47322
  function globalExpr(gguiKey, legacyName) {
46928
47323
  return `(globalThis.__ggui__&&globalThis.__ggui__["${gguiKey}"]||window["${legacyName}"])`;
46929
47324
  }
46930
- function buildDataUrlReactShim(globalName) {
47325
+ function toDataUrl(js) {
47326
+ return `data:text/javascript,${encodeURIComponent(js)}`;
47327
+ }
47328
+ function jsReactShim(globalName) {
46931
47329
  const namedExports = REACT_EXPORTS.map((e) => `export const ${e} = R.${e};`).join(" ");
46932
47330
  const resolve = globalExpr("react", globalName);
46933
- const js = `const R = ${resolve}; export default R; ${namedExports}`;
46934
- return `data:text/javascript,${encodeURIComponent(js)}`;
47331
+ return `const R = ${resolve}; export default R; ${namedExports}`;
46935
47332
  }
46936
- function buildDataUrlReactDomShim() {
47333
+ function buildDataUrlReactShim(globalName) {
47334
+ return toDataUrl(jsReactShim(globalName));
47335
+ }
47336
+ function jsReactDomShim() {
46937
47337
  const REACT_DOM_EXPORTS = ["createPortal", "flushSync", "unstable_batchedUpdates"];
46938
47338
  const namedExports = REACT_DOM_EXPORTS.map((e) => `export const ${e} = D.${e};`).join(" ");
46939
- const js = `const D = globalThis.__ggui__["reactDom"]; export default D; ${namedExports}`;
46940
- return `data:text/javascript,${encodeURIComponent(js)}`;
47339
+ return `const D = globalThis.__ggui__["reactDom"]; export default D; ${namedExports}`;
46941
47340
  }
46942
- function buildDataUrlJsxShim(globalName) {
47341
+ function buildDataUrlReactDomShim() {
47342
+ return toDataUrl(jsReactDomShim());
47343
+ }
47344
+ function jsJsxShim(globalName) {
46943
47345
  const resolve = globalExpr("react", globalName);
46944
47346
  const js = [
46945
47347
  `const R = ${resolve};`,
@@ -46952,9 +47354,12 @@ function buildDataUrlJsxShim(globalName) {
46952
47354
  `export{jsx,jsx as jsxs,jsx as jsxDEV};`,
46953
47355
  `export const Fragment=R.Fragment;`
46954
47356
  ].join("");
46955
- return `data:text/javascript,${encodeURIComponent(js)}`;
47357
+ return js;
46956
47358
  }
46957
- function buildDataUrlGlobalShim(globalName, gguiKey, exportNames, fallbackGlobals, fallbackGguiKeys) {
47359
+ function buildDataUrlJsxShim(globalName) {
47360
+ return toDataUrl(jsJsxShim(globalName));
47361
+ }
47362
+ function jsGlobalShim(globalName, gguiKey, exportNames, fallbackGlobals, fallbackGguiKeys) {
46958
47363
  if (exportNames && exportNames.length > 0) {
46959
47364
  const globals = [globalName, ...fallbackGlobals || []];
46960
47365
  const gguiKeys = [gguiKey, ...fallbackGguiKeys || []];
@@ -46965,17 +47370,20 @@ function buildDataUrlGlobalShim(globalName, gguiKey, exportNames, fallbackGlobal
46965
47370
  ));
46966
47371
  const mergeExpr = resolveExprs.join(",");
46967
47372
  const named = exportNames.map((n) => `export const ${n} = M["${n}"];`).join(" ");
46968
- const js2 = resolveExprs.length > 1 ? `const M = Object.assign({}, ${mergeExpr}); ${named} export default M;` : `const M = ${resolveExprs[0]}; ${named} export default M;`;
46969
- return `data:text/javascript,${encodeURIComponent(js2)}`;
47373
+ return resolveExprs.length > 1 ? `const M = Object.assign({}, ${mergeExpr}); ${named} export default M;` : `const M = ${resolveExprs[0]}; ${named} export default M;`;
46970
47374
  }
46971
47375
  const resolve = globalExpr(gguiKey, globalName);
46972
- const js = `const M = ${resolve} || {}; const handler = { get(_, key) { return M[key]; } }; export default new Proxy({}, handler);`;
46973
- return `data:text/javascript,${encodeURIComponent(js)}`;
47376
+ return `const M = ${resolve} || {}; const handler = { get(_, key) { return M[key]; } }; export default new Proxy({}, handler);`;
46974
47377
  }
46975
- function buildDataUrlWireShim() {
47378
+ function buildDataUrlGlobalShim(globalName, gguiKey, exportNames, fallbackGlobals, fallbackGguiKeys) {
47379
+ return toDataUrl(jsGlobalShim(globalName, gguiKey, exportNames, fallbackGlobals, fallbackGguiKeys));
47380
+ }
47381
+ function jsWireShim() {
46976
47382
  const named = WIRE_EXPORTS.map((e) => `export const ${e} = w.${e};`).join(" ");
46977
- const js = `const w = globalThis.__ggui__.wire; ${named} export default w;`;
46978
- return `data:text/javascript,${encodeURIComponent(js)}`;
47383
+ return `const w = globalThis.__ggui__.wire; ${named} export default w;`;
47384
+ }
47385
+ function buildDataUrlWireShim() {
47386
+ return toDataUrl(jsWireShim());
46979
47387
  }
46980
47388
  function extractNamedImports(code, specifier) {
46981
47389
  const esc2 = specifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -46992,7 +47400,7 @@ function extractNamedImports(code, specifier) {
46992
47400
  }
46993
47401
  return [...names];
46994
47402
  }
46995
- function buildGadgetPackageShim(packageName, exportNames) {
47403
+ function jsGadgetPackageShim(packageName, exportNames) {
46996
47404
  const pkgLit = JSON.stringify(packageName);
46997
47405
  const hasComponent = exportNames.some((n) => /^[A-Z]/.test(n));
46998
47406
  const parts = [];
@@ -47009,7 +47417,10 @@ function buildGadgetPackageShim(packageName, exportNames) {
47009
47417
  parts.push(`export const ${name}=${factory}(${JSON.stringify(name)});`);
47010
47418
  }
47011
47419
  parts.push(`export default new Proxy({},{get:function(_,k){return NS()[k];}});`);
47012
- return `data:text/javascript,${encodeURIComponent(parts.join(""))}`;
47420
+ return parts.join("");
47421
+ }
47422
+ function buildGadgetPackageShim(packageName, exportNames) {
47423
+ return toDataUrl(jsGadgetPackageShim(packageName, exportNames));
47013
47424
  }
47014
47425
  function rewriteDataUrl(code, opts) {
47015
47426
  const reactGlobal = opts.reactGlobal ?? "__REACT";
@@ -47044,6 +47455,29 @@ function rewriteDataUrl(code, opts) {
47044
47455
  }
47045
47456
  return code;
47046
47457
  }
47458
+ var ASSET_SHIM_FOR_SPECIFIER = {
47459
+ "react/jsx-runtime": "jsx-runtime",
47460
+ "react/jsx-dev-runtime": "jsx-runtime",
47461
+ "react-dom": "react-dom",
47462
+ react: "react",
47463
+ "@ggui-ai/design/primitives": "primitives",
47464
+ "@ggui-ai/design/components": "components",
47465
+ "@ggui-ai/design/compositions": "compositions",
47466
+ "@ggui-ai/design/interact": "interact",
47467
+ "@ggui-ai/design/templates": "templates",
47468
+ "@ggui-ai/design/app-components": "app-components",
47469
+ "@ggui-ai/design/tokens": "tokens",
47470
+ "@ggui-ai/design": "design",
47471
+ "@ggui-ai/wire": "wire",
47472
+ "@ggui-ai/gadgets": "gadgets"
47473
+ };
47474
+ function rewriteAssetUrl(code, opts) {
47475
+ const base = opts.shimBaseUrl.replace(/\/$/, "");
47476
+ for (const [specifier, shimName] of Object.entries(ASSET_SHIM_FOR_SPECIFIER)) {
47477
+ code = replaceSpecifier(code, specifier, `${base}/${shimName}.js`);
47478
+ }
47479
+ return code;
47480
+ }
47047
47481
  function rewriteImportmap(code, opts) {
47048
47482
  const base = opts.reactBaseUrl ?? "https://esm.sh/react@18.2.0";
47049
47483
  code = replaceSpecifier(code, "react/jsx-runtime", `${base}/jsx-runtime`);
@@ -47057,6 +47491,8 @@ function rewriteImports(code, options) {
47057
47491
  return rewriteDataUrl(code, options);
47058
47492
  case "importmap":
47059
47493
  return rewriteImportmap(code, options);
47494
+ case "asset-url":
47495
+ return rewriteAssetUrl(code, options);
47060
47496
  }
47061
47497
  }
47062
47498
  function hoistImports(code) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ggui-ai/dev-stack",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "Shared local dev engine for the ggui protocol: local UI registry discovery, compile-on-demand, filesystem watcher with SSE, and a read-only HTTP surface for dev tooling. Framework-neutral — agent runtime supervision plugs in via an adapter seam, so no agent SDK is hardcoded.",
5
5
  "keywords": [
6
6
  "ggui",
@@ -28,9 +28,9 @@
28
28
  "dependencies": {
29
29
  "chokidar": "^4.0.3",
30
30
  "esbuild": "^0.25.12",
31
- "@ggui-ai/project-config": "0.9.0",
32
- "@ggui-ai/agent-runtime": "0.9.0",
33
- "@ggui-ai/ui-registry": "0.9.0"
31
+ "@ggui-ai/agent-runtime": "0.11.0",
32
+ "@ggui-ai/ui-registry": "0.11.0",
33
+ "@ggui-ai/project-config": "0.11.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^24.0.0",
@@ -40,9 +40,9 @@
40
40
  "react-dom": "^19.0.0",
41
41
  "typescript": "^5.0.0",
42
42
  "vitest": "^3.2.6",
43
- "@ggui-ai/design": "0.9.0",
44
- "@ggui-ai/mcp-apps-react": "0.9.0",
45
- "@ggui-ai/wire": "0.9.0"
43
+ "@ggui-ai/design": "0.11.0",
44
+ "@ggui-ai/mcp-apps-react": "0.11.0",
45
+ "@ggui-ai/wire": "0.11.0"
46
46
  },
47
47
  "repository": {
48
48
  "type": "git",