@ggui-ai/mcp-server-handlers 0.25.0 → 0.27.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.
Files changed (101) hide show
  1. package/README.md +2 -2
  2. package/dist/credits/index.d.ts +2 -2
  3. package/dist/credits/index.d.ts.map +1 -1
  4. package/dist/credits/index.js +1 -1
  5. package/dist/credits/list-credit-transactions.d.ts +21 -7
  6. package/dist/credits/list-credit-transactions.d.ts.map +1 -1
  7. package/dist/credits/list-credit-transactions.js +12 -2
  8. package/dist/index.d.ts +2 -2
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +1 -1
  11. package/dist/ops-blueprint/cache-mirror.d.ts +41 -0
  12. package/dist/ops-blueprint/cache-mirror.d.ts.map +1 -0
  13. package/dist/ops-blueprint/cache-mirror.js +19 -0
  14. package/dist/ops-blueprint/delete.d.ts +18 -0
  15. package/dist/ops-blueprint/delete.d.ts.map +1 -1
  16. package/dist/ops-blueprint/delete.js +21 -2
  17. package/dist/ops-blueprint/errors.d.ts +11 -0
  18. package/dist/ops-blueprint/errors.d.ts.map +1 -1
  19. package/dist/ops-blueprint/errors.js +14 -0
  20. package/dist/ops-blueprint/generate.d.ts +1 -3
  21. package/dist/ops-blueprint/generate.d.ts.map +1 -1
  22. package/dist/ops-blueprint/generate.js +47 -58
  23. package/dist/ops-blueprint/list.d.ts.map +1 -1
  24. package/dist/ops-blueprint/list.js +1 -2
  25. package/dist/ops-blueprint/register.d.ts +17 -6
  26. package/dist/ops-blueprint/register.d.ts.map +1 -1
  27. package/dist/ops-blueprint/register.js +77 -45
  28. package/dist/ops-blueprint/update.d.ts +3 -2
  29. package/dist/ops-blueprint/update.d.ts.map +1 -1
  30. package/dist/ops-blueprint/update.js +4 -3
  31. package/dist/renders/blueprint-coverage.d.ts +23 -4
  32. package/dist/renders/blueprint-coverage.d.ts.map +1 -1
  33. package/dist/renders/blueprint-coverage.js +45 -5
  34. package/dist/renders/blueprint-durability.d.ts.map +1 -1
  35. package/dist/renders/blueprint-durability.js +5 -0
  36. package/dist/renders/blueprint-matcher.d.ts +28 -0
  37. package/dist/renders/blueprint-matcher.d.ts.map +1 -1
  38. package/dist/renders/blueprint-matcher.js +39 -7
  39. package/dist/renders/blueprint-registry.d.ts +52 -1
  40. package/dist/renders/blueprint-registry.d.ts.map +1 -1
  41. package/dist/renders/blueprint-registry.js +137 -10
  42. package/dist/renders/build-seed-pool.d.ts.map +1 -1
  43. package/dist/renders/build-seed-pool.js +6 -0
  44. package/dist/renders/consume.d.ts +3 -2
  45. package/dist/renders/consume.d.ts.map +1 -1
  46. package/dist/renders/consume.js +23 -14
  47. package/dist/renders/cross-app-refused.d.ts +3 -2
  48. package/dist/renders/cross-app-refused.d.ts.map +1 -1
  49. package/dist/renders/cross-app-refused.js +5 -3
  50. package/dist/renders/decide-handshake.d.ts +28 -0
  51. package/dist/renders/decide-handshake.d.ts.map +1 -1
  52. package/dist/renders/decide-handshake.js +39 -4
  53. package/dist/renders/export-registry.d.ts +8 -1
  54. package/dist/renders/export-registry.d.ts.map +1 -1
  55. package/dist/renders/export-registry.js +3 -0
  56. package/dist/renders/fits.d.ts.map +1 -1
  57. package/dist/renders/fits.js +23 -1
  58. package/dist/renders/handshake.d.ts +6 -42
  59. package/dist/renders/handshake.d.ts.map +1 -1
  60. package/dist/renders/handshake.js +1 -1
  61. package/dist/renders/index.d.ts +5 -4
  62. package/dist/renders/index.d.ts.map +1 -1
  63. package/dist/renders/index.js +4 -3
  64. package/dist/renders/installed-blueprints-provider.d.ts.map +1 -1
  65. package/dist/renders/installed-blueprints-provider.js +3 -1
  66. package/dist/renders/match-precision/pairs.d.ts +5 -4
  67. package/dist/renders/match-precision/pairs.d.ts.map +1 -1
  68. package/dist/renders/match-precision/topk-probe.js +13 -8
  69. package/dist/renders/record-committed-one-shot.d.ts +18 -3
  70. package/dist/renders/record-committed-one-shot.d.ts.map +1 -1
  71. package/dist/renders/record-committed-one-shot.js +14 -7
  72. package/dist/renders/refresh-ws-token.d.ts +9 -12
  73. package/dist/renders/refresh-ws-token.d.ts.map +1 -1
  74. package/dist/renders/refresh-ws-token.js +13 -10
  75. package/dist/renders/render-identity.d.ts +14 -5
  76. package/dist/renders/render-identity.d.ts.map +1 -1
  77. package/dist/renders/render-identity.js +25 -12
  78. package/dist/renders/render-read-gate.d.ts +27 -1
  79. package/dist/renders/render-read-gate.d.ts.map +1 -1
  80. package/dist/renders/render-read-gate.js +17 -5
  81. package/dist/renders/render.d.ts +36 -19
  82. package/dist/renders/render.d.ts.map +1 -1
  83. package/dist/renders/render.js +201 -17
  84. package/dist/renders/report-render-failure.d.ts +69 -0
  85. package/dist/renders/report-render-failure.d.ts.map +1 -0
  86. package/dist/renders/report-render-failure.js +83 -0
  87. package/dist/renders/runtime-pull.d.ts.map +1 -1
  88. package/dist/renders/runtime-pull.js +6 -0
  89. package/dist/renders/slice-meta-derivation.d.ts +8 -1
  90. package/dist/renders/slice-meta-derivation.d.ts.map +1 -1
  91. package/dist/renders/slice-meta-derivation.js +1 -0
  92. package/dist/renders/submit-action.d.ts +41 -71
  93. package/dist/renders/submit-action.d.ts.map +1 -1
  94. package/dist/renders/submit-action.js +225 -78
  95. package/dist/renders/sync-context.d.ts +3 -1
  96. package/dist/renders/sync-context.d.ts.map +1 -1
  97. package/dist/renders/sync-context.js +38 -8
  98. package/dist/types.d.ts +71 -1
  99. package/dist/types.d.ts.map +1 -1
  100. package/dist/types.js +32 -0
  101. package/package.json +8 -8
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @ggui-ai/mcp-server-handlers
2
2
 
