@ggui-ai/ui-visual-tester 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.
- package/fixture/fixture-runtime.js +207 -122
- package/package.json +4 -4
|
@@ -19836,7 +19836,7 @@
|
|
|
19836
19836
|
case "warning":
|
|
19837
19837
|
case "error":
|
|
19838
19838
|
case "info":
|
|
19839
|
-
return `var(--ggui-color-${tone}, ${SEMANTIC_TONE_FALLBACK[tone]})`;
|
|
19839
|
+
return `var(--ggui-color-${tone}-500, ${SEMANTIC_TONE_FALLBACK[tone]})`;
|
|
19840
19840
|
case "inverse":
|
|
19841
19841
|
return "var(--ggui-color-surface, #ffffff)";
|
|
19842
19842
|
case "inherit":
|
|
@@ -27817,7 +27817,7 @@
|
|
|
27817
27817
|
}
|
|
27818
27818
|
|
|
27819
27819
|
// ../protocol/dist/version.js
|
|
27820
|
-
var PROTOCOL_VERSION = "draft-2026-
|
|
27820
|
+
var PROTOCOL_VERSION = "draft-2026-08-19";
|
|
27821
27821
|
var PROTOCOL_SCHEMA_VERSION = PROTOCOL_VERSION;
|
|
27822
27822
|
var CLIENT_SUPPORTED_VERSIONS = Object.freeze([
|
|
27823
27823
|
PROTOCOL_SCHEMA_VERSION
|
|
@@ -42344,7 +42344,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
42344
42344
|
|
|
42345
42345
|
// ../protocol/dist/gadgets/stdlib-gadgets.js
|
|
42346
42346
|
var STDLIB_GADGETS_PACKAGE = "@ggui-ai/gadgets";
|
|
42347
|
-
var STDLIB_GADGETS_VERSION = "0.
|
|
42347
|
+
var STDLIB_GADGETS_VERSION = "0.10.0";
|
|
42348
42348
|
var STDLIB_GADGETS = [
|
|
42349
42349
|
{
|
|
42350
42350
|
package: STDLIB_GADGETS_PACKAGE,
|
|
@@ -42495,15 +42495,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
42495
42495
|
// surface as `undefined` at runtime which JSON.stringify drops.
|
|
42496
42496
|
external_exports.record(external_exports.string(), jsonValueSchema)
|
|
42497
42497
|
]));
|
|
42498
|
+
var jsonSchemaTypeNameSchema = external_exports.enum([
|
|
42499
|
+
"string",
|
|
42500
|
+
"number",
|
|
42501
|
+
"integer",
|
|
42502
|
+
"boolean",
|
|
42503
|
+
"array",
|
|
42504
|
+
"object",
|
|
42505
|
+
"null"
|
|
42506
|
+
]);
|
|
42498
42507
|
var jsonSchemaSchema = external_exports.lazy(() => external_exports.object({
|
|
42499
|
-
type
|
|
42500
|
-
|
|
42501
|
-
|
|
42502
|
-
|
|
42503
|
-
|
|
42504
|
-
|
|
42505
|
-
|
|
42506
|
-
|
|
42508
|
+
// Single type OR a draft-07 type array (`['string','null']` —
|
|
42509
|
+
// the canonical nullability form the enforced-props-schema
|
|
42510
|
+
// emission produces). Mirrors `JsonSchemaTypeName | JsonSchemaTypeName[]`
|
|
42511
|
+
// on the TS type — the zod and TS sides are an SSoT pair; widen
|
|
42512
|
+
// both or neither.
|
|
42513
|
+
type: external_exports.union([
|
|
42514
|
+
jsonSchemaTypeNameSchema,
|
|
42515
|
+
external_exports.array(jsonSchemaTypeNameSchema)
|
|
42507
42516
|
]).optional(),
|
|
42508
42517
|
description: external_exports.string().optional(),
|
|
42509
42518
|
enum: external_exports.array(jsonValueSchema).optional(),
|
|
@@ -42671,12 +42680,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
42671
42680
|
}).strict();
|
|
42672
42681
|
var appPublicEnvSchema = external_exports.record(external_exports.string().regex(PUBLIC_ENV_APP_KEY_RE), external_exports.string()).readonly();
|
|
42673
42682
|
var dataContractSchema = external_exports.object({
|
|
42674
|
-
propsSpec: propsSpecSchema.optional(),
|
|
42675
|
-
actionSpec: actionSpecSchema.optional(),
|
|
42676
|
-
streamSpec: streamSpecSchema.optional(),
|
|
42677
|
-
contextSpec: contextSpecSchema.optional(),
|
|
42678
|
-
agentCapabilities: agentCapabilitiesSpecSchema.optional(),
|
|
42679
|
-
clientCapabilities: clientCapabilitiesSpecSchema.optional()
|
|
42683
|
+
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)."),
|
|
42684
|
+
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."),
|
|
42685
|
+
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."),
|
|
42686
|
+
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."),
|
|
42687
|
+
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."),
|
|
42688
|
+
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.")
|
|
42680
42689
|
}).passthrough();
|
|
42681
42690
|
|
|
42682
42691
|
// ../protocol/dist/schemas/blueprint.js
|
|
@@ -42692,11 +42701,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
42692
42701
|
userBlueprintSourceSchema,
|
|
42693
42702
|
curatedBlueprintSourceSchema
|
|
42694
42703
|
]);
|
|
42704
|
+
var BLUEPRINT_VARIANCE_KEYS = ["persona", "aesthetic", "context", "seedPrompt"];
|
|
42695
42705
|
var blueprintVarianceSchema = external_exports.object({
|
|
42696
42706
|
persona: external_exports.string().optional().describe('Design persona, e.g. "minimalist" / "data-dense". Part of cache identity.'),
|
|
42697
42707
|
aesthetic: external_exports.string().optional().describe('Visual aesthetic, e.g. "calm" / "ornate". Part of cache identity.'),
|
|
42698
42708
|
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.'),
|
|
42699
42709
|
seedPrompt: external_exports.string().optional().describe("Generation seed directive. Part of cache identity.")
|
|
42710
|
+
}, {
|
|
42711
|
+
// A rejection that teaches (ggui#523 item 2): the first live guest
|
|
42712
|
+
// turn sent `mood` and got a bare "Unrecognized key" — name the
|
|
42713
|
+
// legal set and where the misplaced intent belongs.
|
|
42714
|
+
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
|
|
42700
42715
|
}).strict();
|
|
42701
42716
|
var blueprintSchema = external_exports.object({
|
|
42702
42717
|
blueprintId: external_exports.string().min(1),
|
|
@@ -42757,15 +42772,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
42757
42772
|
}).strict()
|
|
42758
42773
|
]);
|
|
42759
42774
|
var jsonPatchSchema = external_exports.array(jsonPatchOpSchema);
|
|
42775
|
+
var BLUEPRINT_DRAFT_KEYS = ["contract", "variance", "generator"];
|
|
42760
42776
|
var blueprintDraftObjectSchema = external_exports.object({
|
|
42761
42777
|
contract: dataContractSchema,
|
|
42762
|
-
variance:
|
|
42763
|
-
|
|
42764
|
-
|
|
42765
|
-
|
|
42766
|
-
|
|
42767
|
-
}).strict().optional(),
|
|
42778
|
+
// ONE declaration of the variance shape, protocol-wide: the same
|
|
42779
|
+
// schema (with its `.describe()` teaching and its legal-set
|
|
42780
|
+
// rejection message) that `blueprintMeta.variance` projects on the
|
|
42781
|
+
// way back out (ggui#523 item 1 — the mirror-of-a-mirror is gone).
|
|
42782
|
+
variance: blueprintVarianceSchema.optional(),
|
|
42768
42783
|
generator: external_exports.string().optional()
|
|
42784
|
+
}, {
|
|
42785
|
+
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
|
|
42769
42786
|
}).strict();
|
|
42770
42787
|
var blueprintDraftSchema = blueprintDraftObjectSchema;
|
|
42771
42788
|
var blueprintMetaSchema = external_exports.object({
|
|
@@ -42827,6 +42844,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
42827
42844
|
sessionId: external_exports.string().min(1).describe("GguiSession opaque id (UUID) \u2014 returned by ggui_render.")
|
|
42828
42845
|
};
|
|
42829
42846
|
var getSessionInputSchema = external_exports.object(getSessionInputShape);
|
|
42847
|
+
var getRenderSourceInputShape = {
|
|
42848
|
+
sessionId: external_exports.string().min(1).describe("GguiSession opaque id (UUID) \u2014 returned by ggui_render.")
|
|
42849
|
+
};
|
|
42850
|
+
var getRenderSourceInputSchema = external_exports.object(getRenderSourceInputShape);
|
|
42830
42851
|
var listFeaturedBlueprintsInputShape = {};
|
|
42831
42852
|
var listFeaturedBlueprintsInputSchema = external_exports.object(listFeaturedBlueprintsInputShape);
|
|
42832
42853
|
var searchBlueprintsInputShape = {
|
|
@@ -42861,7 +42882,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
42861
42882
|
* and the contract validators; variance feeds the variance axis
|
|
42862
42883
|
* and rides through to the suggestion's `blueprintMeta`.
|
|
42863
42884
|
*/
|
|
42864
|
-
blueprintDraft: blueprintDraftSchema.describe(
|
|
42885
|
+
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).`),
|
|
42865
42886
|
/**
|
|
42866
42887
|
* Skip blueprint-search on step-2 and route straight to validation
|
|
42867
42888
|
* + (if validation passes) agent-mode suggestion against the draft.
|
|
@@ -43267,87 +43288,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
43267
43288
|
// ../protocol/dist/registry/canonicalize-contract.js
|
|
43268
43289
|
var import_canonicalize = __toESM(require_canonicalize(), 1);
|
|
43269
43290
|
|
|
43291
|
+
// ../protocol/dist/validation/enforced-props-schema.js
|
|
43292
|
+
var import_canonicalize2 = __toESM(require_canonicalize(), 1);
|
|
43293
|
+
|
|
43270
43294
|
// ../protocol/dist/types/data-contract.js
|
|
43271
43295
|
var CONTEXT_SLOT_VALUE_MAX_BYTES = 16 * 1024;
|
|
43272
43296
|
var CONTEXT_SNAPSHOT_MAX_BYTES = 64 * 1024;
|
|
43273
43297
|
|
|
43274
|
-
// ../protocol/dist/schemas/ops-blueprint.js
|
|
43275
|
-
var opsGenerateBlueprintInputSchema = external_exports.object({
|
|
43276
|
-
contract: dataContractSchema,
|
|
43277
|
-
generator: external_exports.string().min(1).optional().describe("Generator slug (e.g. `ui-gen-default-haiku-4-5`). When omitted, dispatches through `GeneratorRegistry.defaultGenerator()`."),
|
|
43278
|
-
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."),
|
|
43279
|
-
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."),
|
|
43280
|
-
context: external_exports.record(external_exports.string(), jsonValueSchema).optional().describe("Small structured signal carried alongside the persona. Persisted on `Blueprint.variance.context`."),
|
|
43281
|
-
seedPrompt: external_exports.string().optional().describe("The raw operator prompt that produced this variant. Round-trip input for the variant-selector + audit trail."),
|
|
43282
|
-
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.")
|
|
43283
|
-
}).strict();
|
|
43284
|
-
var opsGenerateBlueprintOutputSchema = external_exports.object({
|
|
43285
|
-
blueprintId: external_exports.string().min(1),
|
|
43286
|
-
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."),
|
|
43287
|
-
validatorScore: external_exports.number().min(0).max(1).optional().describe("Advanced generator's iterative-loop validator score (0-1). Absent for default-generator output."),
|
|
43288
|
-
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.")
|
|
43289
|
-
}).strict();
|
|
43290
|
-
var opsRegisterBlueprintInputSchema = external_exports.object({
|
|
43291
|
-
contract: dataContractSchema,
|
|
43292
|
-
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_*`."),
|
|
43293
|
-
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."),
|
|
43294
|
-
aesthetic: external_exports.string().optional().describe("Free-form aesthetic tag. Persisted on `Blueprint.variance.aesthetic`."),
|
|
43295
|
-
context: external_exports.record(external_exports.string(), jsonValueSchema).optional().describe("Small structured signal carried alongside the persona. Persisted on `Blueprint.variance.context`."),
|
|
43296
|
-
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)."),
|
|
43297
|
-
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.")
|
|
43298
|
-
}).strict();
|
|
43299
|
-
var opsRegisterBlueprintOutputSchema = external_exports.object({
|
|
43300
|
-
blueprintId: external_exports.string().min(1),
|
|
43301
|
-
codeHash: external_exports.string().min(1).describe("Content hash of the persisted code body (full sha256 hex)."),
|
|
43302
|
-
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.')
|
|
43303
|
-
}).strict();
|
|
43304
|
-
var opsListBlueprintsInputSchema = external_exports.object({
|
|
43305
|
-
contractHash: external_exports.string().min(1).optional().describe("Filter to a single `(appId, contractHash)` group. Combine with `generator` / `persona` to narrow within the group."),
|
|
43306
|
-
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).'),
|
|
43307
|
-
persona: external_exports.string().optional().describe("Filter on `variance.persona`. Normalized to match persisted form (lowercase+trim)."),
|
|
43308
|
-
intentKeywords: external_exports.array(external_exports.string().min(1)).optional().describe("Semantic-search tokens. When set, dispatches through `BlueprintSearch.search()` rather than indexed `list()`.")
|
|
43309
|
-
}).strict();
|
|
43310
|
-
var opsListBlueprintsOutputSchema = external_exports.object({
|
|
43311
|
-
blueprints: external_exports.array(blueprintSchema)
|
|
43312
|
-
}).strict();
|
|
43313
|
-
var opsUpdateBlueprintInputSchema = external_exports.object({
|
|
43314
|
-
blueprintId: external_exports.string().min(1),
|
|
43315
|
-
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."),
|
|
43316
|
-
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).')
|
|
43317
|
-
}).strict();
|
|
43318
|
-
var opsUpdateBlueprintOutputSchema = external_exports.object({
|
|
43319
|
-
blueprintId: external_exports.string().min(1),
|
|
43320
|
-
updatedAt: external_exports.string().min(1)
|
|
43321
|
-
}).strict();
|
|
43322
|
-
var opsDeleteBlueprintInputSchema = external_exports.object({
|
|
43323
|
-
blueprintId: external_exports.string().min(1)
|
|
43324
|
-
}).strict();
|
|
43325
|
-
var opsDeleteBlueprintOutputSchema = external_exports.object({
|
|
43326
|
-
deleted: external_exports.literal(true)
|
|
43327
|
-
}).strict();
|
|
43328
|
-
|
|
43329
|
-
// ../protocol/dist/envelopes/builders.js
|
|
43330
|
-
function resolveSchemaVersion(parts) {
|
|
43331
|
-
if ("schemaVersion" in parts) {
|
|
43332
|
-
return parts.schemaVersion;
|
|
43333
|
-
}
|
|
43334
|
-
return PROTOCOL_SCHEMA_VERSION;
|
|
43335
|
-
}
|
|
43336
|
-
function makeActionEnvelope(parts) {
|
|
43337
|
-
const envelope = {
|
|
43338
|
-
sessionId: parts.sessionId,
|
|
43339
|
-
type: parts.type
|
|
43340
|
-
};
|
|
43341
|
-
if (parts.payload !== void 0)
|
|
43342
|
-
envelope.payload = parts.payload;
|
|
43343
|
-
if (parts.clientSeq !== void 0)
|
|
43344
|
-
envelope.clientSeq = parts.clientSeq;
|
|
43345
|
-
const stamp = resolveSchemaVersion(parts);
|
|
43346
|
-
if (stamp !== void 0)
|
|
43347
|
-
envelope.schemaVersion = stamp;
|
|
43348
|
-
return envelope;
|
|
43349
|
-
}
|
|
43350
|
-
|
|
43351
43298
|
// ../protocol/dist/validation/ajv-runtime.js
|
|
43352
43299
|
var import_ajv = __toESM(require_ajv(), 1);
|
|
43353
43300
|
var import_ajv_formats = __toESM(require_dist(), 1);
|
|
@@ -43390,8 +43337,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
43390
43337
|
if (!standaloneAjv.getKeyword("nullable")) {
|
|
43391
43338
|
standaloneAjv.addKeyword({ keyword: "nullable" });
|
|
43392
43339
|
}
|
|
43340
|
+
var standaloneCjsAjv = new import_ajv.default({
|
|
43341
|
+
...AJV_OPTIONS,
|
|
43342
|
+
code: { source: true }
|
|
43343
|
+
});
|
|
43344
|
+
(0, import_ajv_formats.default)(standaloneCjsAjv);
|
|
43345
|
+
if (!standaloneCjsAjv.getKeyword("example")) {
|
|
43346
|
+
standaloneCjsAjv.addKeyword({ keyword: "example" });
|
|
43347
|
+
}
|
|
43348
|
+
if (!standaloneCjsAjv.getKeyword("nullable")) {
|
|
43349
|
+
standaloneCjsAjv.addKeyword({ keyword: "nullable" });
|
|
43350
|
+
}
|
|
43393
43351
|
function injectClosedShape(schema) {
|
|
43394
|
-
const
|
|
43352
|
+
const typeSet = new Set(Array.isArray(schema.type) ? schema.type : schema.type ? [schema.type] : []);
|
|
43353
|
+
const isObjectNode = typeSet.has("object") || schema.properties !== void 0;
|
|
43395
43354
|
if (isObjectNode) {
|
|
43396
43355
|
const out = { ...schema };
|
|
43397
43356
|
if (out.properties) {
|
|
@@ -43412,7 +43371,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
43412
43371
|
out.anyOf = out.anyOf.map(injectClosedShape);
|
|
43413
43372
|
return out;
|
|
43414
43373
|
}
|
|
43415
|
-
if (
|
|
43374
|
+
if (typeSet.has("array") && schema.items) {
|
|
43416
43375
|
return { ...schema, items: injectClosedShape(schema.items) };
|
|
43417
43376
|
}
|
|
43418
43377
|
if (schema.oneOf || schema.anyOf) {
|
|
@@ -43432,7 +43391,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
43432
43391
|
function mapAjvErrorsToViolations(errors, data) {
|
|
43433
43392
|
if (!errors)
|
|
43434
43393
|
return [];
|
|
43435
|
-
return errors.map((err) =>
|
|
43394
|
+
return errors.map((err) => ({
|
|
43395
|
+
...mapOne(err, data),
|
|
43396
|
+
...err.keyword ? { keyword: err.keyword } : {}
|
|
43397
|
+
}));
|
|
43436
43398
|
}
|
|
43437
43399
|
function prefixViolations(violations, prefix) {
|
|
43438
43400
|
if (!prefix)
|
|
@@ -43779,6 +43741,88 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
43779
43741
|
return validateActionData(envelope.payload, spec, precompiledActions);
|
|
43780
43742
|
}
|
|
43781
43743
|
|
|
43744
|
+
// ../protocol/dist/schemas/ops-blueprint.js
|
|
43745
|
+
var opsGenerateBlueprintInputSchema = external_exports.object({
|
|
43746
|
+
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."),
|
|
43747
|
+
contract: dataContractSchema,
|
|
43748
|
+
generator: external_exports.string().min(1).optional().describe("Generator slug (e.g. `ui-gen-default-haiku-4-5`). When omitted, dispatches through `GeneratorRegistry.defaultGenerator()`."),
|
|
43749
|
+
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."),
|
|
43750
|
+
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."),
|
|
43751
|
+
context: external_exports.record(external_exports.string(), jsonValueSchema).optional().describe("Small structured signal carried alongside the persona. Persisted on `Blueprint.variance.context`."),
|
|
43752
|
+
seedPrompt: external_exports.string().optional().describe("The raw operator prompt that produced this variant. Round-trip input for the variant-selector + audit trail."),
|
|
43753
|
+
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.")
|
|
43754
|
+
}).strict();
|
|
43755
|
+
var opsGenerateBlueprintOutputSchema = external_exports.object({
|
|
43756
|
+
blueprintId: external_exports.string().min(1),
|
|
43757
|
+
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."),
|
|
43758
|
+
validatorScore: external_exports.number().min(0).max(1).optional().describe("Advanced generator's iterative-loop validator score (0-1). Absent for default-generator output."),
|
|
43759
|
+
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.")
|
|
43760
|
+
}).strict();
|
|
43761
|
+
var opsRegisterBlueprintInputSchema = external_exports.object({
|
|
43762
|
+
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."),
|
|
43763
|
+
contract: dataContractSchema,
|
|
43764
|
+
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_*`."),
|
|
43765
|
+
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."),
|
|
43766
|
+
aesthetic: external_exports.string().optional().describe("Free-form aesthetic tag. Persisted on `Blueprint.variance.aesthetic`."),
|
|
43767
|
+
context: external_exports.record(external_exports.string(), jsonValueSchema).optional().describe("Small structured signal carried alongside the persona. Persisted on `Blueprint.variance.context`."),
|
|
43768
|
+
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)."),
|
|
43769
|
+
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.")
|
|
43770
|
+
}).strict();
|
|
43771
|
+
var opsRegisterBlueprintOutputSchema = external_exports.object({
|
|
43772
|
+
blueprintId: external_exports.string().min(1),
|
|
43773
|
+
codeHash: external_exports.string().min(1).describe("Content hash of the persisted code body (full sha256 hex)."),
|
|
43774
|
+
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.')
|
|
43775
|
+
}).strict();
|
|
43776
|
+
var opsListBlueprintsInputSchema = external_exports.object({
|
|
43777
|
+
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."),
|
|
43778
|
+
contractHash: external_exports.string().min(1).optional().describe("Filter to a single `(appId, contractHash)` group. Combine with `generator` / `persona` to narrow within the group."),
|
|
43779
|
+
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).'),
|
|
43780
|
+
persona: external_exports.string().optional().describe("Filter on `variance.persona`. Normalized to match persisted form (lowercase+trim)."),
|
|
43781
|
+
intentKeywords: external_exports.array(external_exports.string().min(1)).optional().describe("Semantic-search tokens. When set, dispatches through `BlueprintSearch.search()` rather than indexed `list()`.")
|
|
43782
|
+
}).strict();
|
|
43783
|
+
var opsListBlueprintsOutputSchema = external_exports.object({
|
|
43784
|
+
blueprints: external_exports.array(blueprintSchema)
|
|
43785
|
+
}).strict();
|
|
43786
|
+
var opsUpdateBlueprintInputSchema = external_exports.object({
|
|
43787
|
+
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."),
|
|
43788
|
+
blueprintId: external_exports.string().min(1),
|
|
43789
|
+
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."),
|
|
43790
|
+
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).')
|
|
43791
|
+
}).strict();
|
|
43792
|
+
var opsUpdateBlueprintOutputSchema = external_exports.object({
|
|
43793
|
+
blueprintId: external_exports.string().min(1),
|
|
43794
|
+
updatedAt: external_exports.string().min(1)
|
|
43795
|
+
}).strict();
|
|
43796
|
+
var opsDeleteBlueprintInputSchema = external_exports.object({
|
|
43797
|
+
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."),
|
|
43798
|
+
blueprintId: external_exports.string().min(1)
|
|
43799
|
+
}).strict();
|
|
43800
|
+
var opsDeleteBlueprintOutputSchema = external_exports.object({
|
|
43801
|
+
deleted: external_exports.literal(true)
|
|
43802
|
+
}).strict();
|
|
43803
|
+
|
|
43804
|
+
// ../protocol/dist/envelopes/builders.js
|
|
43805
|
+
function resolveSchemaVersion(parts) {
|
|
43806
|
+
if ("schemaVersion" in parts) {
|
|
43807
|
+
return parts.schemaVersion;
|
|
43808
|
+
}
|
|
43809
|
+
return PROTOCOL_SCHEMA_VERSION;
|
|
43810
|
+
}
|
|
43811
|
+
function makeActionEnvelope(parts) {
|
|
43812
|
+
const envelope = {
|
|
43813
|
+
sessionId: parts.sessionId,
|
|
43814
|
+
type: parts.type
|
|
43815
|
+
};
|
|
43816
|
+
if (parts.payload !== void 0)
|
|
43817
|
+
envelope.payload = parts.payload;
|
|
43818
|
+
if (parts.clientSeq !== void 0)
|
|
43819
|
+
envelope.clientSeq = parts.clientSeq;
|
|
43820
|
+
const stamp = resolveSchemaVersion(parts);
|
|
43821
|
+
if (stamp !== void 0)
|
|
43822
|
+
envelope.schemaVersion = stamp;
|
|
43823
|
+
return envelope;
|
|
43824
|
+
}
|
|
43825
|
+
|
|
43782
43826
|
// ../wire/dist/contract.js
|
|
43783
43827
|
var ClientContractViolationError = class extends Error {
|
|
43784
43828
|
direction;
|
|
@@ -46849,19 +46893,26 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
46849
46893
|
function globalExpr(gguiKey, legacyName) {
|
|
46850
46894
|
return `(globalThis.__ggui__&&globalThis.__ggui__["${gguiKey}"]||window["${legacyName}"])`;
|
|
46851
46895
|
}
|
|
46852
|
-
function
|
|
46896
|
+
function toDataUrl(js) {
|
|
46897
|
+
return `data:text/javascript,${encodeURIComponent(js)}`;
|
|
46898
|
+
}
|
|
46899
|
+
function jsReactShim(globalName) {
|
|
46853
46900
|
const namedExports = REACT_EXPORTS.map((e) => `export const ${e} = R.${e};`).join(" ");
|
|
46854
46901
|
const resolve = globalExpr("react", globalName);
|
|
46855
|
-
|
|
46856
|
-
return `data:text/javascript,${encodeURIComponent(js)}`;
|
|
46902
|
+
return `const R = ${resolve}; export default R; ${namedExports}`;
|
|
46857
46903
|
}
|
|
46858
|
-
function
|
|
46904
|
+
function buildDataUrlReactShim(globalName) {
|
|
46905
|
+
return toDataUrl(jsReactShim(globalName));
|
|
46906
|
+
}
|
|
46907
|
+
function jsReactDomShim() {
|
|
46859
46908
|
const REACT_DOM_EXPORTS = ["createPortal", "flushSync", "unstable_batchedUpdates"];
|
|
46860
46909
|
const namedExports = REACT_DOM_EXPORTS.map((e) => `export const ${e} = D.${e};`).join(" ");
|
|
46861
|
-
|
|
46862
|
-
return `data:text/javascript,${encodeURIComponent(js)}`;
|
|
46910
|
+
return `const D = globalThis.__ggui__["reactDom"]; export default D; ${namedExports}`;
|
|
46863
46911
|
}
|
|
46864
|
-
function
|
|
46912
|
+
function buildDataUrlReactDomShim() {
|
|
46913
|
+
return toDataUrl(jsReactDomShim());
|
|
46914
|
+
}
|
|
46915
|
+
function jsJsxShim(globalName) {
|
|
46865
46916
|
const resolve = globalExpr("react", globalName);
|
|
46866
46917
|
const js = [
|
|
46867
46918
|
`const R = ${resolve};`,
|
|
@@ -46874,9 +46925,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
46874
46925
|
`export{jsx,jsx as jsxs,jsx as jsxDEV};`,
|
|
46875
46926
|
`export const Fragment=R.Fragment;`
|
|
46876
46927
|
].join("");
|
|
46877
|
-
return
|
|
46928
|
+
return js;
|
|
46878
46929
|
}
|
|
46879
|
-
function
|
|
46930
|
+
function buildDataUrlJsxShim(globalName) {
|
|
46931
|
+
return toDataUrl(jsJsxShim(globalName));
|
|
46932
|
+
}
|
|
46933
|
+
function jsGlobalShim(globalName, gguiKey, exportNames, fallbackGlobals, fallbackGguiKeys) {
|
|
46880
46934
|
if (exportNames && exportNames.length > 0) {
|
|
46881
46935
|
const globals = [globalName, ...fallbackGlobals || []];
|
|
46882
46936
|
const gguiKeys = [gguiKey, ...fallbackGguiKeys || []];
|
|
@@ -46887,17 +46941,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
46887
46941
|
));
|
|
46888
46942
|
const mergeExpr = resolveExprs.join(",");
|
|
46889
46943
|
const named = exportNames.map((n) => `export const ${n} = M["${n}"];`).join(" ");
|
|
46890
|
-
|
|
46891
|
-
return `data:text/javascript,${encodeURIComponent(js2)}`;
|
|
46944
|
+
return resolveExprs.length > 1 ? `const M = Object.assign({}, ${mergeExpr}); ${named} export default M;` : `const M = ${resolveExprs[0]}; ${named} export default M;`;
|
|
46892
46945
|
}
|
|
46893
46946
|
const resolve = globalExpr(gguiKey, globalName);
|
|
46894
|
-
|
|
46895
|
-
return `data:text/javascript,${encodeURIComponent(js)}`;
|
|
46947
|
+
return `const M = ${resolve} || {}; const handler = { get(_, key) { return M[key]; } }; export default new Proxy({}, handler);`;
|
|
46896
46948
|
}
|
|
46897
|
-
function
|
|
46949
|
+
function buildDataUrlGlobalShim(globalName, gguiKey, exportNames, fallbackGlobals, fallbackGguiKeys) {
|
|
46950
|
+
return toDataUrl(jsGlobalShim(globalName, gguiKey, exportNames, fallbackGlobals, fallbackGguiKeys));
|
|
46951
|
+
}
|
|
46952
|
+
function jsWireShim() {
|
|
46898
46953
|
const named = WIRE_EXPORTS.map((e) => `export const ${e} = w.${e};`).join(" ");
|
|
46899
|
-
|
|
46900
|
-
|
|
46954
|
+
return `const w = globalThis.__ggui__.wire; ${named} export default w;`;
|
|
46955
|
+
}
|
|
46956
|
+
function buildDataUrlWireShim() {
|
|
46957
|
+
return toDataUrl(jsWireShim());
|
|
46901
46958
|
}
|
|
46902
46959
|
function extractNamedImports(code, specifier) {
|
|
46903
46960
|
const esc2 = specifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -46914,7 +46971,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
46914
46971
|
}
|
|
46915
46972
|
return [...names];
|
|
46916
46973
|
}
|
|
46917
|
-
function
|
|
46974
|
+
function jsGadgetPackageShim(packageName, exportNames) {
|
|
46918
46975
|
const pkgLit = JSON.stringify(packageName);
|
|
46919
46976
|
const hasComponent = exportNames.some((n) => /^[A-Z]/.test(n));
|
|
46920
46977
|
const parts = [];
|
|
@@ -46931,7 +46988,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
46931
46988
|
parts.push(`export const ${name}=${factory}(${JSON.stringify(name)});`);
|
|
46932
46989
|
}
|
|
46933
46990
|
parts.push(`export default new Proxy({},{get:function(_,k){return NS()[k];}});`);
|
|
46934
|
-
return
|
|
46991
|
+
return parts.join("");
|
|
46992
|
+
}
|
|
46993
|
+
function buildGadgetPackageShim(packageName, exportNames) {
|
|
46994
|
+
return toDataUrl(jsGadgetPackageShim(packageName, exportNames));
|
|
46935
46995
|
}
|
|
46936
46996
|
function rewriteDataUrl(code, opts) {
|
|
46937
46997
|
const reactGlobal = opts.reactGlobal ?? "__REACT";
|
|
@@ -46966,6 +47026,29 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
46966
47026
|
}
|
|
46967
47027
|
return code;
|
|
46968
47028
|
}
|
|
47029
|
+
var ASSET_SHIM_FOR_SPECIFIER = {
|
|
47030
|
+
"react/jsx-runtime": "jsx-runtime",
|
|
47031
|
+
"react/jsx-dev-runtime": "jsx-runtime",
|
|
47032
|
+
"react-dom": "react-dom",
|
|
47033
|
+
react: "react",
|
|
47034
|
+
"@ggui-ai/design/primitives": "primitives",
|
|
47035
|
+
"@ggui-ai/design/components": "components",
|
|
47036
|
+
"@ggui-ai/design/compositions": "compositions",
|
|
47037
|
+
"@ggui-ai/design/interact": "interact",
|
|
47038
|
+
"@ggui-ai/design/templates": "templates",
|
|
47039
|
+
"@ggui-ai/design/app-components": "app-components",
|
|
47040
|
+
"@ggui-ai/design/tokens": "tokens",
|
|
47041
|
+
"@ggui-ai/design": "design",
|
|
47042
|
+
"@ggui-ai/wire": "wire",
|
|
47043
|
+
"@ggui-ai/gadgets": "gadgets"
|
|
47044
|
+
};
|
|
47045
|
+
function rewriteAssetUrl(code, opts) {
|
|
47046
|
+
const base = opts.shimBaseUrl.replace(/\/$/, "");
|
|
47047
|
+
for (const [specifier, shimName] of Object.entries(ASSET_SHIM_FOR_SPECIFIER)) {
|
|
47048
|
+
code = replaceSpecifier(code, specifier, `${base}/${shimName}.js`);
|
|
47049
|
+
}
|
|
47050
|
+
return code;
|
|
47051
|
+
}
|
|
46969
47052
|
function rewriteImportmap(code, opts) {
|
|
46970
47053
|
const base = opts.reactBaseUrl ?? "https://esm.sh/react@18.2.0";
|
|
46971
47054
|
code = replaceSpecifier(code, "react/jsx-runtime", `${base}/jsx-runtime`);
|
|
@@ -46979,6 +47062,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
46979
47062
|
return rewriteDataUrl(code, options);
|
|
46980
47063
|
case "importmap":
|
|
46981
47064
|
return rewriteImportmap(code, options);
|
|
47065
|
+
case "asset-url":
|
|
47066
|
+
return rewriteAssetUrl(code, options);
|
|
46982
47067
|
}
|
|
46983
47068
|
}
|
|
46984
47069
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ggui-ai/ui-visual-tester",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Behavioral validator for ggui-generated component code. Renders a component in real Chromium via Playwright, clicks each action declared in its contract, and verifies the action actually does something — mutating bound state or dispatching to the agent. Catches buttons wired to no-op handlers that structural validators miss. Playwright is an optional peer dependency, injected by the caller.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ggui",
|
|
@@ -48,9 +48,9 @@
|
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"react": "^19.0.0",
|
|
50
50
|
"react-dom": "^19.0.0",
|
|
51
|
-
"@ggui-ai/
|
|
52
|
-
"@ggui-ai/
|
|
53
|
-
"@ggui-ai/
|
|
51
|
+
"@ggui-ai/protocol": "0.10.0",
|
|
52
|
+
"@ggui-ai/wire": "0.10.0",
|
|
53
|
+
"@ggui-ai/design": "0.10.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@playwright/test": "^1.60.0",
|