@ggui-ai/dev-stack 0.9.0 → 0.10.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.10.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":
@@ -46927,19 +46971,26 @@ function replaceSpecifier(code, specifier, replacement) {
46927
46971
  function globalExpr(gguiKey, legacyName) {
46928
46972
  return `(globalThis.__ggui__&&globalThis.__ggui__["${gguiKey}"]||window["${legacyName}"])`;
46929
46973
  }
46930
- function buildDataUrlReactShim(globalName) {
46974
+ function toDataUrl(js) {
46975
+ return `data:text/javascript,${encodeURIComponent(js)}`;
46976
+ }
46977
+ function jsReactShim(globalName) {
46931
46978
  const namedExports = REACT_EXPORTS.map((e) => `export const ${e} = R.${e};`).join(" ");
46932
46979
  const resolve = globalExpr("react", globalName);
46933
- const js = `const R = ${resolve}; export default R; ${namedExports}`;
46934
- return `data:text/javascript,${encodeURIComponent(js)}`;
46980
+ return `const R = ${resolve}; export default R; ${namedExports}`;
46935
46981
  }
46936
- function buildDataUrlReactDomShim() {
46982
+ function buildDataUrlReactShim(globalName) {
46983
+ return toDataUrl(jsReactShim(globalName));
46984
+ }
46985
+ function jsReactDomShim() {
46937
46986
  const REACT_DOM_EXPORTS = ["createPortal", "flushSync", "unstable_batchedUpdates"];
46938
46987
  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)}`;
46988
+ return `const D = globalThis.__ggui__["reactDom"]; export default D; ${namedExports}`;
46941
46989
  }
46942
- function buildDataUrlJsxShim(globalName) {
46990
+ function buildDataUrlReactDomShim() {
46991
+ return toDataUrl(jsReactDomShim());
46992
+ }
46993
+ function jsJsxShim(globalName) {
46943
46994
  const resolve = globalExpr("react", globalName);
46944
46995
  const js = [
46945
46996
  `const R = ${resolve};`,
@@ -46952,9 +47003,12 @@ function buildDataUrlJsxShim(globalName) {
46952
47003
  `export{jsx,jsx as jsxs,jsx as jsxDEV};`,
46953
47004
  `export const Fragment=R.Fragment;`
46954
47005
  ].join("");
46955
- return `data:text/javascript,${encodeURIComponent(js)}`;
47006
+ return js;
46956
47007
  }
46957
- function buildDataUrlGlobalShim(globalName, gguiKey, exportNames, fallbackGlobals, fallbackGguiKeys) {
47008
+ function buildDataUrlJsxShim(globalName) {
47009
+ return toDataUrl(jsJsxShim(globalName));
47010
+ }
47011
+ function jsGlobalShim(globalName, gguiKey, exportNames, fallbackGlobals, fallbackGguiKeys) {
46958
47012
  if (exportNames && exportNames.length > 0) {
46959
47013
  const globals = [globalName, ...fallbackGlobals || []];
46960
47014
  const gguiKeys = [gguiKey, ...fallbackGguiKeys || []];
@@ -46965,17 +47019,20 @@ function buildDataUrlGlobalShim(globalName, gguiKey, exportNames, fallbackGlobal
46965
47019
  ));
46966
47020
  const mergeExpr = resolveExprs.join(",");
46967
47021
  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)}`;
47022
+ return resolveExprs.length > 1 ? `const M = Object.assign({}, ${mergeExpr}); ${named} export default M;` : `const M = ${resolveExprs[0]}; ${named} export default M;`;
46970
47023
  }
46971
47024
  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)}`;
47025
+ return `const M = ${resolve} || {}; const handler = { get(_, key) { return M[key]; } }; export default new Proxy({}, handler);`;
46974
47026
  }
46975
- function buildDataUrlWireShim() {
47027
+ function buildDataUrlGlobalShim(globalName, gguiKey, exportNames, fallbackGlobals, fallbackGguiKeys) {
47028
+ return toDataUrl(jsGlobalShim(globalName, gguiKey, exportNames, fallbackGlobals, fallbackGguiKeys));
47029
+ }
47030
+ function jsWireShim() {
46976
47031
  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)}`;