3
- MCP tool handler logic for the **ggui protocol**.
3
+ MCP tool handler logic for the **GGUI protocol**.
4
4
 
5
- This package implements the actual behavior behind every ggui MCP tool — render
5
+ This package implements the actual behavior behind every GGUI MCP tool — render
6
6
  lifecycle, the contract handshake, UI emission, blueprint management, threads, app
7
7
  discovery, and the operator (`ggui_ops_*`) tools. The handlers are written purely
8
8
  over the seam interfaces in
@@ -25,6 +25,6 @@
25
25
  */
26
26
  export { createGetCreditBalanceHandler, } from './get-credit-balance.js';
27
27
  export type { CreditBalanceSource, CreditBalanceView, GetCreditBalanceDeps, GetCreditBalanceOutput, } from './get-credit-balance.js';
28
- export { createListCreditTransactionsHandler, } from './list-credit-transactions.js';
29
- export type { CreditTransactionSource, CreditTransactionView, ListCreditTransactionsDeps, ListCreditTransactionsOutput, } from './list-credit-transactions.js';
28
+ export { createListCreditTransactionsHandler, KNOWN_CREDIT_TRANSACTION_KINDS, } from './list-credit-transactions.js';
29
+ export type { CreditTransactionKind, CreditTransactionSource, CreditTransactionView, KnownCreditTransactionKind, ListCreditTransactionsDeps, ListCreditTransactionsOutput, } from './list-credit-transactions.js';
30
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/credits/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EACL,6BAA6B,GAC9B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,mCAAmC,GACpC,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/credits/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EACL,6BAA6B,GAC9B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,mCAAmC,EACnC,8BAA8B,GAC/B,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,EAC1B,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,+BAA+B,CAAC"}
@@ -24,4 +24,4 @@
24
24
  * side-channel — same posture as the blueprint family.
25
25
  */
26
26
  export { createGetCreditBalanceHandler, } from './get-credit-balance.js';
27
- export { createListCreditTransactionsHandler, } from './list-credit-transactions.js';
27
+ export { createListCreditTransactionsHandler, KNOWN_CREDIT_TRANSACTION_KINDS, } from './list-credit-transactions.js';
@@ -34,9 +34,28 @@ export interface CreditTransactionSource {
34
34
  nextCursor?: string;
35
35
  }>;
36
36
  }
