@lerianstudio/matcher-mcp 1.0.0-beta.5

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 (220) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +281 -0
  3. package/dist/auth/request-token.js +117 -0
  4. package/dist/auth/request-token.js.map +1 -0
  5. package/dist/config.js +95 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/matcher/client.js +168 -0
  8. package/dist/matcher/client.js.map +1 -0
  9. package/dist/observability/otel.js +223 -0
  10. package/dist/observability/otel.js.map +1 -0
  11. package/dist/server.js +245 -0
  12. package/dist/server.js.map +1 -0
  13. package/dist/spec/curated-operations.js +145 -0
  14. package/dist/spec/curated-operations.js.map +1 -0
  15. package/dist/spec/index.js +155 -0
  16. package/dist/spec/index.js.map +1 -0
  17. package/dist/spec/load.js +76 -0
  18. package/dist/spec/load.js.map +1 -0
  19. package/dist/spec/openapi.yaml +15217 -0
  20. package/dist/tools/context/create.js +100 -0
  21. package/dist/tools/context/create.js.map +1 -0
  22. package/dist/tools/context/get.js +31 -0
  23. package/dist/tools/context/get.js.map +1 -0
  24. package/dist/tools/context/index.js +21 -0
  25. package/dist/tools/context/index.js.map +1 -0
  26. package/dist/tools/context/list.js +78 -0
  27. package/dist/tools/context/list.js.map +1 -0
  28. package/dist/tools/context/shared.js +61 -0
  29. package/dist/tools/context/shared.js.map +1 -0
  30. package/dist/tools/context/update.js +105 -0
  31. package/dist/tools/context/update.js.map +1 -0
  32. package/dist/tools/dashboard/aggregates.js +34 -0
  33. package/dist/tools/dashboard/aggregates.js.map +1 -0
  34. package/dist/tools/dashboard/cash-impact.js +36 -0
  35. package/dist/tools/dashboard/cash-impact.js.map +1 -0
  36. package/dist/tools/dashboard/index.js +27 -0
  37. package/dist/tools/dashboard/index.js.map +1 -0
  38. package/dist/tools/dashboard/match-rate.js +35 -0
  39. package/dist/tools/dashboard/match-rate.js.map +1 -0
  40. package/dist/tools/dashboard/metrics.js +36 -0
  41. package/dist/tools/dashboard/metrics.js.map +1 -0
  42. package/dist/tools/dashboard/shared.js +122 -0
  43. package/dist/tools/dashboard/shared.js.map +1 -0
  44. package/dist/tools/dashboard/sla.js +33 -0
  45. package/dist/tools/dashboard/sla.js.map +1 -0
  46. package/dist/tools/dashboard/source-breakdown.js +36 -0
  47. package/dist/tools/dashboard/source-breakdown.js.map +1 -0
  48. package/dist/tools/dashboard/volume.js +35 -0
  49. package/dist/tools/dashboard/volume.js.map +1 -0
  50. package/dist/tools/dispute/close.js +49 -0
  51. package/dist/tools/dispute/close.js.map +1 -0
  52. package/dist/tools/dispute/get.js +27 -0
  53. package/dist/tools/dispute/get.js.map +1 -0
  54. package/dist/tools/dispute/index.js +17 -0
  55. package/dist/tools/dispute/index.js.map +1 -0
  56. package/dist/tools/dispute/list.js +137 -0
  57. package/dist/tools/dispute/list.js.map +1 -0
  58. package/dist/tools/dispute/shared.js +66 -0
  59. package/dist/tools/dispute/shared.js.map +1 -0
  60. package/dist/tools/dispute/submit-evidence.js +58 -0
  61. package/dist/tools/dispute/submit-evidence.js.map +1 -0
  62. package/dist/tools/exception/add-comment.js +50 -0
  63. package/dist/tools/exception/add-comment.js.map +1 -0
  64. package/dist/tools/exception/adjust-entry.js +71 -0
  65. package/dist/tools/exception/adjust-entry.js.map +1 -0
  66. package/dist/tools/exception/bulk-assign.js +47 -0
  67. package/dist/tools/exception/bulk-assign.js.map +1 -0
  68. package/dist/tools/exception/bulk-dispatch.js +69 -0
  69. package/dist/tools/exception/bulk-dispatch.js.map +1 -0
  70. package/dist/tools/exception/bulk-resolve.js +64 -0
  71. package/dist/tools/exception/bulk-resolve.js.map +1 -0
  72. package/dist/tools/exception/delete-comment.js +40 -0
  73. package/dist/tools/exception/delete-comment.js.map +1 -0
  74. package/dist/tools/exception/dispatch.js +64 -0
  75. package/dist/tools/exception/dispatch.js.map +1 -0
  76. package/dist/tools/exception/force-match.js +55 -0
  77. package/dist/tools/exception/force-match.js.map +1 -0
  78. package/dist/tools/exception/get.js +34 -0
  79. package/dist/tools/exception/get.js.map +1 -0
  80. package/dist/tools/exception/history.js +61 -0
  81. package/dist/tools/exception/history.js.map +1 -0
  82. package/dist/tools/exception/index.js +39 -0
  83. package/dist/tools/exception/index.js.map +1 -0
  84. package/dist/tools/exception/list-comments.js +35 -0
  85. package/dist/tools/exception/list-comments.js.map +1 -0
  86. package/dist/tools/exception/list.js +169 -0
  87. package/dist/tools/exception/list.js.map +1 -0
  88. package/dist/tools/exception/open-dispute.js +53 -0
  89. package/dist/tools/exception/open-dispute.js.map +1 -0
  90. package/dist/tools/exception/shared.js +98 -0
  91. package/dist/tools/exception/shared.js.map +1 -0
  92. package/dist/tools/fee-rule/create.js +106 -0
  93. package/dist/tools/fee-rule/create.js.map +1 -0
  94. package/dist/tools/fee-rule/delete.js +27 -0
  95. package/dist/tools/fee-rule/delete.js.map +1 -0
  96. package/dist/tools/fee-rule/get.js +27 -0
  97. package/dist/tools/fee-rule/get.js.map +1 -0
  98. package/dist/tools/fee-rule/index.js +21 -0
  99. package/dist/tools/fee-rule/index.js.map +1 -0
  100. package/dist/tools/fee-rule/list.js +64 -0
  101. package/dist/tools/fee-rule/list.js.map +1 -0
  102. package/dist/tools/fee-rule/shared.js +67 -0
  103. package/dist/tools/fee-rule/shared.js.map +1 -0
  104. package/dist/tools/fee-rule/update.js +70 -0
  105. package/dist/tools/fee-rule/update.js.map +1 -0
  106. package/dist/tools/fee-schedule/create.js +105 -0
  107. package/dist/tools/fee-schedule/create.js.map +1 -0
  108. package/dist/tools/fee-schedule/delete.js +32 -0
  109. package/dist/tools/fee-schedule/delete.js.map +1 -0
  110. package/dist/tools/fee-schedule/get.js +30 -0
  111. package/dist/tools/fee-schedule/get.js.map +1 -0
  112. package/dist/tools/fee-schedule/index.js +22 -0
  113. package/dist/tools/fee-schedule/index.js.map +1 -0
  114. package/dist/tools/fee-schedule/list.js +56 -0
  115. package/dist/tools/fee-schedule/list.js.map +1 -0
  116. package/dist/tools/fee-schedule/shared.js +58 -0
  117. package/dist/tools/fee-schedule/shared.js.map +1 -0
  118. package/dist/tools/fee-schedule/simulate.js +54 -0
  119. package/dist/tools/fee-schedule/simulate.js.map +1 -0
  120. package/dist/tools/fee-schedule/update.js +69 -0
  121. package/dist/tools/fee-schedule/update.js.map +1 -0
  122. package/dist/tools/generic/describe-operation.js +157 -0
  123. package/dist/tools/generic/describe-operation.js.map +1 -0
  124. package/dist/tools/generic/invoke.js +343 -0
  125. package/dist/tools/generic/invoke.js.map +1 -0
  126. package/dist/tools/generic/list-operations.js +73 -0
  127. package/dist/tools/generic/list-operations.js.map +1 -0
  128. package/dist/tools/ingestion/index.js +29 -0
  129. package/dist/tools/ingestion/index.js.map +1 -0
  130. package/dist/tools/ingestion/job-errors-list.js +45 -0
  131. package/dist/tools/ingestion/job-errors-list.js.map +1 -0
  132. package/dist/tools/ingestion/job-get.js +42 -0
  133. package/dist/tools/ingestion/job-get.js.map +1 -0
  134. package/dist/tools/ingestion/job-transactions-list.js +93 -0
  135. package/dist/tools/ingestion/job-transactions-list.js.map +1 -0
  136. package/dist/tools/ingestion/jobs-list.js +89 -0
  137. package/dist/tools/ingestion/jobs-list.js.map +1 -0
  138. package/dist/tools/ingestion/shared.js +84 -0
  139. package/dist/tools/ingestion/shared.js.map +1 -0
  140. package/dist/tools/ingestion/transaction-ignore.js +51 -0
  141. package/dist/tools/ingestion/transaction-ignore.js.map +1 -0
  142. package/dist/tools/ingestion/transactions-search.js +143 -0
  143. package/dist/tools/ingestion/transactions-search.js.map +1 -0
  144. package/dist/tools/match-rule/create.js +64 -0
  145. package/dist/tools/match-rule/create.js.map +1 -0
  146. package/dist/tools/match-rule/delete.js +35 -0
  147. package/dist/tools/match-rule/delete.js.map +1 -0
  148. package/dist/tools/match-rule/get.js +32 -0
  149. package/dist/tools/match-rule/get.js.map +1 -0
  150. package/dist/tools/match-rule/index.js +22 -0
  151. package/dist/tools/match-rule/index.js.map +1 -0
  152. package/dist/tools/match-rule/list.js +72 -0
  153. package/dist/tools/match-rule/list.js.map +1 -0
  154. package/dist/tools/match-rule/reorder.js +45 -0
  155. package/dist/tools/match-rule/reorder.js.map +1 -0
  156. package/dist/tools/match-rule/shared.js +71 -0
  157. package/dist/tools/match-rule/shared.js.map +1 -0
  158. package/dist/tools/match-rule/update.js +68 -0
  159. package/dist/tools/match-rule/update.js.map +1 -0
  160. package/dist/tools/matching/get.js +48 -0
  161. package/dist/tools/matching/get.js.map +1 -0
  162. package/dist/tools/matching/groups.js +98 -0
  163. package/dist/tools/matching/groups.js.map +1 -0
  164. package/dist/tools/matching/index.js +19 -0
  165. package/dist/tools/matching/index.js.map +1 -0
  166. package/dist/tools/matching/list.js +76 -0
  167. package/dist/tools/matching/list.js.map +1 -0
  168. package/dist/tools/matching/shared.js +77 -0
  169. package/dist/tools/matching/shared.js.map +1 -0
  170. package/dist/tools/matching/start.js +55 -0
  171. package/dist/tools/matching/start.js.map +1 -0
  172. package/dist/tools/report/count-exceptions.js +45 -0
  173. package/dist/tools/report/count-exceptions.js.map +1 -0
  174. package/dist/tools/report/count-matched.js +46 -0
  175. package/dist/tools/report/count-matched.js.map +1 -0
  176. package/dist/tools/report/count-transactions.js +44 -0
  177. package/dist/tools/report/count-transactions.js.map +1 -0
  178. package/dist/tools/report/count-unmatched.js +44 -0
  179. package/dist/tools/report/count-unmatched.js.map +1 -0
  180. package/dist/tools/report/export-exceptions.js +46 -0
  181. package/dist/tools/report/export-exceptions.js.map +1 -0
  182. package/dist/tools/report/export-matched.js +47 -0
  183. package/dist/tools/report/export-matched.js.map +1 -0
  184. package/dist/tools/report/export-summary.js +47 -0
  185. package/dist/tools/report/export-summary.js.map +1 -0
  186. package/dist/tools/report/export-unmatched.js +47 -0
  187. package/dist/tools/report/export-unmatched.js.map +1 -0
  188. package/dist/tools/report/export-variance.js +46 -0
  189. package/dist/tools/report/export-variance.js.map +1 -0
  190. package/dist/tools/report/index.js +40 -0
  191. package/dist/tools/report/index.js.map +1 -0
  192. package/dist/tools/report/matched.js +44 -0
  193. package/dist/tools/report/matched.js.map +1 -0
  194. package/dist/tools/report/shared.js +176 -0
  195. package/dist/tools/report/shared.js.map +1 -0
  196. package/dist/tools/report/summary.js +41 -0
  197. package/dist/tools/report/summary.js.map +1 -0
  198. package/dist/tools/report/unmatched.js +44 -0
  199. package/dist/tools/report/unmatched.js.map +1 -0
  200. package/dist/tools/report/variance.js +44 -0
  201. package/dist/tools/report/variance.js.map +1 -0
  202. package/dist/tools/source/create.js +84 -0
  203. package/dist/tools/source/create.js.map +1 -0
  204. package/dist/tools/source/get.js +41 -0
  205. package/dist/tools/source/get.js.map +1 -0
  206. package/dist/tools/source/index.js +22 -0
  207. package/dist/tools/source/index.js.map +1 -0
  208. package/dist/tools/source/list.js +72 -0
  209. package/dist/tools/source/list.js.map +1 -0
  210. package/dist/tools/source/shared.js +63 -0
  211. package/dist/tools/source/shared.js.map +1 -0
  212. package/dist/tools/source/update.js +73 -0
  213. package/dist/tools/source/update.js.map +1 -0
  214. package/dist/tools/tool-error.js +74 -0
  215. package/dist/tools/tool-error.js.map +1 -0
  216. package/dist/transport/body-limit.js +82 -0
  217. package/dist/transport/body-limit.js.map +1 -0
  218. package/dist/transport/http.js +154 -0
  219. package/dist/transport/http.js.map +1 -0
  220. package/package.json +68 -0