47032
+ return `const w = globalThis.__ggui__.wire; ${named} export default w;`;
47033
+ }
47034
+ function buildDataUrlWireShim() {
47035
+ return toDataUrl(jsWireShim());
46979
47036
  }
46980
47037
  function extractNamedImports(code, specifier) {
46981
47038
  const esc2 = specifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -46992,7 +47049,7 @@ function extractNamedImports(code, specifier) {
46992
47049
  }
46993
47050
  return [...names];
46994
47051
  }
46995
- function buildGadgetPackageShim(packageName, exportNames) {
47052
+ function jsGadgetPackageShim(packageName, exportNames) {
46996
47053
  const pkgLit = JSON.stringify(packageName);
46997
47054
  const hasComponent = exportNames.some((n) => /^[A-Z]/.test(n));
46998
47055
  const parts = [];
@@ -47009,7 +47066,10 @@ function buildGadgetPackageShim(packageName, exportNames) {
47009
47066
  parts.push(`export const ${name}=${factory}(${JSON.stringify(name)});`);
47010
47067
  }
47011
47068
  parts.push(`export default new Proxy({},{get:function(_,k){return NS()[k];}});`);
47012
- return `data:text/javascript,${encodeURIComponent(parts.join(""))}`;
47069
+ return parts.join("");
47070
+ }
47071
+ function buildGadgetPackageShim(packageName, exportNames) {
47072
+ return toDataUrl(jsGadgetPackageShim(packageName, exportNames));
47013
47073
  }
47014
47074
  function rewriteDataUrl(code, opts) {
47015
47075
  const reactGlobal = opts.reactGlobal ?? "__REACT";
@@ -47044,6 +47104,29 @@ function rewriteDataUrl(code, opts) {
47044
47104
  }
47045
47105
  return code;
47046
47106
  }
47107
+ var ASSET_SHIM_FOR_SPECIFIER = {
47108
+ "react/jsx-runtime": "jsx-runtime",
47109
+ "react/jsx-dev-runtime": "jsx-runtime",
47110
+ "react-dom": "react-dom",
47111
+ react: "react",
47112
+ "@ggui-ai/design/primitives": "primitives",
47113
+ "@ggui-ai/design/components": "components",
47114
+ "@ggui-ai/design/compositions": "compositions",
47115
+ "@ggui-ai/design/interact": "interact",
47116
+ "@ggui-ai/design/templates": "templates",
47117
+ "@ggui-ai/design/app-components": "app-components",
47118
+ "@ggui-ai/design/tokens": "tokens",
47119
+ "@ggui-ai/design": "design",
47120
+ "@ggui-ai/wire": "wire",
47121
+ "@ggui-ai/gadgets": "gadgets"
47122
+ };
47123
+ function rewriteAssetUrl(code, opts) {
47124
+ const base = opts.shimBaseUrl.replace(/\/$/, "");
47125
+ for (const [specifier, shimName] of Object.entries(ASSET_SHIM_FOR_SPECIFIER)) {
47126
+ code = replaceSpecifier(code, specifier, `${base}/${shimName}.js`);
47127
+ }
47128
+ return code;
47129
+ }
47047
47130
  function rewriteImportmap(code, opts) {
47048
47131
  const base = opts.reactBaseUrl ?? "https://esm.sh/react@18.2.0";
47049
47132
  code = replaceSpecifier(code, "react/jsx-runtime", `${base}/jsx-runtime`);
@@ -47057,6 +47140,8 @@ function rewriteImports(code, options) {
47057
47140
  return rewriteDataUrl(code, options);
47058
47141
  case "importmap":
47059
47142
  return rewriteImportmap(code, options);
47143
+ case "asset-url":
47144
+ return rewriteAssetUrl(code, options);
47060
47145
  }
47061
47146
  }
47062
47147
  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.10.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/project-config": "0.10.0",
32
+ "@ggui-ai/agent-runtime": "0.10.0",
33
+ "@ggui-ai/ui-registry": "0.10.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/mcp-apps-react": "0.10.0",
44
+ "@ggui-ai/design": "0.10.0",
45
+ "@ggui-ai/wire": "0.10.0"
46
46
  },
47
47
  "repository": {
48
48
  "type": "git",