@ggui-ai/mcp-server-handlers 0.25.0 → 0.26.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/README.md +2 -2
- package/dist/credits/index.d.ts +2 -2
- package/dist/credits/index.d.ts.map +1 -1
- package/dist/credits/index.js +1 -1
- package/dist/credits/list-credit-transactions.d.ts +21 -7
- package/dist/credits/list-credit-transactions.d.ts.map +1 -1
- package/dist/credits/list-credit-transactions.js +12 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/ops-blueprint/cache-mirror.d.ts +41 -0
- package/dist/ops-blueprint/cache-mirror.d.ts.map +1 -0
- package/dist/ops-blueprint/cache-mirror.js +19 -0
- package/dist/ops-blueprint/delete.d.ts +18 -0
- package/dist/ops-blueprint/delete.d.ts.map +1 -1
- package/dist/ops-blueprint/delete.js +21 -2
- package/dist/ops-blueprint/errors.d.ts +11 -0
- package/dist/ops-blueprint/errors.d.ts.map +1 -1
- package/dist/ops-blueprint/errors.js +14 -0
- package/dist/ops-blueprint/generate.d.ts +1 -3
- package/dist/ops-blueprint/generate.d.ts.map +1 -1
- package/dist/ops-blueprint/generate.js +47 -58
- package/dist/ops-blueprint/list.d.ts.map +1 -1
- package/dist/ops-blueprint/list.js +1 -2
- package/dist/ops-blueprint/register.d.ts +17 -6
- package/dist/ops-blueprint/register.d.ts.map +1 -1
- package/dist/ops-blueprint/register.js +77 -45
- package/dist/ops-blueprint/update.d.ts +3 -2
- package/dist/ops-blueprint/update.d.ts.map +1 -1
- package/dist/ops-blueprint/update.js +4 -3
- package/dist/renders/blueprint-coverage.d.ts +23 -4
- package/dist/renders/blueprint-coverage.d.ts.map +1 -1
- package/dist/renders/blueprint-coverage.js +45 -5
- package/dist/renders/blueprint-durability.d.ts.map +1 -1
- package/dist/renders/blueprint-durability.js +5 -0
- package/dist/renders/blueprint-matcher.d.ts +28 -0
- package/dist/renders/blueprint-matcher.d.ts.map +1 -1
- package/dist/renders/blueprint-matcher.js +39 -7
- package/dist/renders/blueprint-registry.d.ts +52 -1
- package/dist/renders/blueprint-registry.d.ts.map +1 -1
- package/dist/renders/blueprint-registry.js +137 -10
- package/dist/renders/build-seed-pool.d.ts.map +1 -1
- package/dist/renders/build-seed-pool.js +6 -0
- package/dist/renders/consume.d.ts +3 -2
- package/dist/renders/consume.d.ts.map +1 -1
- package/dist/renders/consume.js +23 -14
- package/dist/renders/cross-app-refused.d.ts +3 -2
- package/dist/renders/cross-app-refused.d.ts.map +1 -1
- package/dist/renders/cross-app-refused.js +5 -3
- package/dist/renders/decide-handshake.d.ts +28 -0
- package/dist/renders/decide-handshake.d.ts.map +1 -1
- package/dist/renders/decide-handshake.js +39 -4
- package/dist/renders/export-registry.d.ts +8 -1
- package/dist/renders/export-registry.d.ts.map +1 -1
- package/dist/renders/export-registry.js +3 -0
- package/dist/renders/fits.d.ts.map +1 -1
- package/dist/renders/fits.js +23 -1
- package/dist/renders/handshake.d.ts +6 -42
- package/dist/renders/handshake.d.ts.map +1 -1
- package/dist/renders/handshake.js +1 -1
- package/dist/renders/index.d.ts +5 -4
- package/dist/renders/index.d.ts.map +1 -1
- package/dist/renders/index.js +4 -3
- package/dist/renders/installed-blueprints-provider.d.ts.map +1 -1
- package/dist/renders/installed-blueprints-provider.js +3 -1
- package/dist/renders/match-precision/pairs.d.ts +5 -4
- package/dist/renders/match-precision/pairs.d.ts.map +1 -1
- package/dist/renders/match-precision/topk-probe.js +13 -8
- package/dist/renders/record-committed-one-shot.d.ts +18 -3
- package/dist/renders/record-committed-one-shot.d.ts.map +1 -1
- package/dist/renders/record-committed-one-shot.js +14 -7
- package/dist/renders/refresh-ws-token.d.ts +9 -12
- package/dist/renders/refresh-ws-token.d.ts.map +1 -1
- package/dist/renders/refresh-ws-token.js +13 -10
- package/dist/renders/render-identity.d.ts +14 -5
- package/dist/renders/render-identity.d.ts.map +1 -1
- package/dist/renders/render-identity.js +25 -12
- package/dist/renders/render-read-gate.d.ts +27 -1
- package/dist/renders/render-read-gate.d.ts.map +1 -1
- package/dist/renders/render-read-gate.js +17 -5
- package/dist/renders/render.d.ts +36 -19
- package/dist/renders/render.d.ts.map +1 -1
- package/dist/renders/render.js +174 -17
- package/dist/renders/report-render-failure.d.ts +69 -0
- package/dist/renders/report-render-failure.d.ts.map +1 -0
- package/dist/renders/report-render-failure.js +83 -0
- package/dist/renders/runtime-pull.d.ts.map +1 -1
- package/dist/renders/runtime-pull.js +6 -0
- package/dist/renders/slice-meta-derivation.d.ts +8 -1
- package/dist/renders/slice-meta-derivation.d.ts.map +1 -1
- package/dist/renders/slice-meta-derivation.js +1 -0
- package/dist/renders/submit-action.d.ts +41 -71
- package/dist/renders/submit-action.d.ts.map +1 -1
- package/dist/renders/submit-action.js +225 -78
- package/dist/renders/sync-context.d.ts +3 -1
- package/dist/renders/sync-context.d.ts.map +1 -1
- package/dist/renders/sync-context.js +38 -8
- package/dist/types.d.ts +71 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +32 -0
- package/package.json +8 -8
|
@@ -2,7 +2,7 @@ import { DomainError } from '@ggui-ai/protocol';
|
|
|
2
2
|
import type { BlueprintIndex, EmbeddingProvider, EnumerableVectorStore, VectorStore } from '@ggui-ai/mcp-server-core';
|
|
3
3
|
export type { BlueprintIndex } from '@ggui-ai/mcp-server-core';
|
|
4
4
|
import type { AestheticPresetRef, DirectionScope } from './fits.js';
|
|
5
|
-
import { type BlueprintSource, type BlueprintVariance, type DataContract } from '@ggui-ai/protocol';
|
|
5
|
+
import { type BlueprintSource, type BlueprintVariance, type DataContract, type GeneratorBuild } from '@ggui-ai/protocol';
|
|
6
6
|
import { type ContractValidationFinding, type ContractValidationResult } from '@ggui-ai/negotiator';
|
|
7
7
|
import { type BlueprintDurabilityDeps } from './blueprint-durability.js';
|
|
8
8
|
/**
|
|
@@ -102,6 +102,16 @@ export interface Blueprint {
|
|
|
102
102
|
* A blueprint cache invalidates by regeneration; it never coerces.
|
|
103
103
|
*/
|
|
104
104
|
readonly source: BlueprintSource;
|
|
105
|
+
/**
|
|
106
|
+
* The build of the engine that minted this blueprint (ggui#1280), set
|
|
107
|
+
* only on a generation mint (`source.kind === 'llm'`) whose stamp
|
|
108
|
+
* passed {@link admitGeneratorBuild}. It is written to the DURABLE
|
|
109
|
+
* record (`projectDurableBlueprint`) and to the vector-store row
|
|
110
|
+
* (`METADATA_KEYS.build`, ggui#1476), so a row read back via
|
|
111
|
+
* {@link rowToBlueprint} — a dedup return and a reuse included — names
|
|
112
|
+
* its MINTING build; an unreadable stored value reads as absent.
|
|
113
|
+
*/
|
|
114
|
+
readonly build?: GeneratorBuild;
|
|
105
115
|
/**
|
|
106
116
|
* Lifecycle-owner marker for rows materialized by the marketplace
|
|
107
117
|
* install bridge (`installToCache`). Orthogonal to {@link source}
|
|
@@ -255,6 +265,13 @@ export interface RegisterBlueprintInput {
|
|
|
255
265
|
* empty variance as one stable sentinel.
|
|
256
266
|
*/
|
|
257
267
|
readonly variance?: BlueprintVariance;
|
|
268
|
+
/**
|
|
269
|
+
* The minting engine's build (ggui#1280), from the generation's
|
|
270
|
+
* `metadata.build`. Pass it only for code a generation produced; the
|
|
271
|
+
* registry keeps it only when {@link admitGeneratorBuild} does, and a
|
|
272
|
+
* dedup keeps the row's MINTING build (first write wins).
|
|
273
|
+
*/
|
|
274
|
+
readonly build?: GeneratorBuild;
|
|
258
275
|
/**
|
|
259
276
|
* WHO initiated this mint, for the durable record. `'agent'` is the
|
|
260
277
|
* standard handshake → render flow; the operator tools
|
|
@@ -288,6 +305,40 @@ export declare function composeExactKey(kind: BlueprintKind, contractKey: string
|
|
|
288
305
|
* the prompt's `cachedContractSummary` MUST equal what was embedded.
|
|
289
306
|
*/
|
|
290
307
|
export declare function composeEmbeddingInput(contract: DataContract | undefined, intent: string): string;
|
|
308
|
+
/**
|
|
309
|
+
* ggui#1476 — the minting build a registry row stores, or `undefined` when
|
|
310
|
+
* the row has none or its stored value is unreadable. The ONE reader of the
|
|
311
|
+
* `build` key: the registry's row reader and the exporter both call it, so
|
|
312
|
+
* the key has one owner. It parses the stored JSON and validates it with the
|
|
313
|
+
* protocol's strict `generatorBuildSchema`; an unreadable value drops the
|
|
314
|
+
* FACT — the row reads as an unknown minting build — never the row, with one
|
|
315
|
+
* line per row id per process.
|
|
316
|
+
*/
|
|
317
|
+
export declare function readGeneratorBuild(metadata: Record<string, string | number | boolean | null>, rowId: string): GeneratorBuild | undefined;
|
|
318
|
+
/**
|
|
319
|
+
* The one admission rule for a blueprint's build stamp (ggui#1280): keep
|
|
320
|
+
* `build` only for code a generation produced (`source.kind === 'llm'`),
|
|
321
|
+
* only when it passes the protocol's strict `generatorBuildSchema`, and only
|
|
322
|
+
* when it serializes within {@link MAX_BUILD_STAMP_BYTES} (ggui#1476 — the
|
|
323
|
+
* stamp rides every vector-store row's metadata).
|
|
324
|
+
* Otherwise the STAMP is dropped, with a line, and the registration goes
|
|
325
|
+
* ahead unstamped: a row whose minting build is unknown is a reported
|
|
326
|
+
* category, never an error, while a malformed stamp on a durable row would
|
|
327
|
+
* make every strict reader of that row refuse it (`ggui_ops_list_blueprints`
|
|
328
|
+
* validates its rows with `blueprintSchema`). Every writer of a stamp calls
|
|
329
|
+
* this, so the rule has one home.
|
|
330
|
+
*/
|
|
331
|
+
export declare function admitGeneratorBuild(source: BlueprintSource, build: GeneratorBuild | undefined): GeneratorBuild | undefined;
|
|
332
|
+
/**
|
|
333
|
+
* ggui#1476 — the largest build stamp, serialized, a row may carry. The stamp
|
|
334
|
+
* rides every registry row's vector-store metadata, and a production vector
|
|
335
|
+
* backend bounds that metadata per row (a filterable-metadata budget of
|
|
336
|
+
* about 2 KB on one such backend, where a rejected write is swallowed by
|
|
337
|
+
* registration and reads as a silently empty cache). A real stamp — two
|
|
338
|
+
* 64-hex digests, a version and a mode — is about 250 bytes; the bound keeps
|
|
339
|
+
* an engine that reports many more digests from ever reaching that budget.
|
|
340
|
+
*/
|
|
341
|
+
export declare const MAX_BUILD_STAMP_BYTES = 1024;
|
|
291
342
|
/**
|
|
292
343
|
* Default cap on registered blueprints per (scope, kind). When a
|
|
293
344
|
* fresh registration would push the bucket past the cap,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blueprint-registry.d.ts","sourceRoot":"","sources":["../../src/renders/blueprint-registry.ts"],"names":[],"mappings":"AA0CA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EAKrB,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAKlC,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,
|
|
1
|
+
{"version":3,"file":"blueprint-registry.d.ts","sourceRoot":"","sources":["../../src/renders/blueprint-registry.ts"],"names":[],"mappings":"AA0CA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EAKrB,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAKlC,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAEL,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC9B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,2BAA2B,CAAC;AAEnC;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;AAE1E,mDAAmD;AACnD,MAAM,WAAW,SAAS;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,UAAU,CAAC;IACnC;;;;;OAKG;IACH,sDAAsD;IACtD,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,sFAAsF;IACtF,QAAQ,CAAC,eAAe,CAAC,EAAE,kBAAkB,CAAC;IAC9C,wEAAwE;IACxE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,yGAAyG;IACzG,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC,oFAAoF;IACpF,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,qCAAqC;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;OASG;IACH,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;IAChC;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,yBAAyB,EAAE,CAAC;CACpE;AAED;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAC9B,QAAQ,EAAE,YAAY,KACnB,wBAAwB,CAAC;AAE9B;;;;;;;;;;;;GAYG;AACH,qBAAa,sBAAuB,SAAQ,WAAW,CAAC,oBAAoB,CAAC;IAC3E,QAAQ,CAAC,QAAQ,EAAE,SAAS,yBAAyB,EAAE,CAAC;gBAC5C,QAAQ,EAAE,SAAS,yBAAyB,EAAE;CAQ3D;AAED,gFAAgF;AAChF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B;;;;;;;;;OASG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,uBAAuB,CAAC;CAC/C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,UAAU,CAAC;AAE5D;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAGlE;AAED,2CAA2C;AAC3C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,qBAAqB,CAAC;IAC9C,mEAAmE;IACnE,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,oEAAoE;IACpE,QAAQ,CAAC,eAAe,CAAC,EAAE,kBAAkB,CAAC;IAC9C,oEAAoE;IACpE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,6FAA6F;IAC7F,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IACtC;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;IAChC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CAC3C;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,aAAa,EACnB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,MAAM,CAER;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,YAAY,GAAG,SAAS,EAClC,MAAM,EAAE,MAAM,GACb,MAAM,CAER;AAgHD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,EAC1D,KAAK,EAAE,MAAM,GACZ,cAAc,GAAG,SAAS,CAqB5B;AAmED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,cAAc,GAAG,SAAS,GAChC,cAAc,GAAG,SAAS,CAqB5B;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,OAAO,CAAC;AA2J1C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAEnD,MAAM,WAAW,wBAAwB;IACvC;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,iBAAiB,CAAC;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CAChC;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,qBAAqB,EAC3B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,sBAAsB,EAC7B,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,mBAAmB,CAAC,CAmH9B;AAoID;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE;IAAE,WAAW,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,EACzD,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,aAAa,EACnB,WAAW,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAM3B;AA4DD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE;IAAE,WAAW,EAAE,WAAW,CAAA;CAAE,EAClC,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAE3B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,qBAAqB,EAC3B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAA;CAAE,EACpE,OAAO,GAAE;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACtE,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAaxC;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE;IAAE,WAAW,EAAE,qBAAqB,CAAA;CAAE,EAC5C,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,aAAa,GACnB,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC,CAU/B;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE;IAAE,WAAW,EAAE,WAAW,CAAA;CAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC,EACnE,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED,0EAA0E;AAC1E,MAAM,MAAM,2BAA2B,GACnC,UAAU,GACV,kBAAkB,GAClB,mBAAmB,GACnB,kBAAkB,GAClB,WAAW,GACX,WAAW,CAAC;AAKhB,kDAAkD;AAClD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,2BAA2B,CAAC;IAC9C;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,kEAAkE;IAClE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,qBAAqB,EAC3B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE;IACN,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CACvC,EACD,IAAI,EAAE;IAAE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EACrE,OAAO,GAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1C,OAAO,CAAC,0BAA0B,CAAC,CAqErC;AAoBD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE;IAAE,WAAW,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,EACzD,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,IAAI,CAAC,CAef"}
|
|
@@ -41,7 +41,7 @@ import { createHash } from 'node:crypto';
|
|
|
41
41
|
*/
|
|
42
42
|
import { randomUUID } from 'node:crypto';
|
|
43
43
|
import { DomainError } from '@ggui-ai/protocol';
|
|
44
|
-
import { blueprintSourceToFlat, flatToBlueprintSource, summarizeContract, } from '@ggui-ai/protocol';
|
|
44
|
+
import { blueprintSourceToFlat, flatToBlueprintSource, generatorBuildSchema, summarizeContract, } from '@ggui-ai/protocol';
|
|
45
45
|
// `blueprintKey` + `variantKey` are server-only — pulled in from a
|
|
46
46
|
// dedicated subpath because they import `node:crypto`, which browsers
|
|
47
47
|
// can't bundle.
|
|
@@ -143,6 +143,10 @@ const METADATA_KEYS = {
|
|
|
143
143
|
aestheticPresetVersion: 'aestheticPresetVersion',
|
|
144
144
|
directionDigest: 'directionDigest',
|
|
145
145
|
directionScope: 'directionScope',
|
|
146
|
+
// ggui#1476 — the minting engine's build, as a JSON string. Bounded at
|
|
147
|
+
// admission (MAX_BUILD_STAMP_BYTES) so it cannot crowd a vector backend's
|
|
148
|
+
// metadata budget; written only when present.
|
|
149
|
+
build: 'build',
|
|
146
150
|
};
|
|
147
151
|
function blueprintToMetadata(bp) {
|
|
148
152
|
return {
|
|
@@ -186,6 +190,7 @@ function blueprintToMetadata(bp) {
|
|
|
186
190
|
...(bp.directionDigest !== undefined && bp.directionScope !== undefined
|
|
187
191
|
? { [METADATA_KEYS.directionScope]: bp.directionScope }
|
|
188
192
|
: {}),
|
|
193
|
+
...(bp.build !== undefined ? { [METADATA_KEYS.build]: JSON.stringify(bp.build) } : {}),
|
|
189
194
|
};
|
|
190
195
|
}
|
|
191
196
|
function readDirectionScope(raw) {
|
|
@@ -207,6 +212,48 @@ function readJudgedCanvases(raw) {
|
|
|
207
212
|
return undefined;
|
|
208
213
|
}
|
|
209
214
|
}
|
|
215
|
+
/** Row ids whose stored stamp was unreadable, already warned this process. */
|
|
216
|
+
const warnedUnreadableBuildIds = new Set();
|
|
217
|
+
/**
|
|
218
|
+
* ggui#1476 — the minting build a registry row stores, or `undefined` when
|
|
219
|
+
* the row has none or its stored value is unreadable. The ONE reader of the
|
|
220
|
+
* `build` key: the registry's row reader and the exporter both call it, so
|
|
221
|
+
* the key has one owner. It parses the stored JSON and validates it with the
|
|
222
|
+
* protocol's strict `generatorBuildSchema`; an unreadable value drops the
|
|
223
|
+
* FACT — the row reads as an unknown minting build — never the row, with one
|
|
224
|
+
* line per row id per process.
|
|
225
|
+
*/
|
|
226
|
+
export function readGeneratorBuild(metadata, rowId) {
|
|
227
|
+
const stored = metadata[METADATA_KEYS.build];
|
|
228
|
+
if (stored === undefined)
|
|
229
|
+
return undefined;
|
|
230
|
+
if (typeof stored !== 'string') {
|
|
231
|
+
warnUnreadableBuild(rowId, `stored as ${stored === null ? 'null' : typeof stored}, not a JSON string`);
|
|
232
|
+
return undefined;
|
|
233
|
+
}
|
|
234
|
+
const raw = stored;
|
|
235
|
+
let parsed;
|
|
236
|
+
try {
|
|
237
|
+
parsed = JSON.parse(raw);
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
warnUnreadableBuild(rowId, err instanceof Error ? err.message : String(err));
|
|
241
|
+
return undefined;
|
|
242
|
+
}
|
|
243
|
+
const build = generatorBuildSchema.safeParse(parsed);
|
|
244
|
+
if (!build.success) {
|
|
245
|
+
warnUnreadableBuild(rowId, build.error.issues.map((i) => i.message).join('; '));
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
return build.data;
|
|
249
|
+
}
|
|
250
|
+
function warnUnreadableBuild(rowId, why) {
|
|
251
|
+
if (warnedUnreadableBuildIds.has(rowId))
|
|
252
|
+
return;
|
|
253
|
+
warnedUnreadableBuildIds.add(rowId);
|
|
254
|
+
// eslint-disable-next-line no-console -- operator-visible degradation notice
|
|
255
|
+
console.warn(`[ggui] blueprint registry: blueprint_build_stamp_unreadable — row ${rowId} keeps its code; its minting build reads as unknown (${why})`);
|
|
256
|
+
}
|
|
210
257
|
function readAestheticPreset(metadata) {
|
|
211
258
|
const id = readScalarString(metadata[METADATA_KEYS.aestheticPresetId]);
|
|
212
259
|
if (id === undefined)
|
|
@@ -242,6 +289,59 @@ function warnEvictionFallback(event, consequence, err) {
|
|
|
242
289
|
// eslint-disable-next-line no-console -- operator-visible degradation notice
|
|
243
290
|
console.warn(`[ggui] blueprint registry: ${event} — ${consequence}: ${err instanceof Error ? err.message : String(err)} (logged once per process)`);
|
|
244
291
|
}
|
|
292
|
+
/**
|
|
293
|
+
* Stamp-drop reasons already warned this process — one line per process per
|
|
294
|
+
* reason, the {@link warnEvictionFallback} posture: visible without a line
|
|
295
|
+
* per generation when an engine keeps reporting the same bad stamp.
|
|
296
|
+
*/
|
|
297
|
+
const warnedBuildStampDrops = new Set();
|
|
298
|
+
/**
|
|
299
|
+
* The one admission rule for a blueprint's build stamp (ggui#1280): keep
|
|
300
|
+
* `build` only for code a generation produced (`source.kind === 'llm'`),
|
|
301
|
+
* only when it passes the protocol's strict `generatorBuildSchema`, and only
|
|
302
|
+
* when it serializes within {@link MAX_BUILD_STAMP_BYTES} (ggui#1476 — the
|
|
303
|
+
* stamp rides every vector-store row's metadata).
|
|
304
|
+
* Otherwise the STAMP is dropped, with a line, and the registration goes
|
|
305
|
+
* ahead unstamped: a row whose minting build is unknown is a reported
|
|
306
|
+
* category, never an error, while a malformed stamp on a durable row would
|
|
307
|
+
* make every strict reader of that row refuse it (`ggui_ops_list_blueprints`
|
|
308
|
+
* validates its rows with `blueprintSchema`). Every writer of a stamp calls
|
|
309
|
+
* this, so the rule has one home.
|
|
310
|
+
*/
|
|
311
|
+
export function admitGeneratorBuild(source, build) {
|
|
312
|
+
if (build === undefined)
|
|
313
|
+
return undefined;
|
|
314
|
+
const drop = (() => {
|
|
315
|
+
if (source.kind !== 'llm')
|
|
316
|
+
return { reason: 'not-generated', detail: 'code no generation produced carries no build' };
|
|
317
|
+
if (!generatorBuildSchema.safeParse(build).success)
|
|
318
|
+
return { reason: 'schema', detail: 'the stamp fails generatorBuildSchema' };
|
|
319
|
+
const bytes = new TextEncoder().encode(JSON.stringify(build)).length;
|
|
320
|
+
if (bytes > MAX_BUILD_STAMP_BYTES) {
|
|
321
|
+
return { reason: 'size', detail: `the stamp is ${bytes} bytes, over the ${MAX_BUILD_STAMP_BYTES}-byte bound` };
|
|
322
|
+
}
|
|
323
|
+
return undefined;
|
|
324
|
+
})();
|
|
325
|
+
if (drop === undefined)
|
|
326
|
+
return build;
|
|
327
|
+
if (!warnedBuildStampDrops.has(drop.reason)) {
|
|
328
|
+
warnedBuildStampDrops.add(drop.reason);
|
|
329
|
+
// eslint-disable-next-line no-console -- operator-visible degradation notice
|
|
330
|
+
console.warn(`[ggui] blueprint registry: blueprint_build_stamp_dropped — ${drop.detail}; ` +
|
|
331
|
+
'the row registers unstamped (its minting build reads as unknown) (logged once per process per reason)');
|
|
332
|
+
}
|
|
333
|
+
return undefined;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* ggui#1476 — the largest build stamp, serialized, a row may carry. The stamp
|
|
337
|
+
* rides every registry row's vector-store metadata, and a production vector
|
|
338
|
+
* backend bounds that metadata per row (a filterable-metadata budget of
|
|
339
|
+
* about 2 KB on one such backend, where a rejected write is swallowed by
|
|
340
|
+
* registration and reads as a silently empty cache). A real stamp — two
|
|
341
|
+
* 64-hex digests, a version and a mode — is about 250 bytes; the bound keeps
|
|
342
|
+
* an engine that reports many more digests from ever reaching that budget.
|
|
343
|
+
*/
|
|
344
|
+
export const MAX_BUILD_STAMP_BYTES = 1024;
|
|
245
345
|
function readScalarString(value) {
|
|
246
346
|
return typeof value === 'string' ? value : undefined;
|
|
247
347
|
}
|
|
@@ -333,6 +433,7 @@ function rowToBlueprint(key, metadata) {
|
|
|
333
433
|
const aestheticPreset = readAestheticPreset(metadata);
|
|
334
434
|
const directionDigest = readScalarString(metadata[METADATA_KEYS.directionDigest]);
|
|
335
435
|
const directionScope = directionDigest !== undefined ? readDirectionScope(metadata[METADATA_KEYS.directionScope]) : undefined;
|
|
436
|
+
const build = readGeneratorBuild(metadata, key);
|
|
336
437
|
return {
|
|
337
438
|
id: key,
|
|
338
439
|
kind: kindStr,
|
|
@@ -353,6 +454,7 @@ function rowToBlueprint(key, metadata) {
|
|
|
353
454
|
...(aestheticPreset !== undefined ? { aestheticPreset } : {}),
|
|
354
455
|
...(directionDigest !== undefined ? { directionDigest } : {}),
|
|
355
456
|
...(directionScope !== undefined ? { directionScope } : {}),
|
|
457
|
+
...(build !== undefined ? { build } : {}),
|
|
356
458
|
};
|
|
357
459
|
}
|
|
358
460
|
/**
|
|
@@ -436,8 +538,9 @@ export async function registerBlueprint(deps, scope, input, options = {}) {
|
|
|
436
538
|
if (existing)
|
|
437
539
|
return { ...existing, deduped: true };
|
|
438
540
|
// Dangling binding (id present, row gone) — self-heal: drop the stale
|
|
439
|
-
// binding and fall through to mint a fresh row.
|
|
440
|
-
|
|
541
|
+
// binding and fall through to mint a fresh row. Conditional on the stale
|
|
542
|
+
// id, so a registration that bound the key in between keeps it (#1603).
|
|
543
|
+
await deps.index.deleteId(scope, exactKey, existingId);
|
|
441
544
|
}
|
|
442
545
|
const id = options.mintId?.() ?? `bp_${randomUUID()}`;
|
|
443
546
|
const variance = input.variance ?? {};
|
|
@@ -452,6 +555,10 @@ export async function registerBlueprint(deps, scope, input, options = {}) {
|
|
|
452
555
|
codeStore !== undefined
|
|
453
556
|
? codeStore.hashOf(input.sourceCode)
|
|
454
557
|
: undefined;
|
|
558
|
+
// ggui#1280 / ggui#1476 — the minting engine's build, admitted once: the
|
|
559
|
+
// returned blueprint, the durable record and the vector-store row
|
|
560
|
+
// (`METADATA_KEYS.build`, via `blueprintToMetadata`) all carry it.
|
|
561
|
+
const build = admitGeneratorBuild(input.source, input.build);
|
|
455
562
|
const blueprint = {
|
|
456
563
|
id,
|
|
457
564
|
kind: input.kind,
|
|
@@ -464,6 +571,7 @@ export async function registerBlueprint(deps, scope, input, options = {}) {
|
|
|
464
571
|
createdAt,
|
|
465
572
|
hitCount: 0,
|
|
466
573
|
source: input.source,
|
|
574
|
+
...(build !== undefined ? { build } : {}),
|
|
467
575
|
...(input.installed === true ? { installed: true } : {}),
|
|
468
576
|
...(input.intentSource === 'fallback' ? { intentSource: 'fallback' } : {}),
|
|
469
577
|
...(input.judgedCanvases !== undefined ? { judgedCanvases: [...input.judgedCanvases] } : {}),
|
|
@@ -606,12 +714,16 @@ async function maybeEvictLowestHitBlueprint(deps, scope, kind, cap) {
|
|
|
606
714
|
if (victimKind !== undefined &&
|
|
607
715
|
victimContractKey !== undefined &&
|
|
608
716
|
victimVariantKey !== undefined) {
|
|
717
|
+
const victimExactKey = composeExactKey(victimKind, victimContractKey, victimVariantKey);
|
|
609
718
|
try {
|
|
610
|
-
|
|
719
|
+
// Conditional on the victim's own id: a key re-bound since to a
|
|
720
|
+
// different blueprint keeps its binding (#1603).
|
|
721
|
+
await deps.index.deleteId(scope, victimExactKey, victim.key);
|
|
611
722
|
}
|
|
612
|
-
catch {
|
|
613
|
-
// Best-effort — a failed index delete leaves a
|
|
614
|
-
//
|
|
723
|
+
catch (err) {
|
|
724
|
+
// Best-effort — a failed index delete leaves a dangling binding, which
|
|
725
|
+
// `findBlueprintExact` resolves to null; named so an operator sees it.
|
|
726
|
+
warnUnbindFailed(scope, victimExactKey, victim.key, err);
|
|
615
727
|
}
|
|
616
728
|
}
|
|
617
729
|
}
|
|
@@ -905,11 +1017,26 @@ export async function deleteBlueprint(deps, scope, id) {
|
|
|
905
1017
|
const existing = await findBlueprintByUuid(deps.vectorStore, scope, id);
|
|
906
1018
|
await deps.vectorStore.deleteVector(scope, id);
|
|
907
1019
|
if (existing) {
|
|
1020
|
+
const exactKey = composeExactKey(existing.kind, existing.contractKey, existing.variantKey);
|
|
908
1021
|
try {
|
|
909
|
-
|
|
1022
|
+
// Conditional on the deleted id: if the key has since been bound to a
|
|
1023
|
+
// different blueprint, that binding is the live design and stays (#1603).
|
|
1024
|
+
await deps.index.deleteId(scope, exactKey, id);
|
|
910
1025
|
}
|
|
911
|
-
catch {
|
|
912
|
-
// Best-effort — a dangling binding self-heals at the read site
|
|
1026
|
+
catch (err) {
|
|
1027
|
+
// Best-effort — a dangling binding self-heals at the read site; named
|
|
1028
|
+
// so an operator sees it.
|
|
1029
|
+
warnUnbindFailed(scope, exactKey, id, err);
|
|
913
1030
|
}
|
|
914
1031
|
}
|
|
915
1032
|
}
|
|
1033
|
+
/**
|
|
1034
|
+
* An index unbind failed after its row was deleted (#1603). Best-effort by
|
|
1035
|
+
* design: the dangling binding self-heals at the read site. Named, so an
|
|
1036
|
+
* operator sees it rather than a silent swallow.
|
|
1037
|
+
*/
|
|
1038
|
+
function warnUnbindFailed(scope, exactKey, blueprintId, err) {
|
|
1039
|
+
// eslint-disable-next-line no-console -- operator-visible degradation notice
|
|
1040
|
+
console.warn(`[ggui] blueprint registry: blueprint_index_unbind_failed — scope ${scope}, key ${exactKey}, ` +
|
|
1041
|
+
`blueprint ${blueprintId}; the binding dangles until a read self-heals it: ${err instanceof Error ? err.message : String(err)}`);
|
|
1042
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-seed-pool.d.ts","sourceRoot":"","sources":["../../src/renders/build-seed-pool.ts"],"names":[],"mappings":"AAYA,OAAO,EAAyB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAwB5D,MAAM,WAAW,oBAAoB;IACnC,gEAAgE;IAChE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"build-seed-pool.d.ts","sourceRoot":"","sources":["../../src/renders/build-seed-pool.ts"],"names":[],"mappings":"AAYA,OAAO,EAAyB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAwB5D,MAAM,WAAW,oBAAoB;IACnC,gEAAgE;IAChE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,aAAa,CAAC,CA6ExB"}
|
|
@@ -82,6 +82,12 @@ export async function buildSeedPool(source, options) {
|
|
|
82
82
|
// requires it) — an llm-minted record stays llm-sourced in
|
|
83
83
|
// the pool; importing never re-labels authorship.
|
|
84
84
|
source: record.source,
|
|
85
|
+
// ggui#1476 — the minting build travels with the artifact the same
|
|
86
|
+
// way. A stamp that fails `generatorBuildSchema` never reaches here:
|
|
87
|
+
// `fromPortableBlueprint` rejects the whole record above. The registry
|
|
88
|
+
// then admits what remains — a stamp on non-generated code, or one over
|
|
89
|
+
// the size bound, is dropped with a line and the row registers.
|
|
90
|
+
...(record.build !== undefined ? { build: record.build } : {}),
|
|
85
91
|
variance: record.variance,
|
|
86
92
|
},
|
|
87
93
|
// Seed pool is a fixed curated set — never evict.
|
|
@@ -166,8 +166,9 @@ export interface GguiConsumeHandlerDeps {
|
|
|
166
166
|
readonly logger?: ConsumeLogger;
|
|
167
167
|
/**
|
|
168
168
|
* Optional active-consumer awareness seam. When bound, the handler
|
|
169
|
-
* calls `enter(sessionId)`
|
|
170
|
-
* `exit(sessionId)` in
|
|
169
|
+
* calls `enter(sessionId)` once the caller is admitted to the session
|
|
170
|
+
* (never for a refused or missing one) and `exit(sessionId)` in
|
|
171
|
+
* `finally` so a concurrent
|
|
171
172
|
* `ggui_runtime_submit_action` append can query `hasActive` and
|
|
172
173
|
* surface `consumerPresent: false` to the iframe when no long-poll
|
|
173
174
|
* is registered for the targeted render — the iframe then emits
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consume.d.ts","sourceRoot":"","sources":["../../src/renders/consume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,EACL,KAAK,sBAAsB,EAE3B,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EAEtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,WAAW,EACjB,MAAM,aAAa,CAAC;AAuBrB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAgC,CAAC;AACnD,kEAAkE;AAClE,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,YAAY,CAAC,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,IAAI,EAAE;QACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACvC,QAAQ,CAAC,MAAM,EAAE;YACf,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;YAC5B,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;SACzB,CAAC;KACH,GAAG,IAAI,CAAC;CACV;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,IAAI,EAAE;QACjB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B,GAAG,IAAI,CAAC;CACV;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC5D;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;IACpD,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC;;sDAEkD;IAClD,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAC1C,wDAAwD;IACxD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C;;;;;;OAMG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC
|
|
1
|
+
{"version":3,"file":"consume.d.ts","sourceRoot":"","sources":["../../src/renders/consume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,EACL,KAAK,sBAAsB,EAE3B,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EAEtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,WAAW,EACjB,MAAM,aAAa,CAAC;AAuBrB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAgC,CAAC;AACnD,kEAAkE;AAClE,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,YAAY,CAAC,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,IAAI,EAAE;QACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACvC,QAAQ,CAAC,MAAM,EAAE;YACf,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;YAC5B,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;SACzB,CAAC;KACH,GAAG,IAAI,CAAC;CACV;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,IAAI,EAAE;QACjB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B,GAAG,IAAI,CAAC;CACV;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC5D;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;IACpD,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC;;sDAEkD;IAClD,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAC1C,wDAAwD;IACxD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C;;;;;;OAMG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IACzD;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,gBAAgB,EAAE,oBAAoB,CAAC;CAC3E;AAYD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAyOpE"}
|
package/dist/renders/consume.js
CHANGED
|
@@ -73,22 +73,31 @@ export function createGguiConsumeHandler(deps) {
|
|
|
73
73
|
outputSchema,
|
|
74
74
|
async handler(rawInput, ctx) {
|
|
75
75
|
const { sessionId, timeout = 0 } = z.object(inputSchema).parse(rawInput);
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
//
|
|
76
|
+
// Resolve render FIRST (ggui#1485). Cross-app (appId) + cross-user +
|
|
77
|
+
// missing all surface uniformly as session_not_found (don't leak
|
|
78
|
+
// whether the id exists for another app / another user), and a
|
|
79
|
+
// refused call must leave no trace on the session it named. Entering
|
|
80
|
+
// the active-consumer registry before this gate let another app's
|
|
81
|
+
// consume count as the session's consumer while its store read ran
|
|
82
|
+
// (a dispatch in that moment reported a consumer present), and its
|
|
83
|
+
// `exit` stamped the session's lastExitAt, which changed the grace
|
|
84
|
+
// wait of that session's dispatches for the next minute.
|
|
85
|
+
const stored = await deps.renderStore.get(sessionId);
|
|
86
|
+
if (!isVisibleToCaller(stored, ctx)) {
|
|
87
|
+
// `stored` is narrowed to StoredGguiSession past this guard.
|
|
88
|
+
throw new GguiSessionNotFoundError(sessionId);
|
|
89
|
+
}
|
|
90
|
+
// Register this long-poll on the active-consumer registry once the
|
|
91
|
+
// caller is admitted, so a concurrent `submit-action.ts` append
|
|
92
|
+
// observes `hasActive: true`. A dispatch landing during the store
|
|
93
|
+
// read above waits its own grace (`waitForConsumer`), which this
|
|
94
|
+
// `enter` wakes; with the default policy that wait is at least
|
|
95
|
+
// 150 ms, far longer than one store read, while a deployment's
|
|
96
|
+
// `consumerGraceMs` sets its own. `exit` is paired in `finally` below
|
|
97
|
+
// so every termination path after admission (success, timeout,
|
|
98
|
+
// error, abort) decrements the count exactly once.
|
|
82
99
|
deps.activeConsumerRegistry?.enter(sessionId);
|
|
83
100
|
try {
|
|
84
|
-
// Resolve render. Cross-app (appId) + cross-user + missing
|
|
85
|
-
// all surface uniformly as session_not_found (don't leak whether
|
|
86
|
-
// the id exists for another app / another user).
|
|
87
|
-
const stored = await deps.renderStore.get(sessionId);
|
|
88
|
-
if (!isVisibleToCaller(stored, ctx)) {
|
|
89
|
-
// `stored` is narrowed to StoredGguiSession past this guard.
|
|
90
|
-
throw new GguiSessionNotFoundError(sessionId);
|
|
91
|
-
}
|
|
92
101
|
// `timeout` is schema-bounded to [0, 25] (SPEC §7.3) —
|
|
93
102
|
// out-of-range values rejected INVALID_PARAMS before this line.
|
|
94
103
|
const deadline = Date.now() + timeout * 1000;
|
|
@@ -10,7 +10,8 @@ export declare function logCrossAppRefused(tool: string, sessionId: string, call
|
|
|
10
10
|
* ggui#1479 — the line a refusal leaves when a session's ownership could not
|
|
11
11
|
* be read at all (the store threw): the tool, the session, the caller's app
|
|
12
12
|
* and why. The call fails closed; this line is how an outage reads apart
|
|
13
|
-
* from a probe.
|
|
13
|
+
* from a probe. A caller with no logger of its own passes the store's error
|
|
14
|
+
* text, so the cause rides the same line (ggui#1514).
|
|
14
15
|
*/
|
|
15
|
-
export declare function logOwnershipUnverified(tool: string, sessionId: string, callerAppId: string, reason: 'read-failed'): void;
|
|
16
|
+
export declare function logOwnershipUnverified(tool: string, sessionId: string, callerAppId: string, reason: 'read-failed', error?: string): void;
|
|
16
17
|
//# sourceMappingURL=cross-app-refused.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cross-app-refused.d.ts","sourceRoot":"","sources":["../../src/renders/cross-app-refused.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAGjH;AAED
|
|
1
|
+
{"version":3,"file":"cross-app-refused.d.ts","sourceRoot":"","sources":["../../src/renders/cross-app-refused.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAGjH;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,aAAa,EACrB,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CAIN"}
|
|
@@ -13,9 +13,11 @@ export function logCrossAppRefused(tool, sessionId, callerAppId, ownerAppId) {
|
|
|
13
13
|
* ggui#1479 — the line a refusal leaves when a session's ownership could not
|
|
14
14
|
* be read at all (the store threw): the tool, the session, the caller's app
|
|
15
15
|
* and why. The call fails closed; this line is how an outage reads apart
|
|
16
|
-
* from a probe.
|
|
16
|
+
* from a probe. A caller with no logger of its own passes the store's error
|
|
17
|
+
* text, so the cause rides the same line (ggui#1514).
|
|
17
18
|
*/
|
|
18
|
-
export function logOwnershipUnverified(tool, sessionId, callerAppId, reason) {
|
|
19
|
+
export function logOwnershipUnverified(tool, sessionId, callerAppId, reason, error) {
|
|
20
|
+
const fields = error === undefined ? { tool, sessionId, callerAppId, reason } : { tool, sessionId, callerAppId, reason, error };
|
|
19
21
|
// eslint-disable-next-line no-console -- operator-visible structured refusal line; handlers carry no logger
|
|
20
|
-
console.warn(`[ggui] runtime_ownership_unverified ${JSON.stringify(
|
|
22
|
+
console.warn(`[ggui] runtime_ownership_unverified ${JSON.stringify(fields)}`);
|
|
21
23
|
}
|
|
@@ -95,6 +95,17 @@ export interface BlueprintLookupKeys {
|
|
|
95
95
|
readonly variantKey: string;
|
|
96
96
|
readonly exactKey: string;
|
|
97
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* ggui#1568 — a deployment's answer to "which rows may the semantic tier
|
|
100
|
+
* not offer for this request?" See {@link HandshakeDecisionAdapter.semanticExclusion}.
|
|
101
|
+
*/
|
|
102
|
+
export type SemanticExclusion = {
|
|
103
|
+
readonly kind: 'rows';
|
|
104
|
+
readonly keys: ReadonlySet<string>;
|
|
105
|
+
} | {
|
|
106
|
+
readonly kind: 'all';
|
|
107
|
+
readonly reason: string;
|
|
108
|
+
};
|
|
98
109
|
export interface HandshakeDecisionAdapter {
|
|
99
110
|
/**
|
|
100
111
|
* Resolve the LLM for this request — the find-similar judge AND the
|
|
@@ -141,6 +152,23 @@ export interface HandshakeDecisionAdapter {
|
|
|
141
152
|
* these from wherever it keeps a request's presentation facts.
|
|
142
153
|
*/
|
|
143
154
|
resolveRequestFit?(ctx: HandlerContext): Promise<RequestFitFacts | undefined> | RequestFitFacts | undefined;
|
|
155
|
+
/**
|
|
156
|
+
* ggui#1568 — rows the deployment reserves from the semantic tier for this
|
|
157
|
+
* request: rows that must be reached only by their exact key, never by
|
|
158
|
+
* similarity (an A/B test's arm, served only to the traffic assigned to
|
|
159
|
+
* it, is the first such row). Resolved once per decision and applied to
|
|
160
|
+
* every pool probe. Not asked when `reuseMode` is `'exact-only'`, since
|
|
161
|
+
* the semantic tier is already off.
|
|
162
|
+
*
|
|
163
|
+
* `{ kind: 'rows', keys }` excludes each row named by
|
|
164
|
+
* {@link semanticExclusionKey}. `{ kind: 'all', reason }` turns the
|
|
165
|
+
* semantic tier off for this request: the answer when the deployment
|
|
166
|
+
* cannot say which rows are reserved. It must never answer an empty set it
|
|
167
|
+
* has not read. A hook that throws an operational error is read as
|
|
168
|
+
* `'all'` and reported through `warn`. A programmer error (TypeError and
|
|
169
|
+
* kin) is rethrown, as for every hook here. Absent ⇒ nothing is reserved.
|
|
170
|
+
*/
|
|
171
|
+
readonly semanticExclusion?: (ctx: HandlerContext) => Promise<SemanticExclusion> | SemanticExclusion;
|
|
144
172
|
/**
|
|
145
173
|
* Optional deployment-specific pre-match, run BEFORE the find-similar
|
|
146
174
|
* probe so a curated / byte-exact hit wins over everything — e.g. a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decide-handshake.d.ts","sourceRoot":"","sources":["../../src/renders/decide-handshake.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAGH,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAGlB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAGL,KAAK,SAAS,EACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAGL,KAAK,oBAAoB,
|
|
1
|
+
{"version":3,"file":"decide-handshake.d.ts","sourceRoot":"","sources":["../../src/renders/decide-handshake.ts"],"names":[],"mappings":"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"}
|
|
@@ -88,7 +88,8 @@ function coverageHasGap(gap) {
|
|
|
88
88
|
gap.props.length > 0 ||
|
|
89
89
|
gap.context.length > 0 ||
|
|
90
90
|
gap.streams.length > 0 ||
|
|
91
|
-
gap.gadgets.length > 0
|
|
91
|
+
gap.gadgets.length > 0 ||
|
|
92
|
+
gap.actionMembers.length > 0);
|
|
92
93
|
}
|
|
93
94
|
/**
|
|
94
95
|
* Project a coverage gap into `severity:'warn'` validation findings — one
|
|
@@ -127,6 +128,19 @@ function coverageGapFindings(gap, request) {
|
|
|
127
128
|
push('context', 'contextSpec');
|
|
128
129
|
push('streams', 'streamSpec');
|
|
129
130
|
push('gadgets', 'gadgets');
|
|
131
|
+
// ggui#1428 — a shared action whose stored entry lacks a load-bearing
|
|
132
|
+
// member the draft declares: the served card will not behave that way.
|
|
133
|
+
for (const entry of gap.actionMembers) {
|
|
134
|
+
const dot = entry.lastIndexOf('.');
|
|
135
|
+
const name = entry.slice(0, dot);
|
|
136
|
+
const member = entry.slice(dot + 1);
|
|
137
|
+
findings.push({
|
|
138
|
+
code: COVERAGE_GAP_CODE,
|
|
139
|
+
severity: 'warn',
|
|
140
|
+
path: `actionSpec.${entry}`,
|
|
141
|
+
message: `the proposed cached UI declares action '${name}' without the \`${member}\` your draft declares, so the served card will not carry that behaviour. Default to ACCEPT (reuse-and-refine) — override only if the user or your flow depends on it.`,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
130
144
|
return findings;
|
|
131
145
|
}
|
|
132
146
|
/** Stable code for the VARIANCE_GAP warn finding on a variance-divergent reuse. */
|
|
@@ -402,6 +416,29 @@ export async function decideHandshake(adapter, input) {
|
|
|
402
416
|
// ggui#607 — resolve the reuse policy once; 'exact-only' threads
|
|
403
417
|
// disableSemantic into every pool probe below.
|
|
404
418
|
const reuseMode = adapter.reuseMode ? await adapter.reuseMode(ctx) : 'full';
|
|
419
|
+
// ggui#1568 — the reserved rows, resolved once. An operational failure
|
|
420
|
+
// reads as 'all': the tier stays off rather than offering a reserved row.
|
|
421
|
+
let exclusion;
|
|
422
|
+
if (reuseMode === 'full' && adapter.semanticExclusion) {
|
|
423
|
+
try {
|
|
424
|
+
exclusion = await adapter.semanticExclusion(ctx);
|
|
425
|
+
}
|
|
426
|
+
catch (err) {
|
|
427
|
+
if (!isOperationalError(err))
|
|
428
|
+
throw err;
|
|
429
|
+
exclusion = { kind: 'all', reason: `semanticExclusion threw: ${errMessage(err)}` };
|
|
430
|
+
}
|
|
431
|
+
if (exclusion.kind === 'all') {
|
|
432
|
+
adapter.warn?.(`[decideHandshake] semantic tier off for this request, the reserved rows are unknown: ${exclusion.reason}`);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
const probeOptions = reuseMode === 'exact-only'
|
|
436
|
+
? { disableSemantic: true }
|
|
437
|
+
: exclusion?.kind === 'all'
|
|
438
|
+
? { disableSemantic: true, disableSemanticCause: 'exclusion-unavailable' }
|
|
439
|
+
: exclusion?.kind === 'rows'
|
|
440
|
+
? { excludeFromSemantic: exclusion.keys }
|
|
441
|
+
: undefined;
|
|
405
442
|
// ggui#1427 — the request's fit facts, resolved once for every pool probe.
|
|
406
443
|
const requestFit = adapter.resolveRequestFit ? await adapter.resolveRequestFit(ctx) : undefined;
|
|
407
444
|
// The requesting agent's declared MCP tools (a set keyed by bare
|
|
@@ -442,9 +479,7 @@ export async function decideHandshake(adapter, input) {
|
|
|
442
479
|
contract: parsedDraft.data,
|
|
443
480
|
...(variance !== undefined ? { variance } : {}),
|
|
444
481
|
...(requestFit !== undefined ? { fit: requestFit } : {}),
|
|
445
|
-
}, ...(
|
|
446
|
-
? [{ disableSemantic: true }]
|
|
447
|
-
: []));
|
|
482
|
+
}, ...(probeOptions !== undefined ? [probeOptions] : []));
|
|
448
483
|
// Isolated in its OWN try/catch, separate from the outer
|
|
449
484
|
// pool-probe catch below: onBlueprintMatch's contract promises
|
|
450
485
|
// non-blocking observation, so a throwing observer must never
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type VectorStore } from '@ggui-ai/mcp-server-core';
|
|
2
|
-
import { type BlueprintSource, type DataContract, type BlueprintVariance } from '@ggui-ai/protocol';
|
|
2
|
+
import { type BlueprintSource, type DataContract, type BlueprintVariance, type GeneratorBuild } from '@ggui-ai/protocol';
|
|
3
3
|
export interface ExportableBlueprint {
|
|
4
4
|
readonly contract: DataContract;
|
|
5
5
|
readonly componentCode: string;
|
|
@@ -19,6 +19,13 @@ export interface ExportableBlueprint {
|
|
|
19
19
|
* artifactId fallback — useless prose for semantic matching.
|
|
20
20
|
*/
|
|
21
21
|
readonly intent?: string;
|
|
22
|
+
/**
|
|
23
|
+
* ggui#1476 — the minting engine's build, when the row carries one, so
|
|
24
|
+
* the export codec (`toPortableBlueprint`) ships the portable
|
|
25
|
+
* blueprint's `build`. Read through the registry's one reader of the
|
|
26
|
+
* key; an unreadable stored value is absent.
|
|
27
|
+
*/
|
|
28
|
+
readonly build?: GeneratorBuild;
|
|
22
29
|
}
|
|
23
30
|
/**
|
|
24
31
|
* Enumerate every reusable TEMPLATE blueprint stored under `scope` in a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export-registry.d.ts","sourceRoot":"","sources":["../../src/renders/export-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,iBAAiB,
|
|
1
|
+
{"version":3,"file":"export-registry.d.ts","sourceRoot":"","sources":["../../src/renders/export-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,+BAA+B,CACnD,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC,CAiDzC"}
|