@@ -0,0 +1,100 @@
1
+ // `context_create` — curated POST /v1/contexts.
2
+ //
3
+ // A typed, richly-described front door to creating a reconciliation context,
4
+ // mirroring the spec's CreateContextRequest. The Zod schema models the required
5
+ // scalars (name, type, interval) and the documented enums (type, feeNormalization)
6
+ // so an operator-driving LLM gets the shape and the units up front; the inline
7
+ // `rules[]` and `sources[]` arrays are modeled as typed-but-permissive records
8
+ // (per the Phase 1 pattern) — matcher's server-side validation + the returned
9
+ // RFC 9457 problem are the authoritative check, so we do not duplicate the full
10
+ // rule/source validation here.
11
+ //
12
+ // No tenant field exists in the schema: the context is created for the tenant of
13
+ // the relayed bearer token, never a tenant supplied as input.
14
+ import { z } from 'zod';
15
+ import { CONTEXTS_PATH, dispatchContext } from './shared.js';
16
+ /**
17
+ * Reconciliation topology. The values are literal strings that contain colons:
18
+ * 1:1 matches one left transaction to one right; 1:N matches one against many;
19
+ * N:M matches groups on both sides.
20
+ */
21
+ export const CONTEXT_TYPES = ['1:1', '1:N', 'N:M'];
22
+ /** Fee normalization mode applied before amount comparison. */
23
+ export const FEE_NORMALIZATIONS = ['NET', 'GROSS'];
24
+ /** Maximum inline match rules a context may be created with. */
25
+ export const MAX_INLINE_RULES = 50;
26
+ /** Maximum inline sources a context may be created with. */
27
+ export const MAX_INLINE_SOURCES = 10;
28
+ /** Zod raw shape for `context_create` input — mirrors CreateContextRequest. */
29
+ export const createContextInputShape = {
30
+ name: z
31
+ .string()
32
+ .min(1)
33
+ .max(100)
34
+ .describe('Human-readable name of the reconciliation context (1–100 chars).'),
35
+ type: z
36
+ .enum(CONTEXT_TYPES)
37
+ .describe('Reconciliation topology. "1:1" matches one left transaction to one ' +
38
+ 'right; "1:N" matches one transaction against many on the other side; ' +
39
+ '"N:M" matches groups on both sides. The values contain colons.'),
40
+ interval: z
41
+ .string()
42
+ .min(1)
43
+ .max(100)
44
+ .describe('Execution interval label for the context, e.g. "daily" or "weekly" ' +
45
+ '(1–100 chars).'),
46
+ autoMatchOnUpload: z
47
+ .boolean()
48
+ .optional()
49
+ .describe('When true, a match run is triggered automatically after a file upload ' +
50
+ 'completes.'),
51
+ feeNormalization: z
52
+ .enum(FEE_NORMALIZATIONS)
53
+ .optional()
54
+ .describe('Fee normalization mode. NET compares amounts after fees are deducted; ' +
55
+ 'GROSS compares amounts before fees.'),
56
+ feeToleranceAbs: z
57
+ .string()
58
+ .optional()
59
+ .describe('Absolute fee tolerance as a decimal STRING in the context currency, ' +
60
+ 'e.g. "0.01".'),
61
+ feeTolerancePct: z
62
+ .string()
63
+ .optional()
64
+ .describe('Percentage fee tolerance as a decimal STRING (0.5 means 0.5%), e.g. "0.5".'),
65
+ rules: z
66
+ .array(z.record(z.string(), z.unknown()))
67
+ .max(MAX_INLINE_RULES)
68
+ .optional()
69
+ .describe('Match rules to create inline with the context (max 50). Each rule is ' +
70
+ 'validated server-side; prefer context_create with no rules then ' +
71
+ 'match_rule_create for richer control.'),
72
+ sources: z
73
+ .array(z.record(z.string(), z.unknown()))
74
+ .max(MAX_INLINE_SOURCES)
75
+ .optional()
76
+ .describe('Sources to create inline with the context (max 10). Each source is ' +
77
+ 'validated server-side; prefer context_create with no sources then ' +
78
+ 'source_create for richer control.'),
79
+ };
80
+ /**
81
+ * Register `context_create`. Builds the POST request body from the typed input
82
+ * and dispatches it through the shared fail-closed relay; a matcher error
83
+ * surfaces via the shared toToolError (same shape as matcher_invoke).
84
+ */
85
+ export function registerContextCreateTool(server) {
86
+ server.registerTool('context_create', {
87
+ description: 'Create a reconciliation context — the top of the configuration ' +
88
+ "hierarchy that rules, sources, and fee schedules hang off. Created for " +
89
+ "your token's tenant (no tenant field is accepted). Required: name " +
90
+ '(1–100), type ("1:1"|"1:N"|"N:M", with colons), interval (label, e.g. ' +
91
+ '"daily"). Optional: autoMatchOnUpload (bool), feeNormalization ' +
92
+ '(NET|GROSS), feeToleranceAbs/feeTolerancePct (decimal strings), and ' +
93
+ 'inline rules[] (≤50) / sources[] (≤10). Returns the created context, or ' +
94
+ 'a structured RFC 9457 error.',
95
+ inputSchema: createContextInputShape,
96
+ }, async (args, extra) => {
97
+ return dispatchContext({ method: 'POST', path: CONTEXTS_PATH, body: args }, extra);
98
+ });
99
+ }
100
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/tools/context/create.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,EAAE;AACF,6EAA6E;AAC7E,gFAAgF;AAChF,mFAAmF;AACnF,+EAA+E;AAC/E,+EAA+E;AAC/E,8EAA8E;AAC9E,gFAAgF;AAChF,+BAA+B;AAC/B,EAAE;AACF,iFAAiF;AACjF,8DAA8D;AAE9D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE5D;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAU,CAAA;AAE3D,+DAA+D;AAC/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,OAAO,CAAU,CAAA;AAE3D,gEAAgE;AAChE,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAA;AAElC,4DAA4D;AAC5D,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAA;AAEpC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,CAAC,kEAAkE,CAAC;IAC/E,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,aAAa,CAAC;SACnB,QAAQ,CACP,qEAAqE;QACnE,uEAAuE;QACvE,gEAAgE,CACnE;IACH,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,CACP,qEAAqE;QACnE,gBAAgB,CACnB;IACH,iBAAiB,EAAE,CAAC;SACjB,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CACP,wEAAwE;QACtE,YAAY,CACf;IACH,gBAAgB,EAAE,CAAC;SAChB,IAAI,CAAC,kBAAkB,CAAC;SACxB,QAAQ,EAAE;SACV,QAAQ,CACP,wEAAwE;QACtE,qCAAqC,CACxC;IACH,eAAe,EAAE,CAAC;SACf,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,sEAAsE;QACpE,cAAc,CACjB;IACH,eAAe,EAAE,CAAC;SACf,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,4EAA4E,CAC7E;IACH,KAAK,EAAE,CAAC;SACL,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;SACxC,GAAG,CAAC,gBAAgB,CAAC;SACrB,QAAQ,EAAE;SACV,QAAQ,CACP,uEAAuE;QACrE,kEAAkE;QAClE,uCAAuC,CAC1C;IACH,OAAO,EAAE,CAAC;SACP,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;SACxC,GAAG,CAAC,kBAAkB,CAAC;SACvB,QAAQ,EAAE;SACV,QAAQ,CACP,qEAAqE;QACnE,oEAAoE;QACpE,mCAAmC,CACtC;CACJ,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAiB;IACzD,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,WAAW,EACT,iEAAiE;YACjE,yEAAyE;YACzE,oEAAoE;YACpE,wEAAwE;YACxE,iEAAiE;YACjE,sEAAsE;YACtE,0EAA0E;YAC1E,8BAA8B;QAChC,WAAW,EAAE,uBAAuB;KACrC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,OAAO,eAAe,CACpB,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,EACnD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,31 @@
1
+ // `context_get` — curated GET /v1/contexts/{contextId}.
2
+ //
3
+ // Reads one reconciliation context by id. contextId is the only input (a UUID
4
+ // path param). The context must belong to the relayed token's tenant — matcher
5
+ // enforces that; no tenant field is accepted (contextId is a routing param, not
6
+ // a tenant identifier).
7
+ import { z } from 'zod';
8
+ import { contextPath, dispatchContext } from './shared.js';
9
+ /** Zod raw shape for `context_get` input — just the context id. */
10
+ export const getContextInputShape = {
11
+ contextId: z
12
+ .string()
13
+ .min(1)
14
+ .describe('The reconciliation context id (UUID) to fetch.'),
15
+ };
16
+ /**
17
+ * Register `context_get`. Substitutes the id into the path and dispatches a GET
18
+ * through the shared fail-closed relay; a matcher error (e.g. 404) surfaces via
19
+ * the shared toToolError.
20
+ */
21
+ export function registerContextGetTool(server) {
22
+ server.registerTool('context_get', {
23
+ description: 'Fetch a single reconciliation context by id (UUID). The context must ' +
24
+ "belong to your token's tenant. Returns the context, or a structured " +
25
+ 'RFC 9457 error (e.g. 404 if it does not exist or is not yours).',
26
+ inputSchema: getContextInputShape,
27
+ }, async (args, extra) => {
28
+ return dispatchContext({ method: 'GET', path: contextPath(args.contextId) }, extra);
29
+ });
30
+ }
31
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../../src/tools/context/get.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,gFAAgF;AAChF,wBAAwB;AAExB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE1D,mEAAmE;AACnE,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,gDAAgD,CAAC;CAC9D,CAAA;AAKD;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;QACE,WAAW,EACT,uEAAuE;YACvE,sEAAsE;YACtE,iEAAiE;QACnE,WAAW,EAAE,oBAAoB;KAClC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,OAAO,eAAe,CACpB,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EACpD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ // Curated context vertical (task 2.2.1): four typed tools over the matcher
2
+ // reconciliation-context resource — create, list, get, update. (Delete was
3
+ // removed when the matcher app replaced context hard-delete with the
4
+ // archive/restore lifecycle; archive/restore remain reachable via the generic
5
+ // invoke surface.) Contexts are the top of the configuration hierarchy that
6
+ // rules, sources, and fee schedules hang off. Each tool shares the fail-closed
7
+ // relay (shared.ts) and the RFC 9457 → tool-error mapping (toToolError) with the
8
+ // generic surface, so curated and generic map matcher errors identically. No
9
+ // tool carries a tenant field.
10
+ import { registerContextCreateTool } from './create.js';
11
+ import { registerContextGetTool } from './get.js';
12
+ import { registerContextListTool } from './list.js';
13
+ import { registerContextUpdateTool } from './update.js';
14
+ /** Register all four curated context tools on the given server. */
15
+ export function registerContextTools(server) {
16
+ registerContextCreateTool(server);
17
+ registerContextListTool(server);
18
+ registerContextGetTool(server);
19
+ registerContextUpdateTool(server);
20
+ }
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/context/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,2EAA2E;AAC3E,qEAAqE;AACrE,8EAA8E;AAC9E,4EAA4E;AAC5E,+EAA+E;AAC/E,iFAAiF;AACjF,6EAA6E;AAC7E,+BAA+B;AAI/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA;AACnD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD,mEAAmE;AACnE,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,yBAAyB,CAAC,MAAM,CAAC,CAAA;IACjC,uBAAuB,CAAC,MAAM,CAAC,CAAA;IAC/B,sBAAsB,CAAC,MAAM,CAAC,CAAA;IAC9B,yBAAyB,CAAC,MAAM,CAAC,CAAA;AACnC,CAAC"}
@@ -0,0 +1,78 @@
1
+ // `context_list` — curated GET /v1/contexts.
2
+ //
3
+ // Cursor-paginated list of the tenant's reconciliation contexts, with optional
4
+ // `type` and `status` filters the spec exposes. limit/cursor/type/status pass
5
+ // through untouched and matcher's { items, nextCursor, ... } envelope is returned
6
+ // as-is — no auto-pagination (the model re-calls with the returned cursor). The
7
+ // list is implicitly tenant-scoped by the relayed token; no tenant field is
8
+ // accepted.
9
+ import { z } from 'zod';
10
+ import { CONTEXT_TYPES } from './create.js';
11
+ import { CONTEXTS_PATH, dispatchContext } from './shared.js';
12
+ /** Lifecycle statuses a context can be filtered by on the list endpoint. */
13
+ export const CONTEXT_STATUSES = ['DRAFT', 'ACTIVE', 'PAUSED', 'ARCHIVED'];
14
+ /** Zod raw shape for `context_list` input — pagination knobs + optional filters. */
15
+ export const listContextsInputShape = {
16
+ limit: z
17
+ .number()
18
+ .int()
19
+ .min(1)
20
+ .max(200)
21
+ .optional()
22
+ .describe('Maximum number of records to return (1–200, default 20).'),
23
+ cursor: z
24
+ .string()
25
+ .optional()
26
+ .describe('Opaque pagination cursor from a prior response. Re-call with the ' +
27
+ 'returned nextCursor to page forward (there is no auto-pagination).'),
28
+ type: z
29
+ .enum(CONTEXT_TYPES)
30
+ .optional()
31
+ .describe('Optional filter by reconciliation topology ("1:1"|"1:N"|"N:M", with colons).'),
32
+ status: z
33
+ .enum(CONTEXT_STATUSES)
34
+ .optional()
35
+ .describe('Optional filter by lifecycle status. DRAFT is unactivated; ACTIVE runs; ' +
36
+ 'PAUSED is suspended; ARCHIVED is retired.'),
37
+ };
38
+ /** Build the list query, omitting unset knobs so the request stays minimal. */
39
+ function buildListQuery(args) {
40
+ const query = {};
41
+ if (args.limit !== undefined) {
42
+ query.limit = args.limit;
43
+ }
44
+ if (args.cursor !== undefined) {
45
+ query.cursor = args.cursor;
46
+ }
47
+ if (args.type !== undefined) {
48
+ query.type = args.type;
49
+ }
50
+ if (args.status !== undefined) {
51
+ query.status = args.status;
52
+ }
53
+ return Object.keys(query).length > 0 ? query : undefined;
54
+ }
55
+ /**
56
+ * Register `context_list`. Passes limit/cursor/type/status through and returns
57
+ * matcher's pagination envelope verbatim; a matcher error surfaces via the
58
+ * shared toToolError.
59
+ */
60
+ export function registerContextListTool(server) {
61
+ server.registerTool('context_list', {
62
+ description: "List the reconciliation contexts for your token's tenant " +
63
+ '(cursor-paginated). Pass limit (1–200) and/or cursor; optionally filter ' +
64
+ 'by type ("1:1"|"1:N"|"N:M") and/or status (DRAFT|ACTIVE|PAUSED|ARCHIVED). ' +
65
+ 'The response carries { items, nextCursor } — paginate by re-calling with ' +
66
+ 'the returned nextCursor. No tenant field is accepted; the tenant is ' +
67
+ 'derived from your bearer token.',
68
+ inputSchema: listContextsInputShape,
69
+ }, async (args, extra) => {
70
+ const query = buildListQuery(args);
71
+ return dispatchContext({
72
+ method: 'GET',
73
+ path: CONTEXTS_PATH,
74
+ ...(query !== undefined ? { query } : {}),
75
+ }, extra);
76
+ });
77
+ }
78
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/tools/context/list.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,EAAE;AACF,+EAA+E;AAC/E,8EAA8E;AAC9E,kFAAkF;AAClF,gFAAgF;AAChF,4EAA4E;AAC5E,YAAY;AAEZ,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE5D,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAU,CAAA;AAElF,oFAAoF;AACpF,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,0DAA0D,CAAC;IACvE,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,mEAAmE;QACjE,oEAAoE,CACvE;IACH,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,aAAa,CAAC;SACnB,QAAQ,EAAE;SACV,QAAQ,CACP,8EAA8E,CAC/E;IACH,MAAM,EAAE,CAAC;SACN,IAAI,CAAC,gBAAgB,CAAC;SACtB,QAAQ,EAAE;SACV,QAAQ,CACP,0EAA0E;QACxE,2CAA2C,CAC9C;CACJ,CAAA;AAOD,+EAA+E;AAC/E,SAAS,cAAc,CAAC,IAAuB;IAC7C,MAAM,KAAK,GAAoC,EAAE,CAAA;IACjD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC7B,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IAC1B,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC9B,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;IAC5B,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;IACxB,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC9B,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;IAC5B,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AAC1D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,WAAW,EACT,2DAA2D;YAC3D,0EAA0E;YAC1E,4EAA4E;YAC5E,2EAA2E;YAC3E,sEAAsE;YACtE,iCAAiC;QACnC,WAAW,EAAE,sBAAsB;KACpC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAA;QAClC,OAAO,eAAe,CACpB;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,aAAa;YACnB,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1C,EACD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,61 @@
1
+ // Shared plumbing for the curated context tools.
2
+ //
3
+ // Every context tool follows the same relay shape: fail-closed auth via
4
+ // requireMatcherClient, dispatch one assembled MatcherRequest, then return
5
+ // matcher's JSON on success or the SHARED toToolError on a MatcherApiError. This
6
+ // module factors that boilerplate exactly once so the five tools stay thin (just
7
+ // "build the request") and so curated + generic surfaces map matcher errors
8
+ // through the identical path (toToolError) — the whole point of the curated
9
+ // pattern established in Phase 1.
10
+ //
11
+ // Security: the bearer token is never read here directly — requireMatcherClient
12
+ // owns the request-scoped relay and fails closed when no usable credential was
13
+ // provided. No tenant identifier is ever read or injected (matcher derives
14
+ // tenant from the relayed JWT); no context tool input carries one. The
15
+ // `contextId` forwarded into the path is a routing param matcher validates
16
+ // ownership of, not a tenant field.
17
+ import { requireMatcherClient, UnauthenticatedError, } from '../../auth/request-token.js';
18
+ import { isMatcherApiError, toToolError } from '../tool-error.js';
19
+ /** Base path for the reconciliation-context resource (tenant-scoped; tenant from the token). */
20
+ export const CONTEXTS_PATH = '/v1/contexts';
21
+ /** Build the single-context sub-path, URL-encoding the id so reserved chars are safe. */
22
+ export function contextPath(contextId) {
23
+ return `${CONTEXTS_PATH}/${encodeURIComponent(contextId)}`;
24
+ }
25
+ /**
26
+ * Run one assembled request through the relay: fail-closed auth, dispatch, and
27
+ * RFC 9457 → tool-error mapping — identical to the generic invoke's dispatch so
28
+ * both surfaces produce the same structured error shape.
29
+ *
30
+ * `clientFor` is injectable for tests; production callers pass nothing and get
31
+ * the request-scoped, fail-closed `requireMatcherClient`.
32
+ */
33
+ export async function dispatchContext(request, extra, clientFor = requireMatcherClient) {
34
+ let client;
35
+ try {
36
+ // Fail-closed on a missing / empty / non-Bearer credential.
37
+ client = clientFor(extra);
38
+ }
39
+ catch (err) {
40
+ if (err instanceof UnauthenticatedError) {
41
+ return { isError: true, content: [{ type: 'text', text: err.message }] };
42
+ }
43
+ throw err;
44
+ }
45
+ try {
46
+ const result = await client.request(request);
47
+ // Success → matcher's JSON returned as-is (incl. pagination envelopes and
48
+ // 204 → null for delete).
49
+ return { content: [{ type: 'text', text: JSON.stringify(result ?? null) }] };
50
+ }
51
+ catch (err) {
52
+ // RFC 9457 problem → the SHARED structured tool error (status/title/detail/
53
+ // code preserved). A non-matcher error is a bug, not a matcher failure, and
54
+ // is re-thrown rather than masqueraded as one.
55
+ if (isMatcherApiError(err)) {
56
+ return toToolError(err);
57
+ }
58
+ throw err;
59
+ }
60
+ }
61
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/tools/context/shared.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,EAAE;AACF,wEAAwE;AACxE,2EAA2E;AAC3E,iFAAiF;AACjF,iFAAiF;AACjF,4EAA4E;AAC5E,4EAA4E;AAC5E,kCAAkC;AAClC,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAC/E,2EAA2E;AAC3E,uEAAuE;AACvE,2EAA2E;AAC3E,oCAAoC;AAIpC,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GAErB,MAAM,6BAA6B,CAAA;AAEpC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAEjE,gGAAgG;AAChG,MAAM,CAAC,MAAM,aAAa,GAAG,cAAc,CAAA;AAE3C,yFAAyF;AACzF,MAAM,UAAU,WAAW,CAAC,SAAiB;IAC3C,OAAO,GAAG,aAAa,IAAI,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAA;AAC5D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAuB,EACvB,KAAmC,EACnC,YAAyD,oBAAoB;IAE7E,IAAI,MAAqB,CAAA;IACzB,IAAI,CAAC;QACH,4DAA4D;QAC5D,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,oBAAoB,EAAE,CAAC;YACxC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAA;QAC1E,CAAC;QACD,MAAM,GAAG,CAAA;IACX,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAC5C,0EAA0E;QAC1E,0BAA0B;QAC1B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,CAAC,EAAE,CAAA;IAC9E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,4EAA4E;QAC5E,4EAA4E;QAC5E,+CAA+C;QAC/C,IAAI,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,WAAW,CAAC,GAAG,CAAC,CAAA;QACzB,CAAC;QACD,MAAM,GAAG,CAAA;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,105 @@
1
+ // `context_update` — curated PATCH /v1/contexts/{contextId}.
2
+ //
3
+ // Partial update of a reconciliation context's fields, mirroring the spec's
4
+ // UpdateContextRequest. All body fields are optional (PATCH semantics). The
5
+ // status enum here is the set of *transition targets* (ACTIVE|PAUSED|ARCHIVED) —
6
+ // narrower than the list filter (which also allows DRAFT) because you cannot
7
+ // transition a context back to DRAFT. Transitions to ACTIVE are gated on
8
+ // server-side activation readiness; an unready context is rejected with a 409
9
+ // that surfaces verbatim through the shared toToolError. contextId is a UUID
10
+ // path param; no tenant field is accepted (matcher scopes to the relayed token's
11
+ // tenant).
12
+ import { z } from 'zod';
13
+ import { CONTEXT_TYPES, FEE_NORMALIZATIONS } from './create.js';
14
+ import { contextPath, dispatchContext } from './shared.js';
15
+ /**
16
+ * Lifecycle statuses an update may transition a context to. Narrower than the
17
+ * list filter's CONTEXT_STATUSES: DRAFT is the unactivated initial state and is
18
+ * not a valid transition target.
19
+ */
20
+ export const CONTEXT_STATUS_TRANSITIONS = ['ACTIVE', 'PAUSED', 'ARCHIVED'];
21
+ /** Zod raw shape for `context_update` input — id (path) + optional fields. */
22
+ export const updateContextInputShape = {
23
+ contextId: z
24
+ .string()
25
+ .min(1)
26
+ .describe('The reconciliation context id (UUID) to update.'),
27
+ name: z
28
+ .string()
29
+ .min(1)
30
+ .max(100)
31
+ .optional()
32
+ .describe('New human-readable name of the context (1–100 chars).'),
33
+ type: z
34
+ .enum(CONTEXT_TYPES)
35
+ .optional()
36
+ .describe('Reconciliation topology. "1:1" matches one left transaction to one ' +
37
+ 'right; "1:N" matches one against many; "N:M" matches groups on both ' +
38
+ 'sides. The values contain colons.'),
39
+ interval: z
40
+ .string()
41
+ .min(1)
42
+ .max(100)
43
+ .optional()
44
+ .describe('New execution interval label, e.g. "weekly" (1–100 chars).'),
45
+ status: z
46
+ .enum(CONTEXT_STATUS_TRANSITIONS)
47
+ .optional()
48
+ .describe('Lifecycle status to transition to. ACTIVE runs the context (gated on ' +
49
+ 'server-side activation readiness — an unready context is rejected with ' +
50
+ 'a 409); PAUSED suspends scheduling; ARCHIVED retires it. You cannot ' +
51
+ 'transition back to DRAFT.'),
52
+ autoMatchOnUpload: z
53
+ .boolean()
54
+ .optional()
55
+ .describe('When true, a match run is triggered automatically after a file upload ' +
56
+ 'completes.'),
57
+ feeNormalization: z
58
+ .enum(FEE_NORMALIZATIONS)
59
+ .optional()
60
+ .describe('Fee normalization mode. NET compares amounts after fees are deducted; ' +
61
+ 'GROSS compares amounts before fees.'),
62
+ feeToleranceAbs: z
63
+ .string()
64
+ .optional()
65
+ .describe('Absolute fee tolerance as a decimal STRING in the context currency, ' +
66
+ 'e.g. "0.01".'),
67
+ feeTolerancePct: z
68
+ .string()
69
+ .optional()
70
+ .describe('Percentage fee tolerance as a decimal STRING (0.5 means 0.5%), e.g. "0.5".'),
71
+ };
72
+ /**
73
+ * Build the PATCH body from the input minus the path-only `contextId`. Only the
74
+ * fields the caller actually set are sent — matcher treats absent fields as
75
+ * unchanged.
76
+ */
77
+ export function buildUpdateBody(args) {
78
+ const { contextId: _contextId, ...body } = args;
79
+ void _contextId;
80
+ return body;
81
+ }
82
+ /**
83
+ * Register `context_update`. Splits the id (path) from the body fields,
84
+ * dispatches a PATCH through the shared fail-closed relay; a matcher error
85
+ * surfaces via the shared toToolError.
86
+ */
87
+ export function registerContextUpdateTool(server) {
88
+ server.registerTool('context_update', {
89
+ description: 'Update fields of a reconciliation context by id (UUID). All fields are ' +
90
+ 'optional (PATCH): name, type ("1:1"|"1:N"|"N:M"), interval, status ' +
91
+ '(ACTIVE|PAUSED|ARCHIVED — transitioning to ACTIVE is gated on activation ' +
92
+ 'readiness and may return 409), autoMatchOnUpload, feeNormalization ' +
93
+ '(NET|GROSS), feeToleranceAbs/feeTolerancePct (decimal strings). No tenant ' +
94
+ 'field is accepted. Returns the updated context, or a structured RFC 9457 ' +
95
+ 'error.',
96
+ inputSchema: updateContextInputShape,
97
+ }, async (args, extra) => {
98
+ return dispatchContext({
99
+ method: 'PATCH',
100
+ path: contextPath(args.contextId),
101
+ body: buildUpdateBody(args),
102
+ }, extra);
103
+ });
104
+ }
105
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/tools/context/update.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,iFAAiF;AACjF,6EAA6E;AAC7E,yEAAyE;AACzE,8EAA8E;AAC9E,6EAA6E;AAC7E,iFAAiF;AACjF,WAAW;AAEX,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAC/D,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE1D;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAU,CAAA;AAEnF,8EAA8E;AAC9E,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,iDAAiD,CAAC;IAC9D,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,uDAAuD,CAAC;IACpE,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,aAAa,CAAC;SACnB,QAAQ,EAAE;SACV,QAAQ,CACP,qEAAqE;QACnE,sEAAsE;QACtE,mCAAmC,CACtC;IACH,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,4DAA4D,CAAC;IACzE,MAAM,EAAE,CAAC;SACN,IAAI,CAAC,0BAA0B,CAAC;SAChC,QAAQ,EAAE;SACV,QAAQ,CACP,uEAAuE;QACrE,yEAAyE;QACzE,sEAAsE;QACtE,2BAA2B,CAC9B;IACH,iBAAiB,EAAE,CAAC;SACjB,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CACP,wEAAwE;QACtE,YAAY,CACf;IACH,gBAAgB,EAAE,CAAC;SAChB,IAAI,CAAC,kBAAkB,CAAC;SACxB,QAAQ,EAAE;SACV,QAAQ,CACP,wEAAwE;QACtE,qCAAqC,CACxC;IACH,eAAe,EAAE,CAAC;SACf,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,sEAAsE;QACpE,cAAc,CACjB;IACH,eAAe,EAAE,CAAC;SACf,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,4EAA4E,CAC7E;CACJ,CAAA;AAOD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAwB;IAExB,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAA;IAC/C,KAAK,UAAU,CAAA;IACf,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAiB;IACzD,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,WAAW,EACT,yEAAyE;YACzE,qEAAqE;YACrE,2EAA2E;YAC3E,qEAAqE;YACrE,4EAA4E;YAC5E,2EAA2E;YAC3E,QAAQ;QACV,WAAW,EAAE,uBAAuB;KACrC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,OAAO,eAAe,CACpB;YACE,MAAM,EAAE,OAAO;YACf,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC;YACjC,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC;SAC5B,EACD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,34 @@
1
+ // `dashboard_aggregates` — curated GET /v1/reports/contexts/{contextId}/dashboard.
2
+ //
3
+ // The combined dashboard read: volume, match-rate, and SLA aggregates in one
4
+ // payload (spec operationId getDashboardAggregates). Shares the family input
5
+ // shape (contextId path + optional date_from/date_to/source_id query) and the
6
+ // fail-closed relay. The report is implicitly tenant-scoped by the relayed
7
+ // token; contextId is a routing path param and source_id a data filter — neither
8
+ // is a tenant field, and no tenant field is accepted.
9
+ import { buildDashboardQuery, contextDashboardPath, dashboardQueryInputShape, dispatchDashboard, } from './shared.js';
10
+ /** Zod raw shape for `dashboard_aggregates` input — the shared dashboard shape. */
11
+ export const dashboardAggregatesInputShape = dashboardQueryInputShape;
12
+ /**
13
+ * Register `dashboard_aggregates`. Dispatches a GET to the context's dashboard
14
+ * base path with the optional date/source query and returns matcher's combined
15
+ * aggregates verbatim; a matcher error surfaces via the shared toToolError.
16
+ */
17
+ export function registerDashboardAggregatesTool(server) {
18
+ server.registerTool('dashboard_aggregates', {
19
+ description: 'Get the combined dashboard aggregates (volume, match rate, and SLA) ' +
20
+ 'for a reconciliation context. Pass contextId (UUID path param — not a ' +
21
+ 'tenant field), and optionally date_from/date_to (YYYY-MM-DD; matcher ' +
22
+ 'defaults to the last 30 days and caps the window at 90 days) and/or ' +
23
+ 'source_id (UUID data filter). No tenant field is accepted.',
24
+ inputSchema: dashboardAggregatesInputShape,
25
+ }, async (args, extra) => {
26
+ const query = buildDashboardQuery(args);
27
+ return dispatchDashboard({
28
+ method: 'GET',
29
+ path: contextDashboardPath(args.contextId),
30
+ ...(query !== undefined ? { query } : {}),
31
+ }, extra);
32
+ });
33
+ }
34
+ //# sourceMappingURL=aggregates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregates.js","sourceRoot":"","sources":["../../../src/tools/dashboard/aggregates.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,2EAA2E;AAC3E,iFAAiF;AACjF,sDAAsD;AAItD,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,aAAa,CAAA;AAEpB,mFAAmF;AACnF,MAAM,CAAC,MAAM,6BAA6B,GAAG,wBAAwB,CAAA;AAErE;;;;GAIG;AACH,MAAM,UAAU,+BAA+B,CAAC,MAAiB;IAC/D,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,WAAW,EACT,sEAAsE;YACtE,wEAAwE;YACxE,uEAAuE;YACvE,sEAAsE;YACtE,4DAA4D;QAC9D,WAAW,EAAE,6BAA6B;KAC3C,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAA;QACvC,OAAO,iBAAiB,CACtB;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC;YAC1C,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1C,EACD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,36 @@
1
+ // `dashboard_cash_impact` — curated GET
2
+ // /v1/reports/contexts/{contextId}/dashboard/cash-impact.
3
+ //
4
+ // Unreconciled financial exposure with currency and age breakdowns (spec
5
+ // operationId getCashImpactSummary). Shares the family input shape (contextId
6
+ // path + optional date_from/date_to/source_id query) and the fail-closed relay.
7
+ // contextId is a routing path param and source_id a data filter — neither is a
8
+ // tenant field, and no tenant field is accepted.
9
+ import { buildDashboardQuery, contextDashboardSlicePath, dashboardQueryInputShape, dispatchDashboard, } from './shared.js';
10
+ /** Zod raw shape for `dashboard_cash_impact` input — the shared dashboard shape. */
11
+ export const dashboardCashImpactInputShape = dashboardQueryInputShape;
12
+ /**
13
+ * Register `dashboard_cash_impact`. Dispatches a GET to the context's
14
+ * /dashboard/cash-impact slice with the optional date/source query and returns
15
+ * matcher's exposure summary verbatim; a matcher error surfaces via the shared
16
+ * toToolError.
17
+ */
18
+ export function registerDashboardCashImpactTool(server) {
19
+ server.registerTool('dashboard_cash_impact', {
20
+ description: 'Get the cash-impact summary (unreconciled financial exposure, with ' +
21
+ 'currency and age breakdowns) for a reconciliation context. Pass ' +
22
+ 'contextId (UUID path param — not a tenant field), and optionally ' +
23
+ 'date_from/date_to (YYYY-MM-DD; matcher defaults to the last 30 days and ' +
24
+ 'caps the window at 90 days) and/or source_id (UUID data filter). No ' +
25
+ 'tenant field is accepted.',
26
+ inputSchema: dashboardCashImpactInputShape,
27
+ }, async (args, extra) => {
28
+ const query = buildDashboardQuery(args);
29
+ return dispatchDashboard({
30
+ method: 'GET',
31
+ path: contextDashboardSlicePath(args.contextId, 'cash-impact'),
32
+ ...(query !== undefined ? { query } : {}),
33
+ }, extra);
34
+ });
35
+ }
36
+ //# sourceMappingURL=cash-impact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cash-impact.js","sourceRoot":"","sources":["../../../src/tools/dashboard/cash-impact.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,0DAA0D;AAC1D,EAAE;AACF,yEAAyE;AACzE,8EAA8E;AAC9E,gFAAgF;AAChF,+EAA+E;AAC/E,iDAAiD;AAIjD,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,aAAa,CAAA;AAEpB,oFAAoF;AACpF,MAAM,CAAC,MAAM,6BAA6B,GAAG,wBAAwB,CAAA;AAErE;;;;;GAKG;AACH,MAAM,UAAU,+BAA+B,CAAC,MAAiB;IAC/D,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,WAAW,EACT,qEAAqE;YACrE,kEAAkE;YAClE,mEAAmE;YACnE,0EAA0E;YAC1E,sEAAsE;YACtE,2BAA2B;QAC7B,WAAW,EAAE,6BAA6B;KAC3C,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAA;QACvC,OAAO,iBAAiB,CACtB;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,yBAAyB,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC;YAC9D,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1C,EACD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,27 @@
1
+ // Curated dashboard vertical: seven typed reads over the matcher reporting
2
+ // dashboard surface — the combined aggregates plus six focused slices
3
+ // (cash-impact, match-rate, metrics, sla, source-breakdown, volume). Every op is
4
+ // a context-nested GET sharing one input shape (contextId path + optional
5
+ // date_from/date_to/source_id query) and the fail-closed relay (shared.ts) and
6
+ // the RFC 9457 → tool-error mapping (toToolError) with the generic surface, so
7
+ // curated and generic map matcher errors identically. No tool carries a tenant
8
+ // field; contextId is a routing path param matcher validates against the relayed
9
+ // token's tenant, and source_id is a data filter.
10
+ import { registerDashboardAggregatesTool } from './aggregates.js';
11
+ import { registerDashboardCashImpactTool } from './cash-impact.js';
12
+ import { registerDashboardMatchRateTool } from './match-rate.js';
13
+ import { registerDashboardMetricsTool } from './metrics.js';
14
+ import { registerDashboardSlaTool } from './sla.js';
15
+ import { registerDashboardSourceBreakdownTool } from './source-breakdown.js';
16
+ import { registerDashboardVolumeTool } from './volume.js';
17
+ /** Register all seven curated dashboard tools on the given server. */
18
+ export function registerDashboardTools(server) {
19
+ registerDashboardAggregatesTool(server);
20
+ registerDashboardCashImpactTool(server);
21
+ registerDashboardMatchRateTool(server);
22
+ registerDashboardMetricsTool(server);
23
+ registerDashboardSlaTool(server);
24
+ registerDashboardSourceBreakdownTool(server);
25
+ registerDashboardVolumeTool(server);
26
+ }
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/dashboard/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,sEAAsE;AACtE,iFAAiF;AACjF,0EAA0E;AAC1E,+EAA+E;AAC/E,+EAA+E;AAC/E,+EAA+E;AAC/E,iFAAiF;AACjF,kDAAkD;AAIlD,OAAO,EAAE,+BAA+B,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,EAAE,8BAA8B,EAAE,MAAM,iBAAiB,CAAA;AAChE,OAAO,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,oCAAoC,EAAE,MAAM,uBAAuB,CAAA;AAC5E,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AAEzD,sEAAsE;AACtE,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,+BAA+B,CAAC,MAAM,CAAC,CAAA;IACvC,+BAA+B,CAAC,MAAM,CAAC,CAAA;IACvC,8BAA8B,CAAC,MAAM,CAAC,CAAA;IACtC,4BAA4B,CAAC,MAAM,CAAC,CAAA;IACpC,wBAAwB,CAAC,MAAM,CAAC,CAAA;IAChC,oCAAoC,CAAC,MAAM,CAAC,CAAA;IAC5C,2BAA2B,CAAC,MAAM,CAAC,CAAA;AACrC,CAAC"}
@@ -0,0 +1,35 @@
1
+ // `dashboard_match_rate` — curated GET
2
+ // /v1/reports/contexts/{contextId}/dashboard/match-rate.
3
+ //
4
+ // Match-rate percentage and trend data over the window (spec operationId
5
+ // getMatchRateStats). Shares the family input shape (contextId path + optional
6
+ // date_from/date_to/source_id query) and the fail-closed relay. contextId is a
7
+ // routing path param and source_id a data filter — neither is a tenant field,
8
+ // and no tenant field is accepted.
9
+ import { buildDashboardQuery, contextDashboardSlicePath, dashboardQueryInputShape, dispatchDashboard, } from './shared.js';
10
+ /** Zod raw shape for `dashboard_match_rate` input — the shared dashboard shape. */
11
+ export const dashboardMatchRateInputShape = dashboardQueryInputShape;
12
+ /**
13
+ * Register `dashboard_match_rate`. Dispatches a GET to the context's
14
+ * /dashboard/match-rate slice with the optional date/source query and returns
15
+ * matcher's match-rate stats verbatim; a matcher error surfaces via the shared
16
+ * toToolError.
17
+ */
18
+ export function registerDashboardMatchRateTool(server) {
19
+ server.registerTool('dashboard_match_rate', {
20
+ description: 'Get the match-rate statistics (percentage plus trend) for a ' +
21
+ 'reconciliation context. Pass contextId (UUID path param — not a tenant ' +
22
+ 'field), and optionally date_from/date_to (YYYY-MM-DD; matcher defaults ' +
23
+ 'to the last 30 days and caps the window at 90 days) and/or source_id ' +
24
+ '(UUID data filter). No tenant field is accepted.',
25
+ inputSchema: dashboardMatchRateInputShape,
26
+ }, async (args, extra) => {
27
+ const query = buildDashboardQuery(args);
28
+ return dispatchDashboard({
29
+ method: 'GET',
30
+ path: contextDashboardSlicePath(args.contextId, 'match-rate'),
31
+ ...(query !== undefined ? { query } : {}),
32
+ }, extra);
33
+ });
34
+ }
35
+ //# sourceMappingURL=match-rate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"match-rate.js","sourceRoot":"","sources":["../../../src/tools/dashboard/match-rate.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,yDAAyD;AACzD,EAAE;AACF,yEAAyE;AACzE,+EAA+E;AAC/E,+EAA+E;AAC/E,8EAA8E;AAC9E,mCAAmC;AAInC,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,aAAa,CAAA;AAEpB,mFAAmF;AACnF,MAAM,CAAC,MAAM,4BAA4B,GAAG,wBAAwB,CAAA;AAEpE;;;;;GAKG;AACH,MAAM,UAAU,8BAA8B,CAAC,MAAiB;IAC9D,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,WAAW,EACT,8DAA8D;YAC9D,yEAAyE;YACzE,yEAAyE;YACzE,uEAAuE;YACvE,kDAAkD;QACpD,WAAW,EAAE,4BAA4B;KAC1C,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAA;QACvC,OAAO,iBAAiB,CACtB;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,yBAAyB,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC;YAC7D,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1C,EACD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,36 @@
1
+ // `dashboard_metrics` — curated GET
2
+ // /v1/reports/contexts/{contextId}/dashboard/metrics.
3
+ //
4
+ // The complete Command Center metrics: summary, trends, and breakdowns in one
5
+ // payload (spec operationId getMatcherDashboardMetrics). Shares the family input
6
+ // shape (contextId path + optional date_from/date_to/source_id query) and the
7
+ // fail-closed relay. contextId is a routing path param and source_id a data
8
+ // filter — neither is a tenant field, and no tenant field is accepted.
9
+ import { buildDashboardQuery, contextDashboardSlicePath, dashboardQueryInputShape, dispatchDashboard, } from './shared.js';
10
+ /** Zod raw shape for `dashboard_metrics` input — the shared dashboard shape. */
11
+ export const dashboardMetricsInputShape = dashboardQueryInputShape;
12
+ /**
13
+ * Register `dashboard_metrics`. Dispatches a GET to the context's
14
+ * /dashboard/metrics slice with the optional date/source query and returns
15
+ * matcher's comprehensive metrics verbatim; a matcher error surfaces via the
16
+ * shared toToolError.
17
+ */
18
+ export function registerDashboardMetricsTool(server) {
19
+ server.registerTool('dashboard_metrics', {
20
+ description: 'Get the comprehensive Command Center dashboard metrics (summary, ' +
21
+ 'trends, and breakdowns) for a reconciliation context. Pass contextId ' +
22
+ '(UUID path param — not a tenant field), and optionally date_from/' +
23
+ 'date_to (YYYY-MM-DD; matcher defaults to the last 30 days and caps the ' +
24
+ 'window at 90 days) and/or source_id (UUID data filter). No tenant field ' +
25
+ 'is accepted.',
26
+ inputSchema: dashboardMetricsInputShape,
27
+ }, async (args, extra) => {
28
+ const query = buildDashboardQuery(args);
29
+ return dispatchDashboard({
30
+ method: 'GET',
31
+ path: contextDashboardSlicePath(args.contextId, 'metrics'),
32
+ ...(query !== undefined ? { query } : {}),
33
+ }, extra);
34
+ });
35
+ }
36
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../src/tools/dashboard/metrics.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,sDAAsD;AACtD,EAAE;AACF,8EAA8E;AAC9E,iFAAiF;AACjF,8EAA8E;AAC9E,4EAA4E;AAC5E,uEAAuE;AAIvE,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,aAAa,CAAA;AAEpB,gFAAgF;AAChF,MAAM,CAAC,MAAM,0BAA0B,GAAG,wBAAwB,CAAA;AAElE;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B,CAAC,MAAiB;IAC5D,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,WAAW,EACT,mEAAmE;YACnE,uEAAuE;YACvE,mEAAmE;YACnE,yEAAyE;YACzE,0EAA0E;YAC1E,cAAc;QAChB,WAAW,EAAE,0BAA0B;KACxC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAA;QACvC,OAAO,iBAAiB,CACtB;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,yBAAyB,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC;YAC1D,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1C,EACD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}