37
+ /**
38
+ * The ledger kinds this package names (ggui#1532). The vocabulary is OPEN: a
39
+ * deployment's ledger may carry kinds not listed here, and a reader MUST accept
40
+ * one it does not know, keep it as named, and never read it as a render charge.
41
+ * Listing a kind here documents it; it is not the set of kinds that may appear.
42
+ */
43
+ export declare const KNOWN_CREDIT_TRANSACTION_KINDS: readonly ["free_credit", "render_charge", "topup", "refund"];
44
+ /** One of the kinds this package names. */
45
+ export type KnownCreditTransactionKind = (typeof KNOWN_CREDIT_TRANSACTION_KINDS)[number];
46
+ /**
47
+ * A ledger entry's kind: a known kind, or any other non-empty kind a
48
+ * deployment names. The `string & {}` arm keeps the set OPEN while editors
49
+ * still offer the known kinds and a `switch` can name them (it needs a default).
50
+ */
51
+ export type CreditTransactionKind = KnownCreditTransactionKind | (string & {});
37
52
  export interface CreditTransactionView {
38
53
  readonly transactionId: string;
39
- readonly kind: 'free_credit' | 'render_charge' | 'topup' | 'refund';
54
+ /**
55
+ * The entry's kind: one of {@link KNOWN_CREDIT_TRANSACTION_KINDS}, or a kind
56
+ * the deployment names that this package does not. Open vocabulary.
57
+ */
58
+ readonly kind: CreditTransactionKind;
40
59
  readonly deltaCents: number;
41
60
  readonly balanceAfterCents: number;
42
61
  readonly reason: string;
@@ -58,12 +77,7 @@ export declare function createListCreditTransactionsHandler(deps: ListCreditTran
58
77
  }, {
59
78
  transactions: z.ZodArray<z.ZodObject<{
60
79
  transactionId: z.ZodString;
61
- kind: z.ZodEnum<{
62
- free_credit: "free_credit";
63
- render_charge: "render_charge";
64
- topup: "topup";
65
- refund: "refund";
66
- }>;
80
+ kind: z.ZodString;
67
81
  deltaCents: z.ZodNumber;
68
82
  balanceAfterCents: z.ZodNumber;
69
83
  reason: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"list-credit-transactions.d.ts","sourceRoot":"","sources":["../../src/credits/list-credit-transactions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,IAAI,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;QACf,oCAAoC;QACpC,KAAK,EAAE,MAAM,CAAC;QACd,4EAA4E;QAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC;QACV,YAAY,EAAE,qBAAqB,EAAE,CAAC;QACtC,6CAA6C;QAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,eAAe,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,kBAAkB,EAAE,uBAAuB,CAAC;CACtD;AAyBD,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,YAAY,EAAE,qBAAqB,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,0BAA0B;IA5BhC,2BAA2B;;IAE3B,kEAAkE;;;;;;;;;;;;;;;;;IAgBlE,oFAAoF;;;;;GAgDrF"}
1
+ {"version":3,"file":"list-credit-transactions.d.ts","sourceRoot":"","sources":["../../src/credits/list-credit-transactions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,IAAI,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;QACf,oCAAoC;QACpC,KAAK,EAAE,MAAM,CAAC;QACd,4EAA4E;QAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC;QACV,YAAY,EAAE,qBAAqB,EAAE,CAAC;QACtC,6CAA6C;QAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;CACJ;AAED;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,8DAA+D,CAAC;AAE3G,2CAA2C;AAC3C,MAAM,MAAM,0BAA0B,GAAG,CAAC,OAAO,8BAA8B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzF;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,0BAA0B,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE/E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,kBAAkB,EAAE,uBAAuB,CAAC;CACtD;AA8BD,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,YAAY,EAAE,qBAAqB,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,0BAA0B;IAjChC,2BAA2B;;IAE3B,kEAAkE;;;;;;;;;;;;IAqBlE,oFAAoF;;;;;GAgDrF"}
@@ -17,6 +17,13 @@
17
17
  */
18
18
  import { z } from 'zod';
19
19
  import { defineHandler } from '../types.js';
20
+ /**
21
+ * The ledger kinds this package names (ggui#1532). The vocabulary is OPEN: a
22
+ * deployment's ledger may carry kinds not listed here, and a reader MUST accept
23
+ * one it does not know, keep it as named, and never read it as a render charge.
24
+ * Listing a kind here documents it; it is not the set of kinds that may appear.
25
+ */
26
+ export const KNOWN_CREDIT_TRANSACTION_KINDS = ['free_credit', 'render_charge', 'topup', 'refund'];
20
27
  const inputSchema = {
21
28
  /** Default 20. Cap 100. */
22
29
  limit: z.number().int().min(1).max(100).optional(),
@@ -26,7 +33,10 @@ const inputSchema = {
26
33
  const outputSchema = {
27
34
  transactions: z.array(z.object({
28
35
  transactionId: z.string(),
29
- kind: z.enum(['free_credit', 'render_charge', 'topup', 'refund']),
36
+ kind: z
37
+ .string()
38
+ .min(1)
39
+ .describe("The ledger entry's kind, an open vocabulary. Known kinds: 'free_credit', 'render_charge', 'topup', 'refund'. A deployment may add others: accept a kind you do not know, keep it as named, and never read it as a render charge."),
30
40
  deltaCents: z.number().int(),
31
41
  balanceAfterCents: z.number().int(),
32
42
  reason: z.string(),
@@ -41,7 +51,7 @@ export function createListCreditTransactionsHandler(deps) {
41
51
  name: 'ggui_ops_list_credit_transactions',
42
52
  title: 'List credit transactions',
43
53
  audience: ['ops'],
44
- description: "Returns the calling user's credit transaction ledger, newest-first. Each row carries kind ('free_credit' | 'render_charge' | 'topup' | 'refund'), deltaCents (signed — positive for grants/topups, negative for charges), balanceAfterCents (snapshot at time of write), reason (human-readable), and optional relatedSessionId for render_charge rows. Default limit 20, cap 100; pass `cursor` from the previous response's `nextCursor` for paging.",
54
+ description: "Returns the calling user's credit transaction ledger, newest-first. Each row carries kind (an open vocabulary: known kinds are 'free_credit', 'render_charge', 'topup' and 'refund', and a deployment may add others; treat an unknown kind as a ledger entry of that name, never as a render charge), deltaCents (signed — positive for grants/topups, negative for charges), balanceAfterCents (snapshot at time of write), reason (human-readable), and optional relatedSessionId for render_charge rows. Default limit 20, cap 100; pass `cursor` from the previous response's `nextCursor` for paging.",
45
55
  inputSchema,
46
56
  outputSchema,
47
57
  // No `allowedFor` — same toolset on every deployment kind. Callers
package/dist/index.d.ts CHANGED
@@ -15,8 +15,8 @@
15
15
  */
16
16
  export * from "./blueprints/index.js";
17
17
  export * from "./renders/index.js";
18
- export { AuthRequiredError, HANDLER_FAILURE_MARKER, defineHandler, handlerFailure, isHandlerFailure, } from "./types.js";
19
- export type { AudienceTag, EnvelopedHandlerDefinition, EnvelopeFor, HandlerContext, HandlerDefinition, HandlerFailure, ShapeOutput, SharedHandler, SharedHandlerOutputBound, SharedHandlerOutputData, SharedHandlerResult, } from "./types.js";
18
+ export { AuthRequiredError, HANDLER_FAILURE_MARKER, createSessionRowReads, defineHandler, handlerFailure, isHandlerFailure, readSessionRow, viewProofUseFor, } from "./types.js";
19
+ export type { AudienceTag, EnvelopedHandlerDefinition, EnvelopeFor, HandlerContext, HandlerDefinition, HandlerFailure, SessionRowReads, ShapeOutput, SharedHandler, SharedHandlerOutputBound, SharedHandlerOutputData, SharedHandlerResult, ViewProofDeclaration, ViewProofUse, } from "./types.js";
20
20
  export * from "./threads/index.js";
21
21
  export * from "./credits/index.js";
22
22
  export * from "./app-discovery/index.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,WAAW,EACX,0BAA0B,EAC1B,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,aAAa,EACb,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAIpB,cAAc,oBAAoB,CAAC;AAInC,cAAc,oBAAoB,CAAC;AAInC,cAAc,0BAA0B,CAAC;AAIzC,cAAc,0BAA0B,CAAC;AAKzC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,WAAW,EACX,0BAA0B,EAC1B,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,WAAW,EACX,aAAa,EACb,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,GACb,MAAM,YAAY,CAAC;AAIpB,cAAc,oBAAoB,CAAC;AAInC,cAAc,oBAAoB,CAAC;AAInC,cAAc,0BAA0B,CAAC;AAIzC,cAAc,0BAA0B,CAAC;AAKzC,cAAc,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@
15
15
  */
16
16
  export * from "./blueprints/index.js";
17
17
  export * from "./renders/index.js";
18
- export { AuthRequiredError, HANDLER_FAILURE_MARKER, defineHandler, handlerFailure, isHandlerFailure, } from "./types.js";
18
+ export { AuthRequiredError, HANDLER_FAILURE_MARKER, createSessionRowReads, defineHandler, handlerFailure, isHandlerFailure, readSessionRow, viewProofUseFor, } from "./types.js";
19
19
  // Persistent-chat handler family — thread storage and message
20
20
  // history MCP tools. Thin over @ggui-ai/mcp-server-core ThreadStore.
21
21
  // Available under `@ggui-ai/mcp-server-handlers/threads` subpath too.
@@ -0,0 +1,41 @@
1
+ /**
2
+ * How an ops writer mirrors its durable row into the cache registry
3
+ * (ggui#1497): under ONE id.
4
+ *
5
+ * `ggui_ops_register_blueprint` (with `createRegisterGeneratedBlueprint`,
6
+ * which shares its core) and `ggui_ops_generate_blueprint` each put the
7
+ * durable row first, then mirror it into the cache so the exact-key probe
8
+ * finds it. The mirror used to mint an id of its own, so a render served
9
+ * from that cache row recorded an id the writer's store never held. The
10
+ * mirror now takes the writer's id (`mintId`), and what else it writes
11
+ * depends on where re-mint reads:
12
+ *
13
+ * - The mirror's registry writes through to a durable store OTHER than the
14
+ * writer's (a server that keeps its re-mint store apart from the ops
15
+ * store): the full write-through runs, now under the shared id, so the
16
+ * store re-mint reads holds the row and the compiled body under the id
17
+ * the cache serves.
18
+ * - It writes through to the writer's OWN store: the row is already there
19
+ * under this id, and the store refuses a second put of it, so the mirror
20
+ * skips the row but still puts the compiled body into its code store,
21
+ * where re-mint reads it.
22
+ * - No durable store (a code store at most): nothing more is written; the
23
+ * writer's own store and body are what re-mint reads.
24
+ *
25
+ * The authored source still reaches a bound code store in every case
26
+ * (ggui#1493). A dedup is unchanged: an exact key already bound returns its
27
+ * existing id, and nothing more is written for it.
28
+ */
29
+ import type { BlueprintStore } from "@ggui-ai/mcp-server-core";
30
+ import { type BlueprintRegistryDeps, type RegisterBlueprintInput, type RegisteredBlueprint } from "../renders/blueprint-registry.js";
31
+ export declare function mirrorIntoCache(args: {
32
+ /** The cache registry the writer mirrors into. */
33
+ readonly cacheRegistry: BlueprintRegistryDeps;
34
+ /** The store the writer already put the durable row in, under `blueprintId`. */
35
+ readonly writerStore: BlueprintStore;
36
+ readonly appId: string;
37
+ /** The writer's durable row id: the cache row takes it. */
38
+ readonly blueprintId: string;
39
+ readonly input: RegisterBlueprintInput;
40
+ }): Promise<RegisteredBlueprint>;
41
+ //# sourceMappingURL=cache-mirror.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-mirror.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/cache-mirror.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACzB,MAAM,kCAAkC,CAAC;AAE1C,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,kDAAkD;IAClD,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;IAC9C,gFAAgF;IAChF,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,sBAAsB,CAAC;CACxC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAkB/B"}
@@ -0,0 +1,19 @@
1
+ import { registerBlueprint, } from "../renders/blueprint-registry.js";
2
+ export async function mirrorIntoCache(args) {
3
+ const durability = args.cacheRegistry.durability;
4
+ const sharesWriterStore = durability?.blueprintStore !== undefined && durability.blueprintStore === args.writerStore;
5
+ const deps = sharesWriterStore
6
+ ? {
7
+ ...args.cacheRegistry,
8
+ durability: durability.codeStore !== undefined ? { codeStore: durability.codeStore } : {},
9
+ }
10
+ : args.cacheRegistry;
11
+ const registered = await registerBlueprint(deps, args.appId, args.input, {
12
+ mintId: () => args.blueprintId,
13
+ });
14
+ const codeStore = durability?.codeStore;
15
+ if (sharesWriterStore && !registered.deduped && codeStore !== undefined && args.input.componentCode.length > 0) {
16
+ await codeStore.put(codeStore.hashOf(args.input.componentCode), args.input.componentCode);
17
+ }
18
+ return registered;
19
+ }
@@ -18,12 +18,23 @@
18
18
  * a foreign `appId` input the authorizer denies surfaces the denial
19
19
  * error before the row lookup ever runs.
20
20
  *
21
+ * ## Out of reuse (ggui#1541)
22
+ *
23
+ * `ggui_ops_register_blueprint` and `ggui_ops_generate_blueprint` write a
24
+ * blueprint twice: the durable row, and a mirror in the cache registry, the
25
+ * store the handshake's exact-key probe matches from. So a delete removes
26
+ * both, the cache row first: a cache delete that fails fails the call
27
+ * before the durable row goes, and a retry completes it. An id whose
28
+ * durable row is already gone still has its cache row cleared in the
29
+ * caller's own app scope, which heals a row an earlier delete left behind.
30
+ *
21
31
  * ## Audience
22
32
  *
23
33
  * `['ops']` — served on `/control`. NOT visible to agents on `/mcp`.
24
34
  */
25
35
  import { z } from 'zod';
26
36
  import type { BlueprintStore } from '@ggui-ai/mcp-server-core';
37
+ import { type BlueprintRegistryDeps } from '../renders/blueprint-registry.js';
27
38
  import { type OpsBlueprintAppAuthorizer } from './app-access.js';
28
39
  /**
29
40
  * Deps for `ggui_ops_delete_blueprint`.
@@ -45,6 +56,13 @@ export interface GguiOpsDeleteBlueprintDeps {
45
56
  * the target row belongs to a different app (no existence leak).
46
57
  */
47
58
  readonly authorizeAppAccess?: OpsBlueprintAppAuthorizer;
59
+ /**
60
+ * The cache registry the writers mirror into (ggui#1541): the SAME one
61
+ * `ggui_ops_register_blueprint` and `ggui_ops_generate_blueprint` are
62
+ * given. When bound, a delete removes the blueprint's cache row (its
63
+ * vector and its exact-key binding) so the handshake stops reusing it.
64
+ */
65
+ readonly cacheRegistry?: Pick<BlueprintRegistryDeps, 'vectorStore' | 'index'>;
48
66
  }
49
67
  export declare function createGguiOpsDeleteBlueprintHandler(deps: GguiOpsDeleteBlueprintDeps): import("../types.js").SharedHandler<{
50
68
  appId: z.ZodOptional<z.ZodString>;
@@ -1 +1 @@
1
- {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/delete.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAOxF;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;CACzD;AAED,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,0BAA0B;;;;;;;GAwCjC"}
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/delete.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAmB,KAAK,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAE/F,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAOxF;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;IACxD;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,qBAAqB,EAAE,aAAa,GAAG,OAAO,CAAC,CAAC;CAC/E;AAED,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,0BAA0B;;;;;;;GA8CjC"}
@@ -18,12 +18,23 @@
18
18
  * a foreign `appId` input the authorizer denies surfaces the denial
19
19
  * error before the row lookup ever runs.
20
20
  *
21
+ * ## Out of reuse (ggui#1541)
22
+ *
23
+ * `ggui_ops_register_blueprint` and `ggui_ops_generate_blueprint` write a
24
+ * blueprint twice: the durable row, and a mirror in the cache registry, the
25
+ * store the handshake's exact-key probe matches from. So a delete removes
26
+ * both, the cache row first: a cache delete that fails fails the call
27
+ * before the durable row goes, and a retry completes it. An id whose
28
+ * durable row is already gone still has its cache row cleared in the
29
+ * caller's own app scope, which heals a row an earlier delete left behind.
30
+ *
21
31
  * ## Audience
22
32
  *
23
33
  * `['ops']` — served on `/control`. NOT visible to agents on `/mcp`.
24
34
  */
25
35
  import { z } from 'zod';
26
36
  import { opsDeleteBlueprintInputSchema, } from '@ggui-ai/protocol';
37
+ import { deleteBlueprint } from '../renders/blueprint-registry.js';
27
38
  import { defineHandler } from '../types.js';
28
39
  import { resolveEffectiveAppId } from './app-access.js';
29
40
  const opsInputSchema = opsDeleteBlueprintInputSchema.shape;
@@ -35,7 +46,7 @@ export function createGguiOpsDeleteBlueprintHandler(deps) {
35
46
  name: 'ggui_ops_delete_blueprint',
36
47
  title: 'Delete blueprint',
37
48
  audience: ['ops'],
38
- description: "Remove a blueprint row by id. Idempotent — a second delete for the same id returns `{deleted: true}` without throwing. Cross-app probes return the same shape (no existence leak across apps). Mirrors `BlueprintStore.delete`'s no-throw contract. App-scoped variant curation for an app you operate — distinct from the personal saved-blueprint library (the _my_ tools).",
49
+ description: "Remove a blueprint by id: its durable row, and its entry in the cache the handshake reuses blueprints from, so it is no longer reused. Idempotent — a second delete for the same id returns `{deleted: true}` without throwing. Cross-app probes return the same shape (no existence leak across apps). Mirrors `BlueprintStore.delete`'s no-throw contract. App-scoped variant curation for an app you operate — distinct from the personal saved-blueprint library (the _my_ tools).",
39
50
  inputSchema: opsInputSchema,
40
51
  outputSchema: opsOutputSchema,
41
52
  async handler(rawInput, ctx) {
@@ -48,7 +59,11 @@ export function createGguiOpsDeleteBlueprintHandler(deps) {
48
59
  });
49
60
  const existing = await deps.blueprintStore.get(parsed.blueprintId);
50
61
  if (existing === null) {
51
- // Unknown id — idempotent. Return the success shape.
62
+ // Unknown id — idempotent. Its cache row may outlive it (an earlier
63
+ // delete removed the durable row only): clear it in the caller's
64
+ // own app scope, which says nothing about any other app.
65
+ if (deps.cacheRegistry)
66
+ await deleteBlueprint(deps.cacheRegistry, appId, parsed.blueprintId);
52
67
  return { deleted: true };
53
68
  }
54
69
  if (existing.appId !== appId) {
@@ -58,6 +73,10 @@ export function createGguiOpsDeleteBlueprintHandler(deps) {
58
73
  // leak across app boundaries.
59
74
  return { deleted: true };
60
75
  }
76
+ // Out of reuse first, then the durable row: a cache delete that fails
77
+ // fails the call with the durable row intact, so a retry completes it.
78
+ if (deps.cacheRegistry)
79
+ await deleteBlueprint(deps.cacheRegistry, appId, parsed.blueprintId);
61
80
  await deps.blueprintStore.delete(parsed.blueprintId);
62
81
  return { deleted: true };
63
82
  },
@@ -57,6 +57,17 @@ export declare class DirectionScopeWithoutDigestError extends Error {
57
57
  readonly code: "direction_scope_without_digest";
58
58
  constructor();
59
59
  }
60
+ /**
61
+ * ggui#1570 — a registration named a parent (`clonedFrom`) this registration
62
+ * cannot record: an empty id, the row's own id, or an id that is not a row of
63
+ * the registering app in the durable store. One answer for all of them, and
64
+ * the same text for a missing row and another app's, so the refusal says
65
+ * nothing about another app's rows. Refused before anything is persisted.
66
+ */
67
+ export declare class ClonedFromRefusedError extends Error {
68
+ readonly code: "cloned_from_refused";
69
+ constructor(clonedFrom: string);
70
+ }
60
71
  export declare class MissingCredentialsError extends Error {
61
72
  readonly code: "missing_credentials";
62
73
  constructor(message?: string);
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBACnC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,MAAM,EAAE;CAM7D;AAED;;;;;;;;;;GAUG;AACH;;;;;;;GAOG;AACH,qBAAa,gCAAiC,SAAQ,KAAK;IACzD,QAAQ,CAAC,IAAI,EAAG,gCAAgC,CAAU;;CAO3D;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBACnC,OAAO,CAAC,EAAE,MAAM;CAO7B;AAED;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,EAAG,mBAAmB,CAAU;IAC7C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;gBACZ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAK5C"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBACnC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,MAAM,EAAE;CAM7D;AAED;;;;;;;;;;GAUG;AACH;;;;;;;GAOG;AACH,qBAAa,gCAAiC,SAAQ,KAAK;IACzD,QAAQ,CAAC,IAAI,EAAG,gCAAgC,CAAU;;CAO3D;AAED;;;;;;GAMG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBACnC,UAAU,EAAE,MAAM;CAM/B;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBACnC,OAAO,CAAC,EAAE,MAAM;CAO7B;AAED;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,EAAG,mBAAmB,CAAU;IAC7C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;gBACZ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAK5C"}
@@ -63,6 +63,20 @@ export class DirectionScopeWithoutDigestError extends Error {
63
63
  this.name = "DirectionScopeWithoutDigestError";
64
64
  }
65
65
  }
66
+ /**
67
+ * ggui#1570 — a registration named a parent (`clonedFrom`) this registration
68
+ * cannot record: an empty id, the row's own id, or an id that is not a row of
69
+ * the registering app in the durable store. One answer for all of them, and
70
+ * the same text for a missing row and another app's, so the refusal says
71
+ * nothing about another app's rows. Refused before anything is persisted.
72
+ */
73
+ export class ClonedFromRefusedError extends Error {
74
+ code = "cloned_from_refused";
75
+ constructor(clonedFrom) {
76
+ super(`cloned_from_refused: clonedFrom "${clonedFrom}" is not another row of this app — a copy names a row of its own app, other than itself, that the store holds.`);
77
+ this.name = "ClonedFromRefusedError";
78
+ }
79
+ }
66
80
  export class MissingCredentialsError extends Error {
67
81
  code = "missing_credentials";
68
82
  constructor(message) {
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Operator UX entry point. Dispatches through the bound
5
5
  * {@link GeneratorRegistry} to mint a blueprint variant with
6
- * operator-authored variance tags + optional default-pin.
6
+ * operator-authored variance tags + an optional operator-default mark.
7
7
  *
8
8
  * ## Behavior
9
9
  *
@@ -177,7 +177,6 @@ export declare function createGguiOpsGenerateBlueprintHandler(deps: GguiOpsGener
177
177
  }, {
178
178
  blueprintId: z.ZodString;
179
179
  codeHash: z.ZodOptional<z.ZodString>;
180
- validatorScore: z.ZodOptional<z.ZodNumber>;
181
180
  source: z.ZodObject<{
182
181
  kind: z.ZodLiteral<"llm">;
183
182
  generator: z.ZodString;
@@ -187,6 +186,5 @@ export declare function createGguiOpsGenerateBlueprintHandler(deps: GguiOpsGener
187
186
  blueprintId: string;
188
187
  source: import("@ggui-ai/protocol").LlmBlueprintSource;
189
188
  codeHash?: string | undefined;
190
- validatorScore?: number | undefined;
191
189
  }>;
192
190
  //# sourceMappingURL=generate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,aAAa,EAGd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,YAAY,EAIlB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAsBxF;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;IAC1E;;;;;;;OAOG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,CACnB,GAAG,EAAE,cAAc,KAChB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,GAAG,qBAAqB,GAAG,IAAI,CAAC;IAC1E;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;IAC/B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,qBAAqB,CAAC;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,MAAM,CAAC;IACxC;;;;;;;OAOG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;CACzD;AA2CD,wBAAgB,qCAAqC,CACnD,IAAI,EAAE,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;GA0SnC"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,aAAa,EAGd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,YAAY,EAIlB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAqBxF;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;IAC1E;;;;;;;OAOG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,CACnB,GAAG,EAAE,cAAc,KAChB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,GAAG,qBAAqB,GAAG,IAAI,CAAC;IAC1E;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;IAC/B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,qBAAqB,CAAC;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,MAAM,CAAC;IACxC;;;;;;;OAOG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;CACzD;AA0BD,wBAAgB,qCAAqC,CACnD,IAAI,EAAE,4BAA4B;;;;;;;;;;;;;;;;;;;;;;GAkTnC"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Operator UX entry point. Dispatches through the bound
5
5
  * {@link GeneratorRegistry} to mint a blueprint variant with
6
- * operator-authored variance tags + optional default-pin.
6
+ * operator-authored variance tags + an optional operator-default mark.
7
7
  *
8
8
  * ## Behavior
9
9
  *
@@ -52,7 +52,8 @@ import { createHash, randomUUID } from "node:crypto";
52
52
  import { z } from "zod";
53
53
  import { assertContractNoRetiredFields } from "../renders/assert-contract-no-retired-fields.js";
54
54
  import { assertGadgetsRegistered } from "../renders/assert-gadgets.js";
55
- import { registerBlueprint, } from "../renders/index.js";
55
+ import { admitGeneratorBuild, } from "../renders/index.js";
56
+ import { mirrorIntoCache } from "./cache-mirror.js";
56
57
  import { defineHandler } from "../types.js";
57
58
  import { resolveEffectiveAppId } from "./app-access.js";
58
59
  import { GenerationFailedError, GeneratorNotFoundError, MissingCredentialsError, } from "./errors.js";
@@ -61,7 +62,6 @@ const opsInputSchema = opsGenerateBlueprintInputSchema.shape;
61
62
  const opsOutputSchema = z.object({
62
63
  blueprintId: z.string().min(1),
63
64
  codeHash: z.string().optional(),
64
- validatorScore: z.number().min(0).max(1).optional(),
65
65
  source: z
66
66
  .object({
67
67
  kind: z.literal("llm"),
@@ -70,26 +70,6 @@ const opsOutputSchema = z.object({
70
70
  })
71
71
  .strict(),
72
72
  }).shape;
73
- /**
74
- * Read the optional `validatorScore` carried on
75
- * {@link GenerationMetadata} by the advanced generator, which does
76
- * not yet have an explicit field on the canonical interface. Until
77
- * that lands the score arrives as a structural pass-through on
78
- * `metadata` — the read is type-guarded here so the cast is
79
- * confined to one place and the call sites stay clean.
80
- */
81
- function readValidatorScore(metadata) {
82
- if (!metadata || typeof metadata !== "object")
83
- return undefined;
84
- const candidate = metadata.validatorScore;
85
- if (typeof candidate !== "number")
86
- return undefined;
87
- if (!Number.isFinite(candidate))
88
- return undefined;
89
- if (candidate < 0 || candidate > 1)
90
- return undefined;
91
- return candidate;
92
- }
93
73
  /**
94
74
  * Resolve which generator to dispatch. Throws {@link GeneratorNotFoundError}
95
75
  * with a clear "did you mean…" payload when the slug is unknown.
@@ -117,7 +97,7 @@ export function createGguiOpsGenerateBlueprintHandler(deps) {
117
97
  name: "ggui_ops_generate_blueprint",
118
98
  title: "Generate blueprint",
119
99
  audience: ["ops"],
120
- description: "Author a new blueprint variant for the target app (the caller's bound app by default, or an explicitly named app the deployment's authorization policy accepts). Dispatches through the registry's selected generator (defaults to `registry.defaultGenerator()` when the slug is omitted) and persists the resulting code body + metadata against a fresh `blueprintId`. Optionally pins the new blueprint as the operator default for its `(appId, contractHash)` group. Persona tags are normalized (lowercase + trim); near-duplicates surface a warning via telemetry. Returns the new id + content-hash + validator score + the stamped provenance (`source`, llm arm: engine generator slug + model, from the engine's own metadata stamp) — code body lives in the bound store, fetched via render's fast-path on cache hit. App-scoped variant curation for an app you operate — distinct from the personal saved-blueprint library (the _my_ tools).",
100
+ description: "Author a new blueprint variant for the target app (the caller's bound app by default, or an explicitly named app the deployment's authorization policy accepts). Dispatches through the registry's selected generator (defaults to `registry.defaultGenerator()` when the slug is omitted) and persists the resulting code body + metadata against a fresh `blueprintId`. Optionally marks the new blueprint as the operator default for its `(appId, contractHash)` group (the mark orders blueprint listings; it does not decide which blueprint serves a render). Persona tags are normalized (lowercase + trim); near-duplicates surface a warning via telemetry. Returns the new id + content-hash + validator score + the stamped provenance (`source`, llm arm: engine generator slug + model, from the engine's own metadata stamp) — code body lives in the bound store, fetched via render's fast-path on cache hit. App-scoped variant curation for an app you operate — distinct from the personal saved-blueprint library (the _my_ tools).",
121
101
  inputSchema: opsInputSchema,
122
102
  outputSchema: opsOutputSchema,
123
103
  async handler(rawInput, ctx) {
@@ -255,12 +235,6 @@ export function createGguiOpsGenerateBlueprintHandler(deps) {
255
235
  // bytes. A 32-hex prefix here (ggui#1287) was refused by every
256
236
  // conforming code store.
257
237
  const codeHash = createHash("sha256").update(componentCode).digest("hex");
258
- // The advanced generator tunnels `validatorScore` through
259
- // `metadata` until the UiGenerator interface widens to carry
260
- // it explicitly. Read it via the typed helper so the default
261
- // generator (which never sets it) and the advanced generator
262
- // (which does) both round-trip cleanly.
263
- const validatorScore = readValidatorScore(result.metadata);
264
238
  // Engine-GENERATED code: provenance is the llm arm, stamped from
265
239
  // the engine's own metadata claim — the SAME values the cache-
266
240
  // registry mirror below records, so the two stores can never
@@ -270,6 +244,13 @@ export function createGguiOpsGenerateBlueprintHandler(deps) {
270
244
  generator: result.metadata.generator,
271
245
  model: result.metadata.model,
272
246
  };
247
+ // ggui#1280 — the minting engine's build, through the registry's one
248
+ // admission rule. The durable row below carries it. The cache mirror's
249
+ // registration receives the same value: it rides that registry's
250
+ // vector-store row (ggui#1476) and, when the mirror writes through to a
251
+ // separate durable store, the row it writes there under this same id
252
+ // (ggui#1497, see `mirrorIntoCache`).
253
+ const build = admitGeneratorBuild(source, result.metadata.build);
273
254
  const blueprintId = mintBlueprintId();
274
255
  const blueprint = {
275
256
  blueprintId,
@@ -286,7 +267,7 @@ export function createGguiOpsGenerateBlueprintHandler(deps) {
286
267
  createdAt: now(),
287
268
  createdBy: "operator",
288
269
  contract,
289
- ...(validatorScore !== undefined ? { validatorScore } : {}),
270
+ ...(build !== undefined ? { build } : {}),
290
271
  };
291
272
  await deps.blueprintStore.put(blueprint);
292
273
  if (deps.putCode) {
@@ -305,31 +286,40 @@ export function createGguiOpsGenerateBlueprintHandler(deps) {
305
286
  parsed.seedPrompt ??
306
287
  normalizedPersona ??
307
288
  `operator-authored blueprint (${blueprintId})`;
308
- await registerBlueprint(deps.cacheRegistry, appId, {
309
- kind: "template",
310
- contract,
311
- intent: intentForCache,
312
- // ggui#1275 — an explicit intent or a seed prompt states the
313
- // UI's task; a persona or the placeholder is a stand-in the
314
- // matcher's judge never sees.
315
- intentSource: parsed.intent !== undefined || parsed.seedPrompt !== undefined
316
- ? "authored"
317
- : "fallback",
318
- componentCode,
319
- // The cache row MUST carry the same variance as the MVB
320
- // row: `registerBlueprint` keys the exact-lookup on
321
- // `variantKey(variance)`, so omitting it here filed every
322
- // operator-authored variant under the default-variant
323
- // sentinel — invisible to any request that asks for the
324
- // persona it was minted for.
325
- variance: blueprint.variance,
326
- // Operator-DISPATCHED but engine-GENERATED: the code came
327
- // out of `generator.generate(...)`, so provenance is the
328
- // llm arm — the same `source` stamped on the MVB row above.
329
- // The two axes disagree here on purpose, which is exactly
330
- // why `createdBy` cannot be derived from `source`.
331
- source,
332
- createdBy: "operator",
289
+ // ggui#1497 — ONE id per generation: the cache row serves the
290
+ // durable row's id (see `mirrorIntoCache` for what else it writes).
291
+ await mirrorIntoCache({
292
+ cacheRegistry: deps.cacheRegistry,
293
+ writerStore: deps.blueprintStore,
294
+ appId,
295
+ blueprintId,
296
+ input: {
297
+ kind: "template",
298
+ contract,
299
+ intent: intentForCache,
300
+ // ggui#1275 — an explicit intent or a seed prompt states the
301
+ // UI's task; a persona or the placeholder is a stand-in the
302
+ // matcher's judge never sees.
303
+ intentSource: parsed.intent !== undefined || parsed.seedPrompt !== undefined
304
+ ? "authored"
305
+ : "fallback",
306
+ componentCode,
307
+ // The cache row MUST carry the same variance as the MVB
308
+ // row: `registerBlueprint` keys the exact-lookup on
309
+ // `variantKey(variance)`, so omitting it here filed every
310
+ // operator-authored variant under the default-variant
311
+ // sentinel — invisible to any request that asks for the
312
+ // persona it was minted for.
313
+ variance: blueprint.variance,
314
+ // Operator-DISPATCHED but engine-GENERATED: the code came
315
+ // out of `generator.generate(...)`, so provenance is the
316
+ // llm arm — the same `source` stamped on the MVB row above.
317
+ // The two axes disagree here on purpose, which is exactly
318
+ // why `createdBy` cannot be derived from `source`.
319
+ source,
320
+ ...(build !== undefined ? { build } : {}),
321
+ createdBy: "operator",
322
+ },
333
323
  });
334
324
  }
335
325
  catch (err) {
@@ -352,7 +342,7 @@ export function createGguiOpsGenerateBlueprintHandler(deps) {
352
342
  }
353
343
  }
354
344
  }
355
- // 7. Pin as operator default when requested.
345
+ // 7. Mark as operator default when requested.
356
346
  if (parsed.setAsOperatorDefault === true) {
357
347
  await deps.blueprintStore.setOperatorDefault(blueprintId);
358
348
  }
@@ -381,7 +371,6 @@ export function createGguiOpsGenerateBlueprintHandler(deps) {
381
371
  blueprintId,
382
372
  codeHash,
383
373
  source,
384
- ...(validatorScore !== undefined ? { validatorScore } : {}),
385
374
  };
386
375
  return output;
387
376
  },
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/list.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAGL,KAAK,SAAS,EAGf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAQxF;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C;;;;;;;OAOG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;CACzD;AAmBD,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,yBAAyB;;;;;;;;;;GAyFhC"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/list.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAGL,KAAK,SAAS,EAGf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAQxF;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C;;;;;;;OAOG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;CACzD;AAkBD,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,yBAAyB;;;;;;;;;;GAyFhC"}
@@ -42,8 +42,7 @@ const opsOutputSchema = {
42
42
  };
43
43
  /**
44
44
  * Sort blueprints by `createdAt desc`, then `blueprintId asc` as
45
- * stable tiebreaker. Mirrors the `BlueprintSelector` deterministic
46
- * ladder ordering (see `@ggui-ai/mcp-server-core/blueprint-selector`).
45
+ * stable tiebreaker.
47
46
  */
48
47
  function sortBlueprintsByCreatedAtDesc(rows) {
49
48
  return [...rows].sort((a, b) => {