@atbas/m-mcp 0.1.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 (366) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +364 -0
  3. package/dist/builder/transaction-builder.d.ts +53 -0
  4. package/dist/builder/transaction-builder.d.ts.map +1 -0
  5. package/dist/builder/transaction-builder.js +159 -0
  6. package/dist/builder/transaction-builder.js.map +1 -0
  7. package/dist/catalogue/default-catalogue.d.ts +18 -0
  8. package/dist/catalogue/default-catalogue.d.ts.map +1 -0
  9. package/dist/catalogue/default-catalogue.js +21 -0
  10. package/dist/catalogue/default-catalogue.js.map +1 -0
  11. package/dist/catalogue/endpoints.d.ts +22 -0
  12. package/dist/catalogue/endpoints.d.ts.map +1 -0
  13. package/dist/catalogue/endpoints.js +24 -0
  14. package/dist/catalogue/endpoints.js.map +1 -0
  15. package/dist/catalogue/flows.d.ts +32 -0
  16. package/dist/catalogue/flows.d.ts.map +1 -0
  17. package/dist/catalogue/flows.js +64 -0
  18. package/dist/catalogue/flows.js.map +1 -0
  19. package/dist/catalogue/hash-options.d.ts +112 -0
  20. package/dist/catalogue/hash-options.d.ts.map +1 -0
  21. package/dist/catalogue/hash-options.js +151 -0
  22. package/dist/catalogue/hash-options.js.map +1 -0
  23. package/dist/catalogue/types.d.ts +279 -0
  24. package/dist/catalogue/types.d.ts.map +1 -0
  25. package/dist/catalogue/types.js +360 -0
  26. package/dist/catalogue/types.js.map +1 -0
  27. package/dist/codegen/generate.d.ts +14 -0
  28. package/dist/codegen/generate.d.ts.map +1 -0
  29. package/dist/codegen/generate.js +490 -0
  30. package/dist/codegen/generate.js.map +1 -0
  31. package/dist/codegen/languages/node.d.ts +3 -0
  32. package/dist/codegen/languages/node.d.ts.map +1 -0
  33. package/dist/codegen/languages/node.js +32 -0
  34. package/dist/codegen/languages/node.js.map +1 -0
  35. package/dist/codegen/languages/php.d.ts +3 -0
  36. package/dist/codegen/languages/php.d.ts.map +1 -0
  37. package/dist/codegen/languages/php.js +27 -0
  38. package/dist/codegen/languages/php.js.map +1 -0
  39. package/dist/codegen/languages/python.d.ts +3 -0
  40. package/dist/codegen/languages/python.d.ts.map +1 -0
  41. package/dist/codegen/languages/python.js +27 -0
  42. package/dist/codegen/languages/python.js.map +1 -0
  43. package/dist/codegen/renderer.d.ts +24 -0
  44. package/dist/codegen/renderer.d.ts.map +1 -0
  45. package/dist/codegen/renderer.js +59 -0
  46. package/dist/codegen/renderer.js.map +1 -0
  47. package/dist/codegen/types.d.ts +50 -0
  48. package/dist/codegen/types.d.ts.map +1 -0
  49. package/dist/codegen/types.js +5 -0
  50. package/dist/codegen/types.js.map +1 -0
  51. package/dist/config/credentials.d.ts +64 -0
  52. package/dist/config/credentials.d.ts.map +1 -0
  53. package/dist/config/credentials.js +216 -0
  54. package/dist/config/credentials.js.map +1 -0
  55. package/dist/config/environment.d.ts +23 -0
  56. package/dist/config/environment.d.ts.map +1 -0
  57. package/dist/config/environment.js +54 -0
  58. package/dist/config/environment.js.map +1 -0
  59. package/dist/core/dependencies.d.ts +43 -0
  60. package/dist/core/dependencies.d.ts.map +1 -0
  61. package/dist/core/dependencies.js +2 -0
  62. package/dist/core/dependencies.js.map +1 -0
  63. package/dist/core/registry.d.ts +33 -0
  64. package/dist/core/registry.d.ts.map +1 -0
  65. package/dist/core/registry.js +13 -0
  66. package/dist/core/registry.js.map +1 -0
  67. package/dist/core/server.d.ts +61 -0
  68. package/dist/core/server.d.ts.map +1 -0
  69. package/dist/core/server.js +90 -0
  70. package/dist/core/server.js.map +1 -0
  71. package/dist/dependencies.d.ts +28 -0
  72. package/dist/dependencies.d.ts.map +1 -0
  73. package/dist/dependencies.js +2 -0
  74. package/dist/dependencies.js.map +1 -0
  75. package/dist/diagnostics/diagnose.d.ts +43 -0
  76. package/dist/diagnostics/diagnose.d.ts.map +1 -0
  77. package/dist/diagnostics/diagnose.js +121 -0
  78. package/dist/diagnostics/diagnose.js.map +1 -0
  79. package/dist/domain/amount.d.ts +157 -0
  80. package/dist/domain/amount.d.ts.map +1 -0
  81. package/dist/domain/amount.js +275 -0
  82. package/dist/domain/amount.js.map +1 -0
  83. package/dist/domain/datetime.d.ts +95 -0
  84. package/dist/domain/datetime.d.ts.map +1 -0
  85. package/dist/domain/datetime.js +211 -0
  86. package/dist/domain/datetime.js.map +1 -0
  87. package/dist/domain/response-codes.d.ts +116 -0
  88. package/dist/domain/response-codes.d.ts.map +1 -0
  89. package/dist/domain/response-codes.js +380 -0
  90. package/dist/domain/response-codes.js.map +1 -0
  91. package/dist/domain/secure-hash.d.ts +78 -0
  92. package/dist/domain/secure-hash.d.ts.map +1 -0
  93. package/dist/domain/secure-hash.js +69 -0
  94. package/dist/domain/secure-hash.js.map +1 -0
  95. package/dist/domain/signature/jazzcash.d.ts +56 -0
  96. package/dist/domain/signature/jazzcash.d.ts.map +1 -0
  97. package/dist/domain/signature/jazzcash.js +214 -0
  98. package/dist/domain/signature/jazzcash.js.map +1 -0
  99. package/dist/domain/signature/registry.d.ts +69 -0
  100. package/dist/domain/signature/registry.d.ts.map +1 -0
  101. package/dist/domain/signature/registry.js +92 -0
  102. package/dist/domain/signature/registry.js.map +1 -0
  103. package/dist/domain/signature/scheme.d.ts +349 -0
  104. package/dist/domain/signature/scheme.d.ts.map +1 -0
  105. package/dist/domain/signature/scheme.js +398 -0
  106. package/dist/domain/signature/scheme.js.map +1 -0
  107. package/dist/domain/txn-ref.d.ts +76 -0
  108. package/dist/domain/txn-ref.d.ts.map +1 -0
  109. package/dist/domain/txn-ref.js +126 -0
  110. package/dist/domain/txn-ref.js.map +1 -0
  111. package/dist/domain/types.d.ts +45 -0
  112. package/dist/domain/types.d.ts.map +1 -0
  113. package/dist/domain/types.js +70 -0
  114. package/dist/domain/types.js.map +1 -0
  115. package/dist/errors.d.ts +84 -0
  116. package/dist/errors.d.ts.map +1 -0
  117. package/dist/errors.js +87 -0
  118. package/dist/errors.js.map +1 -0
  119. package/dist/gateway/checkout-form.d.ts +16 -0
  120. package/dist/gateway/checkout-form.d.ts.map +1 -0
  121. package/dist/gateway/checkout-form.js +103 -0
  122. package/dist/gateway/checkout-form.js.map +1 -0
  123. package/dist/gateway/checkout-output.d.ts +70 -0
  124. package/dist/gateway/checkout-output.d.ts.map +1 -0
  125. package/dist/gateway/checkout-output.js +199 -0
  126. package/dist/gateway/checkout-output.js.map +1 -0
  127. package/dist/gateway/guards.d.ts +37 -0
  128. package/dist/gateway/guards.d.ts.map +1 -0
  129. package/dist/gateway/guards.js +44 -0
  130. package/dist/gateway/guards.js.map +1 -0
  131. package/dist/gateway/http-client.d.ts +42 -0
  132. package/dist/gateway/http-client.d.ts.map +1 -0
  133. package/dist/gateway/http-client.js +153 -0
  134. package/dist/gateway/http-client.js.map +1 -0
  135. package/dist/gateway/rest-client.d.ts +42 -0
  136. package/dist/gateway/rest-client.d.ts.map +1 -0
  137. package/dist/gateway/rest-client.js +241 -0
  138. package/dist/gateway/rest-client.js.map +1 -0
  139. package/dist/gateway/transport.d.ts +31 -0
  140. package/dist/gateway/transport.d.ts.map +1 -0
  141. package/dist/gateway/transport.js +73 -0
  142. package/dist/gateway/transport.js.map +1 -0
  143. package/dist/index.d.ts +3 -0
  144. package/dist/index.d.ts.map +1 -0
  145. package/dist/index.js +75 -0
  146. package/dist/index.js.map +1 -0
  147. package/dist/install/cli.d.ts +38 -0
  148. package/dist/install/cli.d.ts.map +1 -0
  149. package/dist/install/cli.js +274 -0
  150. package/dist/install/cli.js.map +1 -0
  151. package/dist/install/harnesses.d.ts +74 -0
  152. package/dist/install/harnesses.d.ts.map +1 -0
  153. package/dist/install/harnesses.js +263 -0
  154. package/dist/install/harnesses.js.map +1 -0
  155. package/dist/knowledge/corpus.d.ts +15 -0
  156. package/dist/knowledge/corpus.d.ts.map +1 -0
  157. package/dist/knowledge/corpus.js +129 -0
  158. package/dist/knowledge/corpus.js.map +1 -0
  159. package/dist/knowledge/search.d.ts +29 -0
  160. package/dist/knowledge/search.d.ts.map +1 -0
  161. package/dist/knowledge/search.js +181 -0
  162. package/dist/knowledge/search.js.map +1 -0
  163. package/dist/knowledge/source.d.ts +60 -0
  164. package/dist/knowledge/source.d.ts.map +1 -0
  165. package/dist/knowledge/source.js +91 -0
  166. package/dist/knowledge/source.js.map +1 -0
  167. package/dist/knowledge/types.d.ts +40 -0
  168. package/dist/knowledge/types.d.ts.map +1 -0
  169. package/dist/knowledge/types.js +19 -0
  170. package/dist/knowledge/types.js.map +1 -0
  171. package/dist/paths.d.ts +26 -0
  172. package/dist/paths.d.ts.map +1 -0
  173. package/dist/paths.js +106 -0
  174. package/dist/paths.js.map +1 -0
  175. package/dist/prompts/integration-walkthrough.d.ts +11 -0
  176. package/dist/prompts/integration-walkthrough.d.ts.map +1 -0
  177. package/dist/prompts/integration-walkthrough.js +52 -0
  178. package/dist/prompts/integration-walkthrough.js.map +1 -0
  179. package/dist/prompts/register.d.ts +4 -0
  180. package/dist/prompts/register.d.ts.map +1 -0
  181. package/dist/prompts/register.js +4 -0
  182. package/dist/prompts/register.js.map +1 -0
  183. package/dist/registry.d.ts +14 -0
  184. package/dist/registry.d.ts.map +1 -0
  185. package/dist/registry.js +2 -0
  186. package/dist/registry.js.map +1 -0
  187. package/dist/resources/knowledge-resources.d.ts +5 -0
  188. package/dist/resources/knowledge-resources.d.ts.map +1 -0
  189. package/dist/resources/knowledge-resources.js +121 -0
  190. package/dist/resources/knowledge-resources.js.map +1 -0
  191. package/dist/resources/register.d.ts +4 -0
  192. package/dist/resources/register.d.ts.map +1 -0
  193. package/dist/resources/register.js +8 -0
  194. package/dist/resources/register.js.map +1 -0
  195. package/dist/server.d.ts +40 -0
  196. package/dist/server.d.ts.map +1 -0
  197. package/dist/server.js +56 -0
  198. package/dist/server.js.map +1 -0
  199. package/dist/telemetry/logger.d.ts +31 -0
  200. package/dist/telemetry/logger.d.ts.map +1 -0
  201. package/dist/telemetry/logger.js +67 -0
  202. package/dist/telemetry/logger.js.map +1 -0
  203. package/dist/telemetry/redaction.d.ts +88 -0
  204. package/dist/telemetry/redaction.d.ts.map +1 -0
  205. package/dist/telemetry/redaction.js +238 -0
  206. package/dist/telemetry/redaction.js.map +1 -0
  207. package/dist/tools/build-transaction-parameters.d.ts +10 -0
  208. package/dist/tools/build-transaction-parameters.d.ts.map +1 -0
  209. package/dist/tools/build-transaction-parameters.js +154 -0
  210. package/dist/tools/build-transaction-parameters.js.map +1 -0
  211. package/dist/tools/call-context.d.ts +47 -0
  212. package/dist/tools/call-context.d.ts.map +1 -0
  213. package/dist/tools/call-context.js +15 -0
  214. package/dist/tools/call-context.js.map +1 -0
  215. package/dist/tools/codegen-tools.d.ts +4 -0
  216. package/dist/tools/codegen-tools.d.ts.map +1 -0
  217. package/dist/tools/codegen-tools.js +131 -0
  218. package/dist/tools/codegen-tools.js.map +1 -0
  219. package/dist/tools/credential-tools.d.ts +32 -0
  220. package/dist/tools/credential-tools.d.ts.map +1 -0
  221. package/dist/tools/credential-tools.js +65 -0
  222. package/dist/tools/credential-tools.js.map +1 -0
  223. package/dist/tools/descriptor.d.ts +52 -0
  224. package/dist/tools/descriptor.d.ts.map +1 -0
  225. package/dist/tools/descriptor.js +2 -0
  226. package/dist/tools/descriptor.js.map +1 -0
  227. package/dist/tools/diagnostic-tools.d.ts +3 -0
  228. package/dist/tools/diagnostic-tools.d.ts.map +1 -0
  229. package/dist/tools/diagnostic-tools.js +128 -0
  230. package/dist/tools/diagnostic-tools.js.map +1 -0
  231. package/dist/tools/gateway-tools.d.ts +6 -0
  232. package/dist/tools/gateway-tools.d.ts.map +1 -0
  233. package/dist/tools/gateway-tools.js +381 -0
  234. package/dist/tools/gateway-tools.js.map +1 -0
  235. package/dist/tools/hash-tools.d.ts +5 -0
  236. package/dist/tools/hash-tools.d.ts.map +1 -0
  237. package/dist/tools/hash-tools.js +238 -0
  238. package/dist/tools/hash-tools.js.map +1 -0
  239. package/dist/tools/knowledge-tools.d.ts +7 -0
  240. package/dist/tools/knowledge-tools.d.ts.map +1 -0
  241. package/dist/tools/knowledge-tools.js +247 -0
  242. package/dist/tools/knowledge-tools.js.map +1 -0
  243. package/dist/tools/onboarding-checklist.d.ts +3 -0
  244. package/dist/tools/onboarding-checklist.d.ts.map +1 -0
  245. package/dist/tools/onboarding-checklist.js +141 -0
  246. package/dist/tools/onboarding-checklist.js.map +1 -0
  247. package/dist/tools/register.d.ts +60 -0
  248. package/dist/tools/register.d.ts.map +1 -0
  249. package/dist/tools/register.js +145 -0
  250. package/dist/tools/register.js.map +1 -0
  251. package/dist/tools/tool-kit.d.ts +88 -0
  252. package/dist/tools/tool-kit.d.ts.map +1 -0
  253. package/dist/tools/tool-kit.js +297 -0
  254. package/dist/tools/tool-kit.js.map +1 -0
  255. package/dist/validation/payload-validator.d.ts +29 -0
  256. package/dist/validation/payload-validator.d.ts.map +1 -0
  257. package/dist/validation/payload-validator.js +79 -0
  258. package/dist/validation/payload-validator.js.map +1 -0
  259. package/dist/validation/rules/amount.d.ts +3 -0
  260. package/dist/validation/rules/amount.d.ts.map +1 -0
  261. package/dist/validation/rules/amount.js +77 -0
  262. package/dist/validation/rules/amount.js.map +1 -0
  263. package/dist/validation/rules/bill-reference.d.ts +10 -0
  264. package/dist/validation/rules/bill-reference.d.ts.map +1 -0
  265. package/dist/validation/rules/bill-reference.js +34 -0
  266. package/dist/validation/rules/bill-reference.js.map +1 -0
  267. package/dist/validation/rules/cnic.d.ts +3 -0
  268. package/dist/validation/rules/cnic.d.ts.map +1 -0
  269. package/dist/validation/rules/cnic.js +42 -0
  270. package/dist/validation/rules/cnic.js.map +1 -0
  271. package/dist/validation/rules/constants.d.ts +9 -0
  272. package/dist/validation/rules/constants.d.ts.map +1 -0
  273. package/dist/validation/rules/constants.js +28 -0
  274. package/dist/validation/rules/constants.js.map +1 -0
  275. package/dist/validation/rules/constraints.d.ts +3 -0
  276. package/dist/validation/rules/constraints.d.ts.map +1 -0
  277. package/dist/validation/rules/constraints.js +113 -0
  278. package/dist/validation/rules/constraints.js.map +1 -0
  279. package/dist/validation/rules/datetime.d.ts +3 -0
  280. package/dist/validation/rules/datetime.d.ts.map +1 -0
  281. package/dist/validation/rules/datetime.js +49 -0
  282. package/dist/validation/rules/datetime.js.map +1 -0
  283. package/dist/validation/rules/empty-string.d.ts +13 -0
  284. package/dist/validation/rules/empty-string.d.ts.map +1 -0
  285. package/dist/validation/rules/empty-string.js +32 -0
  286. package/dist/validation/rules/empty-string.js.map +1 -0
  287. package/dist/validation/rules/expiry.d.ts +3 -0
  288. package/dist/validation/rules/expiry.d.ts.map +1 -0
  289. package/dist/validation/rules/expiry.js +52 -0
  290. package/dist/validation/rules/expiry.js.map +1 -0
  291. package/dist/validation/rules/msisdn.d.ts +3 -0
  292. package/dist/validation/rules/msisdn.d.ts.map +1 -0
  293. package/dist/validation/rules/msisdn.js +45 -0
  294. package/dist/validation/rules/msisdn.js.map +1 -0
  295. package/dist/validation/rules/presence.d.ts +3 -0
  296. package/dist/validation/rules/presence.d.ts.map +1 -0
  297. package/dist/validation/rules/presence.js +90 -0
  298. package/dist/validation/rules/presence.js.map +1 -0
  299. package/dist/validation/rules/return-url.d.ts +14 -0
  300. package/dist/validation/rules/return-url.d.ts.map +1 -0
  301. package/dist/validation/rules/return-url.js +58 -0
  302. package/dist/validation/rules/return-url.js.map +1 -0
  303. package/dist/validation/rules/tool-argument.d.ts +16 -0
  304. package/dist/validation/rules/tool-argument.d.ts.map +1 -0
  305. package/dist/validation/rules/tool-argument.js +38 -0
  306. package/dist/validation/rules/tool-argument.js.map +1 -0
  307. package/dist/validation/rules/txn-ref.d.ts +3 -0
  308. package/dist/validation/rules/txn-ref.d.ts.map +1 -0
  309. package/dist/validation/rules/txn-ref.js +47 -0
  310. package/dist/validation/rules/txn-ref.js.map +1 -0
  311. package/dist/validation/rules/unknown-fields.d.ts +10 -0
  312. package/dist/validation/rules/unknown-fields.d.ts.map +1 -0
  313. package/dist/validation/rules/unknown-fields.js +29 -0
  314. package/dist/validation/rules/unknown-fields.js.map +1 -0
  315. package/dist/validation/types.d.ts +36 -0
  316. package/dist/validation/types.d.ts.map +1 -0
  317. package/dist/validation/types.js +12 -0
  318. package/dist/validation/types.js.map +1 -0
  319. package/dist/version.d.ts +23 -0
  320. package/dist/version.d.ts.map +1 -0
  321. package/dist/version.js +23 -0
  322. package/dist/version.js.map +1 -0
  323. package/knowledge/diagnostics/symptoms.json +321 -0
  324. package/knowledge/docs/bnpl-guide.md +77 -0
  325. package/knowledge/docs/card-page-redirection.md +67 -0
  326. package/knowledge/docs/card-refund.md +91 -0
  327. package/knowledge/docs/hmac-sha256-calculation.md +72 -0
  328. package/knowledge/docs/index.json +189 -0
  329. package/knowledge/docs/ipn-implementation.md +89 -0
  330. package/knowledge/docs/mwallet-recurring.md +117 -0
  331. package/knowledge/docs/mwallet-refund.md +65 -0
  332. package/knowledge/docs/mwallet-rest-v1-1.md +126 -0
  333. package/knowledge/docs/mwallet-rest-v2-0-cnic.md +113 -0
  334. package/knowledge/docs/portal-guide.md +45 -0
  335. package/knowledge/docs/shopify-guide.md +74 -0
  336. package/knowledge/docs/status-inquiry-2025-26.md +32 -0
  337. package/knowledge/docs/status-inquiry.md +111 -0
  338. package/knowledge/docs/wordpress-guide.md +49 -0
  339. package/knowledge/flow.schema.json +390 -0
  340. package/knowledge/flows/bnpl-page-redirection-v1.1.json +211 -0
  341. package/knowledge/flows/card-page-redirection-v1.1.json +211 -0
  342. package/knowledge/flows/mwallet-rest-v1.1.json +187 -0
  343. package/knowledge/flows/mwallet-rest-v2.0-cnic.json +197 -0
  344. package/knowledge/flows/mwallet-token-pay-v4.0.json +130 -0
  345. package/knowledge/flows/refund-bnpl.json +105 -0
  346. package/knowledge/flows/refund-card-v1.1.json +112 -0
  347. package/knowledge/flows/refund-card-v2.0.json +121 -0
  348. package/knowledge/flows/refund-mwallet-v1.1.json +106 -0
  349. package/knowledge/flows/status-inquiry-v1.1.json +102 -0
  350. package/knowledge/flows/status-inquiry-v2.0.json +103 -0
  351. package/knowledge/flows/token-delete-v1.json +85 -0
  352. package/knowledge/flows/token-inquiry-v1.json +85 -0
  353. package/knowledge/flows/wallet-linking-portal.json +103 -0
  354. package/knowledge/templates/node/checkout-redirect.tmpl +166 -0
  355. package/knowledge/templates/node/ipn-handler.tmpl +108 -0
  356. package/knowledge/templates/node/rest-client.tmpl +197 -0
  357. package/knowledge/templates/node/wallet-linking.tmpl +147 -0
  358. package/knowledge/templates/php/checkout-redirect.tmpl +149 -0
  359. package/knowledge/templates/php/ipn-handler.tmpl +105 -0
  360. package/knowledge/templates/php/rest-client.tmpl +191 -0
  361. package/knowledge/templates/php/wallet-linking.tmpl +137 -0
  362. package/knowledge/templates/python/checkout-redirect.tmpl +148 -0
  363. package/knowledge/templates/python/ipn-handler.tmpl +110 -0
  364. package/knowledge/templates/python/rest-client.tmpl +179 -0
  365. package/knowledge/templates/python/wallet-linking.tmpl +133 -0
  366. package/package.json +84 -0
package/dist/paths.js ADDED
@@ -0,0 +1,106 @@
1
+ import { existsSync, statSync } from 'node:fs';
2
+ import { dirname, isAbsolute, join, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { JazzCashConfigError } from './errors.js';
5
+ /**
6
+ * Locate the package root, and the bundled knowledge corpus within it.
7
+ *
8
+ * The two are resolved separately and in that order. Requiring the root to
9
+ * contain `knowledge/` as well would make "where is this package installed" a
10
+ * question the corpus can answer wrongly: relocating the corpus, or serving it
11
+ * from somewhere that is not a directory at all, would break the same walk that
12
+ * also resolves `dist/`. `package.json`
13
+ * is the marker that actually defines a package root, so the walk asks for that
14
+ * and nothing else.
15
+ *
16
+ * The walk works unchanged from `src/` during development and from `dist/` after
17
+ * a build, which avoids a copy step and the class of bug where the built server
18
+ * silently serves a stale corpus.
19
+ */
20
+ /** The file that marks the directory owning a package. */
21
+ const PACKAGE_MARKER = 'package.json';
22
+ /** Where the bundled corpus sits, relative to the package root. */
23
+ const CORPUS_DIRECTORY = 'knowledge';
24
+ /**
25
+ * Environment variable naming the corpus directory outright.
26
+ *
27
+ * The package-root walk starts from `import.meta.url`, which is only the truth
28
+ * while the module is executed as a file inside its own package. A bundler
29
+ * rewrites that value: hosting this server inside a Next.js route handler
30
+ * resolves the walk into `.next/`, whose `package.json` is real and whose
31
+ * `knowledge/` does not exist. The corpus loader then finds no documents, the
32
+ * search index is built over nothing, and the server answers merchant
33
+ * integration questions from an empty knowledge base — confidently, because
34
+ * nothing in that path fails. That is the worst failure mode this server has, so
35
+ * a deployment that knows where the corpus is says so instead of hoping.
36
+ *
37
+ * Deliberately not a tool argument, and deliberately not relative: resolving a
38
+ * relative path would anchor the corpus to the working directory of whichever
39
+ * process happened to start the server, which is exactly the unpredictable input
40
+ * this variable exists to remove.
41
+ */
42
+ const CORPUS_DIRECTORY_VARIABLE = 'MCP_CORPUS_DIR';
43
+ let cachedRoot;
44
+ /**
45
+ * Walk upwards to the nearest directory that owns a `package.json`.
46
+ *
47
+ * Exported so the walk can be exercised from somewhere other than this module's
48
+ * own directory, which is the only way to prove that moving the corpus leaves
49
+ * root discovery intact.
50
+ */
51
+ export function findPackageRoot(startDirectory) {
52
+ let current = resolve(startDirectory);
53
+ for (;;) {
54
+ if (existsSync(join(current, PACKAGE_MARKER))) {
55
+ return current;
56
+ }
57
+ const parent = dirname(current);
58
+ if (parent === current) {
59
+ throw new JazzCashConfigError(`Unable to locate the package root. Searched upwards from ${startDirectory} for a directory containing ${PACKAGE_MARKER}.`);
60
+ }
61
+ current = parent;
62
+ }
63
+ }
64
+ /** Absolute path to the package root. Cached after the first successful walk. */
65
+ export function packageRoot() {
66
+ cachedRoot ??= findPackageRoot(dirname(fileURLToPath(import.meta.url)));
67
+ return cachedRoot;
68
+ }
69
+ /**
70
+ * Absolute path to the directory holding the bundled corpus.
71
+ *
72
+ * Derived from the package root rather than being what identifies it, so this is
73
+ * the single place that has to change if the corpus stops shipping beside the
74
+ * code — and the single place `MCP_CORPUS_DIR` has to override.
75
+ *
76
+ * The override is validated on every call rather than memoised: the check is one
77
+ * `stat` in front of a file read that is about to happen anyway, and a cached
78
+ * answer would make the variable unreadable to anything that sets it after this
79
+ * module was first imported.
80
+ */
81
+ export function corpusRoot() {
82
+ const configured = process.env[CORPUS_DIRECTORY_VARIABLE]?.trim() ?? '';
83
+ if (configured === '') {
84
+ return join(packageRoot(), CORPUS_DIRECTORY);
85
+ }
86
+ // Refused rather than resolved against `process.cwd()`. A silently resolved
87
+ // relative path would either find a corpus nobody meant to serve, or fall
88
+ // through to the empty-knowledge-base failure this variable exists to prevent.
89
+ if (!isAbsolute(configured)) {
90
+ throw new JazzCashConfigError(`${CORPUS_DIRECTORY_VARIABLE} must be an absolute path, but is "${configured}". A relative path would be resolved against the working directory of whichever process started the server, which is not something this server can predict.`);
91
+ }
92
+ // Checked here, at the one place the corpus is located, rather than left to
93
+ // the loader: an absent or mistyped directory yields no documents, and a
94
+ // server that serves no documents answers merchant questions from nothing
95
+ // instead of refusing to start.
96
+ const stats = statSync(configured, { throwIfNoEntry: false });
97
+ if (stats?.isDirectory() !== true) {
98
+ throw new JazzCashConfigError(`${CORPUS_DIRECTORY_VARIABLE} is set to "${configured}", which is not an existing directory. Point it at the ${CORPUS_DIRECTORY}/ directory that ships with this package, or unset it to resolve the corpus from the package root.`);
99
+ }
100
+ return configured;
101
+ }
102
+ /** Absolute path to `knowledge/`, optionally joined with further segments. */
103
+ export function knowledgePath(...segments) {
104
+ return join(corpusRoot(), ...segments);
105
+ }
106
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;;;;;;;;GAcG;AAEH,0DAA0D;AAC1D,MAAM,cAAc,GAAG,cAAc,CAAC;AAEtC,mEAAmE;AACnE,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAErC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,yBAAyB,GAAG,gBAAgB,CAAC;AAEnD,IAAI,UAA8B,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,cAAsB;IACpD,IAAI,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAEtC,SAAS,CAAC;QACR,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;YAC9C,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB,MAAM,IAAI,mBAAmB,CAC3B,4DAA4D,cAAc,+BAA+B,cAAc,GAAG,CAC3H,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;AACH,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,WAAW;IACzB,UAAU,KAAK,eAAe,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACxE,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAExE,IAAI,UAAU,KAAK,EAAE,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC,WAAW,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAC/C,CAAC;IAED,4EAA4E;IAC5E,0EAA0E;IAC1E,+EAA+E;IAC/E,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,mBAAmB,CAC3B,GAAG,yBAAyB,sCAAsC,UAAU,6JAA6J,CAC1O,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,yEAAyE;IACzE,0EAA0E;IAC1E,gCAAgC;IAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9D,IAAI,KAAK,EAAE,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC;QAClC,MAAM,IAAI,mBAAmB,CAC3B,GAAG,yBAAyB,eAAe,UAAU,0DAA0D,gBAAgB,oGAAoG,CACpO,CAAC;IACJ,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,aAAa,CAAC,GAAG,QAA2B;IAC1D,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE,GAAG,QAAQ,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Registrar } from '../registry.js';
2
+ /**
3
+ * Guided integration walkthrough.
4
+ *
5
+ * Sequences the tools in the order a resident engineer works through them, so
6
+ * that a merchant's AI does not have to infer the order — which is where most
7
+ * self-directed integrations go wrong, typically by writing checkout code before
8
+ * establishing what the hash rules are.
9
+ */
10
+ export declare const registerIntegrationWalkthrough: Registrar;
11
+ //# sourceMappingURL=integration-walkthrough.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-walkthrough.d.ts","sourceRoot":"","sources":["../../src/prompts/integration-walkthrough.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,EAAE,SAgD5C,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Guided integration walkthrough.
4
+ *
5
+ * Sequences the tools in the order a resident engineer works through them, so
6
+ * that a merchant's AI does not have to infer the order — which is where most
7
+ * self-directed integrations go wrong, typically by writing checkout code before
8
+ * establishing what the hash rules are.
9
+ */
10
+ export const registerIntegrationWalkthrough = (server, deps) => {
11
+ server.registerPrompt('jazzcash_integration_walkthrough', {
12
+ title: 'JazzCash integration walkthrough',
13
+ description: 'Step-by-step guided integration: choose a flow, complete onboarding, generate code, test in sandbox, and go live.',
14
+ argsSchema: {
15
+ product: z.string().describe('What you want to accept: card, bnpl, mwallet, recurring, or refund.'),
16
+ platform: z.string().optional().describe('custom, woocommerce or shopify.'),
17
+ language: z.string().optional().describe('php, node or python.'),
18
+ },
19
+ }, ({ product, platform, language }) => {
20
+ const resolvedPlatform = platform ?? 'custom';
21
+ const resolvedLanguage = language ?? 'php';
22
+ const availableFlows = deps.catalogue
23
+ .list()
24
+ .map((flow) => `${flow.id} (${flow.product})`)
25
+ .join(', ');
26
+ const instructions = [
27
+ `I want to integrate JazzCash ${product} into a ${resolvedPlatform} application, writing ${resolvedLanguage}.`,
28
+ '',
29
+ 'Work through this in order, using the jazzcash_* tools rather than general knowledge of payment gateways. Cite the document behind each answer.',
30
+ '',
31
+ '1. Call `jazzcash_list_integration_flows` and recommend one flow, saying why.',
32
+ '2. Call `jazzcash_get_integration_flow` for it. Summarise the mandatory parameters and any known documentation defects.',
33
+ `3. Call \`jazzcash_get_onboarding_checklist\` with that flow and platform "${resolvedPlatform}". Tell me what I must do in the JazzCash portal before any code runs.`,
34
+ `4. Call \`jazzcash_generate_integration_code\` for ${resolvedLanguage}. Explain where each generated file belongs and what still needs configuring.`,
35
+ '5. Call `jazzcash_generate_ipn_handler`. IPN and Status Inquiry are mandatory, not optional — do not skip them.',
36
+ '6. Call `jazzcash_build_transaction_parameters` to produce one signed sandbox payload, and show it to me.',
37
+ '7. Explain how to run the sandbox test: `jazzcash_send_gateway_request` for a REST flow, or `jazzcash_build_checkout_form` for a hosted page, which needs a human in a browser.',
38
+ '8. Remind me what evidence JazzCash requires before go-live.',
39
+ '',
40
+ 'Rules for you:',
41
+ '- Never invent a parameter, endpoint or response code. If the corpus does not cover something, say so.',
42
+ '- Never compute the secure hash in browser JavaScript. The Integrity Salt is the HMAC key.',
43
+ '- Sandbox and production share identical endpoints, so remind me that going live is a credential change and to confirm which credentials are loaded before any live call.',
44
+ '',
45
+ `Flows available: ${availableFlows}.`,
46
+ ].join('\n');
47
+ return {
48
+ messages: [{ role: 'user', content: { type: 'text', text: instructions } }],
49
+ };
50
+ });
51
+ };
52
+ //# sourceMappingURL=integration-walkthrough.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-walkthrough.js","sourceRoot":"","sources":["../../src/prompts/integration-walkthrough.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAc,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;IACxE,MAAM,CAAC,cAAc,CACnB,kCAAkC,EAClC;QACE,KAAK,EAAE,kCAAkC;QACzC,WAAW,EACT,mHAAmH;QACrH,UAAU,EAAE;YACV,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qEAAqE,CAAC;YACnG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;YAC3E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;SACjE;KACF,EACD,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE;QAClC,MAAM,gBAAgB,GAAG,QAAQ,IAAI,QAAQ,CAAC;QAC9C,MAAM,gBAAgB,GAAG,QAAQ,IAAI,KAAK,CAAC;QAC3C,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS;aAClC,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,OAAO,GAAG,CAAC;aAC7C,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,MAAM,YAAY,GAAG;YACnB,gCAAgC,OAAO,WAAW,gBAAgB,yBAAyB,gBAAgB,GAAG;YAC9G,EAAE;YACF,iJAAiJ;YACjJ,EAAE;YACF,+EAA+E;YAC/E,yHAAyH;YACzH,8EAA8E,gBAAgB,wEAAwE;YACtK,sDAAsD,gBAAgB,+EAA+E;YACrJ,iHAAiH;YACjH,2GAA2G;YAC3G,iLAAiL;YACjL,8DAA8D;YAC9D,EAAE;YACF,gBAAgB;YAChB,wGAAwG;YACxG,4FAA4F;YAC5F,2KAA2K;YAC3K,EAAE;YACF,oBAAoB,cAAc,GAAG;SACtC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,OAAO;YACL,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Registrar } from '../registry.js';
2
+ /** Prompt registrars. */
3
+ export declare const ALL_PROMPTS: readonly Registrar[];
4
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/prompts/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,yBAAyB;AACzB,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAAqC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { registerIntegrationWalkthrough } from './integration-walkthrough.js';
2
+ /** Prompt registrars. */
3
+ export const ALL_PROMPTS = [registerIntegrationWalkthrough];
4
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/prompts/register.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAE9E,yBAAyB;AACzB,MAAM,CAAC,MAAM,WAAW,GAAyB,CAAC,8BAA8B,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { ServerDependencies } from './dependencies.js';
2
+ import type { RegistrarFor } from './core/registry.js';
3
+ export { applyRegistrars } from './core/registry.js';
4
+ /**
5
+ * Registration signature for a registrar that may read any part of the surface,
6
+ * including the documentation corpus.
7
+ *
8
+ * The default for tools, resources and prompts. A registrar that reads no corpus
9
+ * should be typed {@link import('./core/registry.js').CoreRegistrar} instead —
10
+ * it remains assignable here, so declaring the narrower type costs nothing and
11
+ * buys a compiler-checked claim about what the handler touches.
12
+ */
13
+ export type Registrar = RegistrarFor<ServerDependencies>;
14
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAOrD;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC,kBAAkB,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { applyRegistrars } from './core/registry.js';
2
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Registrar } from '../registry.js';
2
+ export declare const registerIndexResource: Registrar;
3
+ export declare const registerDocumentResources: Registrar;
4
+ export declare const registerFlowResources: Registrar;
5
+ //# sourceMappingURL=knowledge-resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-resources.d.ts","sourceRoot":"","sources":["../../src/resources/knowledge-resources.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA0ChD,eAAO,MAAM,qBAAqB,EAAE,SA0CnC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,SA0BvC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,SA0BnC,CAAC"}
@@ -0,0 +1,121 @@
1
+ import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { McpError } from '@modelcontextprotocol/sdk/types.js';
3
+ import { resolveEndpoint } from '../catalogue/endpoints.js';
4
+ import { JazzCashNotFoundError } from '../errors.js';
5
+ import { CORPUS_VERSION } from '../version.js';
6
+ /**
7
+ * Read-only resources.
8
+ *
9
+ * Clients that prefer to pull context rather than call a tool can read the
10
+ * corpus and the flow catalogue directly. URIs match the citations that tools
11
+ * emit, so a citation is always resolvable — and when one is not, the client is
12
+ * told that in the protocol's own vocabulary rather than as a server fault.
13
+ */
14
+ /**
15
+ * JSON-RPC code the MCP specification reserves for an unknown resource URI.
16
+ *
17
+ * Spelled out because the pinned SDK's `ErrorCode` enum has no member for it.
18
+ * Without the translation below, the thrown {@link JazzCashNotFoundError}
19
+ * carries a *string* code, and the protocol layer — which emits an error code
20
+ * only when it is a safe integer — reports every mistyped URI as `-32603`
21
+ * (internal error). A client then cannot tell its own typo from a broken server.
22
+ */
23
+ const RESOURCE_NOT_FOUND = -32002;
24
+ /**
25
+ * Read a resource, translating "no such entry" into the protocol's own code.
26
+ *
27
+ * Resource callbacks have no `isError` channel, so unlike the tool handlers they
28
+ * cannot use `safeHandler`: the error has to leave through the protocol layer.
29
+ * Anything other than a missing entry is rethrown untouched, so a genuine server
30
+ * fault is still reported as one.
31
+ */
32
+ function readOrNotFound(uri, read) {
33
+ try {
34
+ return read();
35
+ }
36
+ catch (error) {
37
+ if (error instanceof JazzCashNotFoundError) {
38
+ throw new McpError(RESOURCE_NOT_FOUND, error.message, { uri: uri.href });
39
+ }
40
+ throw error;
41
+ }
42
+ }
43
+ export const registerIndexResource = (server, deps) => {
44
+ server.registerResource('jazzcash-index', 'jazzcash://index', {
45
+ title: 'JazzCash corpus index',
46
+ description: 'Every document and integration flow this server knows about.',
47
+ mimeType: 'application/json',
48
+ }, (uri) => ({
49
+ contents: [
50
+ {
51
+ uri: uri.href,
52
+ mimeType: 'application/json',
53
+ text: JSON.stringify({
54
+ corpusVersion: CORPUS_VERSION,
55
+ documents: deps.corpus.documents().map((document) => ({
56
+ uri: `jazzcash://docs/${document.metadata.docId}`,
57
+ docId: document.metadata.docId,
58
+ title: document.metadata.title,
59
+ sourcePdf: document.metadata.sourcePdf,
60
+ version: document.metadata.version,
61
+ sections: document.sections.map((section) => ({ id: section.sectionId, title: section.title })),
62
+ })),
63
+ flows: deps.catalogue.list().map((flow) => ({
64
+ uri: `jazzcash://flows/${flow.id}`,
65
+ id: flow.id,
66
+ title: flow.title,
67
+ product: flow.product,
68
+ transport: flow.transport,
69
+ movesMoney: flow.movesMoney,
70
+ endpoint: resolveEndpoint(flow, 'sandbox'),
71
+ })),
72
+ }, null, 2),
73
+ },
74
+ ],
75
+ }));
76
+ };
77
+ export const registerDocumentResources = (server, deps) => {
78
+ server.registerResource('jazzcash-doc', new ResourceTemplate('jazzcash://docs/{docId}', {
79
+ list: () => ({
80
+ resources: deps.corpus.documents().map((document) => ({
81
+ uri: `jazzcash://docs/${document.metadata.docId}`,
82
+ name: document.metadata.title,
83
+ description: `Curated from ${document.metadata.sourcePdf} (version ${document.metadata.version}).`,
84
+ mimeType: 'text/markdown',
85
+ })),
86
+ }),
87
+ }), {
88
+ title: 'JazzCash integration guide',
89
+ description: 'A curated JazzCash integration guide, transcribed from the official 2026 PDF.',
90
+ mimeType: 'text/markdown',
91
+ }, (uri, variables) => {
92
+ const docId = String(variables['docId']);
93
+ const document = readOrNotFound(uri, () => deps.corpus.document(docId));
94
+ return {
95
+ contents: [{ uri: uri.href, mimeType: 'text/markdown', text: document.markdown }],
96
+ };
97
+ });
98
+ };
99
+ export const registerFlowResources = (server, deps) => {
100
+ server.registerResource('jazzcash-flow', new ResourceTemplate('jazzcash://flows/{flowId}', {
101
+ list: () => ({
102
+ resources: deps.catalogue.list().map((flow) => ({
103
+ uri: `jazzcash://flows/${flow.id}`,
104
+ name: flow.title,
105
+ description: flow.useWhen,
106
+ mimeType: 'application/json',
107
+ })),
108
+ }),
109
+ }), {
110
+ title: 'JazzCash flow specification',
111
+ description: 'Machine-readable specification for one integration flow.',
112
+ mimeType: 'application/json',
113
+ }, (uri, variables) => {
114
+ const flowId = String(variables['flowId']);
115
+ const flow = readOrNotFound(uri, () => deps.catalogue.get(flowId));
116
+ return {
117
+ contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(flow, null, 2) }],
118
+ };
119
+ });
120
+ };
121
+ //# sourceMappingURL=knowledge-resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-resources.js","sourceRoot":"","sources":["../../src/resources/knowledge-resources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Registrar } from '../registry.js';
2
+ /** Resource registrars. */
3
+ export declare const ALL_RESOURCES: readonly Registrar[];
4
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/resources/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,2BAA2B;AAC3B,eAAO,MAAM,aAAa,EAAE,SAAS,SAAS,EAI7C,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { registerDocumentResources, registerFlowResources, registerIndexResource } from './knowledge-resources.js';
2
+ /** Resource registrars. */
3
+ export const ALL_RESOURCES = [
4
+ registerIndexResource,
5
+ registerDocumentResources,
6
+ registerFlowResources,
7
+ ];
8
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/resources/register.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEnH,2BAA2B;AAC3B,MAAM,CAAC,MAAM,aAAa,GAAyB;IACjD,qBAAqB;IACrB,yBAAyB;IACzB,qBAAqB;CACtB,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ServerDependencies } from './dependencies.js';
3
+ import { type Registrar } from './registry.js';
4
+ import { type ToolDescriptor } from './tools/register.js';
5
+ /**
6
+ * Composition root.
7
+ *
8
+ * Builds dependencies from the process environment, then hands them to the
9
+ * registration lists. It deliberately knows nothing about individual tools.
10
+ *
11
+ * The corpus-free half lives in `./core/server.js`, and this module adds the
12
+ * knowledge half on top. The split is not cosmetic: the three loaders imported
13
+ * below run at module scope for anything that reaches this file, so a host that
14
+ * serves only the credential tools imports the core module instead and never
15
+ * pays for — or gains access to — a corpus it does not serve.
16
+ */
17
+ export declare function createServerDependencies(source?: NodeJS.ProcessEnv): ServerDependencies;
18
+ /**
19
+ * Which parts of the surface to register.
20
+ *
21
+ * Every field defaults to the whole of it, so the stdio entry point calls
22
+ * `createServer(deps)` and gets exactly what it always got. The options exist
23
+ * for the hosted HTTP tier, which may only ever expose tools that need no
24
+ * merchant credential. The complementary set — the tools a merchant's local
25
+ * connector serves — has its own entry point in `./core/server.js`, because it
26
+ * must be reachable without a corpus at all.
27
+ *
28
+ * The tool list is passed as descriptors rather than as bare registrars because
29
+ * the caller doing the filtering has to reason about the tool's name, provider
30
+ * and credential dependence — none of which a `Registrar` reveals. See
31
+ * `src/tools/register.ts` for why that flag is written down rather than
32
+ * inferred from a tool's group.
33
+ */
34
+ export interface ServerSurface {
35
+ readonly tools?: readonly ToolDescriptor[] | undefined;
36
+ readonly resources?: readonly Registrar[] | undefined;
37
+ readonly prompts?: readonly Registrar[] | undefined;
38
+ }
39
+ export declare function createServer(deps: ServerDependencies, surface?: ServerSurface): McpServer;
40
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAK5D,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG5E;;;;;;;;;;;GAWG;AASH,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,MAAM,CAAC,UAAwB,GAAG,kBAAkB,CAYpG;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CAAC;CACrD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,EAAE,OAAO,GAAE,aAAkB,GAAG,SAAS,CAsB7F"}
package/dist/server.js ADDED
@@ -0,0 +1,56 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { defaultFlowSource } from './catalogue/default-catalogue.js';
3
+ import { createCoreDependencies, SERVER_INSTRUCTIONS } from './core/server.js';
4
+ import { loadSymptomKnowledgeBase } from './diagnostics/diagnose.js';
5
+ import { loadKnowledgeCorpus } from './knowledge/corpus.js';
6
+ import { buildSearchIndex } from './knowledge/search.js';
7
+ import { ALL_PROMPTS } from './prompts/register.js';
8
+ import { applyRegistrars } from './registry.js';
9
+ import { ALL_RESOURCES } from './resources/register.js';
10
+ import { TOOL_DESCRIPTORS } from './tools/register.js';
11
+ import { SERVER_NAME, SERVER_VERSION } from './version.js';
12
+ /**
13
+ * Composition root.
14
+ *
15
+ * Builds dependencies from the process environment, then hands them to the
16
+ * registration lists. It deliberately knows nothing about individual tools.
17
+ *
18
+ * The corpus-free half lives in `./core/server.js`, and this module adds the
19
+ * knowledge half on top. The split is not cosmetic: the three loaders imported
20
+ * below run at module scope for anything that reaches this file, so a host that
21
+ * serves only the credential tools imports the core module instead and never
22
+ * pays for — or gains access to — a corpus it does not serve.
23
+ */
24
+ // `createCredentialServer`, `createCoreDependencies` and `SERVER_INSTRUCTIONS`
25
+ // are deliberately not re-exported. This module loads the corpus at module
26
+ // scope, so offering the corpus-free entry points through it would invite
27
+ // exactly the import the split exists to prevent — a host serving only the
28
+ // credential tools would pull the whole knowledge half in behind them. They live
29
+ // in `./core/server.js`, which is where the connector reaches them.
30
+ export function createServerDependencies(source = process.env) {
31
+ const core = createCoreDependencies(source, { catalogue: defaultFlowSource() });
32
+ const corpus = loadKnowledgeCorpus();
33
+ const search = buildSearchIndex(corpus);
34
+ const symptoms = loadSymptomKnowledgeBase();
35
+ core.logger.info('Knowledge corpus loaded', {
36
+ documents: corpus.documents().length,
37
+ corpusVersion: corpus.corpusVersion,
38
+ });
39
+ return { ...core, corpus, search, symptoms };
40
+ }
41
+ export function createServer(deps, surface = {}) {
42
+ const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION }, { instructions: SERVER_INSTRUCTIONS });
43
+ const tools = surface.tools ?? TOOL_DESCRIPTORS;
44
+ const resources = surface.resources ?? ALL_RESOURCES;
45
+ const prompts = surface.prompts ?? ALL_PROMPTS;
46
+ applyRegistrars(server, deps, tools.map((descriptor) => descriptor.registrar));
47
+ applyRegistrars(server, deps, resources);
48
+ applyRegistrars(server, deps, prompts);
49
+ deps.logger.debug('Server surface registered', {
50
+ tools: tools.length,
51
+ resources: resources.length,
52
+ prompts: prompts.length,
53
+ });
54
+ return server;
55
+ }
56
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE/E,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAkB,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAuB,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE3D;;;;;;;;;;;GAWG;AAEH,+EAA+E;AAC/E,2EAA2E;AAC3E,0EAA0E;AAC1E,2EAA2E;AAC3E,iFAAiF;AACjF,oEAAoE;AAEpE,MAAM,UAAU,wBAAwB,CAAC,SAA4B,OAAO,CAAC,GAAG;IAC9E,MAAM,IAAI,GAAG,sBAAsB,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC;IAChF,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAC;IACrC,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,wBAAwB,EAAE,CAAC;IAE5C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE;QAC1C,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM;QACpC,aAAa,EAAE,MAAM,CAAC,aAAa;KACpC,CAAC,CAAC;IAEH,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC/C,CAAC;AAwBD,MAAM,UAAU,YAAY,CAAC,IAAwB,EAAE,UAAyB,EAAE;IAChF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE,YAAY,EAAE,mBAAmB,EAAE,CAAC,CAAC;IAEpH,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,gBAAgB,CAAC;IAChD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,aAAa,CAAC;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC;IAE/C,eAAe,CACb,MAAM,EACN,IAAI,EACJ,KAAK,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAChD,CAAC;IACF,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IACzC,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAEvC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE;QAC7C,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,SAAS,EAAE,SAAS,CAAC,MAAM;QAC3B,OAAO,EAAE,OAAO,CAAC,MAAM;KACxB,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Structured logger.
3
+ *
4
+ * WRITES TO STDERR ONLY. On the MCP stdio transport `stdout` carries JSON-RPC
5
+ * framing; a single byte written there by application code desynchronises the
6
+ * client for the remainder of the session. This is enforced by an ESLint rule
7
+ * banning `console` and `process.stdout` in `src/`, and by a unit test.
8
+ */
9
+ export declare const LOG_LEVELS: readonly ["error", "warn", "info", "debug"];
10
+ export type LogLevel = (typeof LOG_LEVELS)[number];
11
+ export type LogContext = Readonly<Record<string, unknown>>;
12
+ export interface Logger {
13
+ error(message: string, context?: LogContext): void;
14
+ warn(message: string, context?: LogContext): void;
15
+ info(message: string, context?: LogContext): void;
16
+ debug(message: string, context?: LogContext): void;
17
+ /** Derive a logger that attaches `bindings` to every record it emits. */
18
+ child(bindings: LogContext): Logger;
19
+ }
20
+ export interface LoggerOptions {
21
+ readonly level: LogLevel;
22
+ /** Defaults to `process.stderr`. Overridable so tests can assert on output. */
23
+ readonly stream?: NodeJS.WritableStream;
24
+ /** Injectable clock, so log assertions are deterministic. */
25
+ readonly now?: () => Date;
26
+ }
27
+ export declare function isLogLevel(value: unknown): value is LogLevel;
28
+ export declare function createLogger(options: LoggerOptions): Logger;
29
+ /** A logger that discards everything. Useful in tests and pure code paths. */
30
+ export declare function createNullLogger(): Logger;
31
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/telemetry/logger.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,eAAO,MAAM,UAAU,6CAA8C,CAAC;AAEtE,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AASnD,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE3D,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IACnD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAClD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAClD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IACnD,yEAAyE;IACzE,KAAK,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,+EAA+E;IAC/E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IACxC,6DAA6D;IAC7D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAmC3D;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,IAAI,MAAM,CAYzC"}
@@ -0,0 +1,67 @@
1
+ import { redactForLog } from './redaction.js';
2
+ /**
3
+ * Structured logger.
4
+ *
5
+ * WRITES TO STDERR ONLY. On the MCP stdio transport `stdout` carries JSON-RPC
6
+ * framing; a single byte written there by application code desynchronises the
7
+ * client for the remainder of the session. This is enforced by an ESLint rule
8
+ * banning `console` and `process.stdout` in `src/`, and by a unit test.
9
+ */
10
+ export const LOG_LEVELS = ['error', 'warn', 'info', 'debug'];
11
+ const LEVEL_SEVERITY = {
12
+ error: 0,
13
+ warn: 1,
14
+ info: 2,
15
+ debug: 3,
16
+ };
17
+ export function isLogLevel(value) {
18
+ return typeof value === 'string' && LOG_LEVELS.includes(value);
19
+ }
20
+ export function createLogger(options) {
21
+ const stream = options.stream ?? process.stderr;
22
+ const now = options.now ?? (() => new Date());
23
+ const threshold = LEVEL_SEVERITY[options.level];
24
+ const emit = (level, bindings, message, context) => {
25
+ if (LEVEL_SEVERITY[level] > threshold) {
26
+ return;
27
+ }
28
+ const record = {
29
+ timestamp: now().toISOString(),
30
+ level,
31
+ message,
32
+ ...redactForLog({ ...bindings, ...context }),
33
+ };
34
+ stream.write(`${JSON.stringify(record)}\n`);
35
+ };
36
+ const build = (bindings) => ({
37
+ error: (message, context) => {
38
+ emit('error', bindings, message, context);
39
+ },
40
+ warn: (message, context) => {
41
+ emit('warn', bindings, message, context);
42
+ },
43
+ info: (message, context) => {
44
+ emit('info', bindings, message, context);
45
+ },
46
+ debug: (message, context) => {
47
+ emit('debug', bindings, message, context);
48
+ },
49
+ child: (extra) => build({ ...bindings, ...extra }),
50
+ });
51
+ return build({});
52
+ }
53
+ /** A logger that discards everything. Useful in tests and pure code paths. */
54
+ export function createNullLogger() {
55
+ const noop = () => {
56
+ /* intentionally empty */
57
+ };
58
+ const logger = {
59
+ error: noop,
60
+ warn: noop,
61
+ info: noop,
62
+ debug: noop,
63
+ child: () => logger,
64
+ };
65
+ return logger;
66
+ }
67
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/telemetry/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAItE,MAAM,cAAc,GAAuC;IACzD,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC;AAqBF,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,UAAgC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAsB;IACjD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAChD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAS,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAEhD,MAAM,IAAI,GAAG,CAAC,KAAe,EAAE,QAAoB,EAAE,OAAe,EAAE,OAAoB,EAAQ,EAAE;QAClG,IAAI,cAAc,CAAC,KAAK,CAAC,GAAG,SAAS,EAAE,CAAC;YACtC,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE;YAC9B,KAAK;YACL,OAAO;YACP,GAAI,YAAY,CAAC,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,CAA6B;SAC1E,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,CAAC,QAAoB,EAAU,EAAE,CAAC,CAAC;QAC/C,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAQ,EAAE;YAChC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAQ,EAAE;YAC/B,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAQ,EAAE;YAC/B,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;QACD,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAQ,EAAE;YAChC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5C,CAAC;QACD,KAAK,EAAE,CAAC,KAAK,EAAU,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,QAAQ,EAAE,GAAG,KAAK,EAAE,CAAC;KAC3D,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC,EAAE,CAAC,CAAC;AACnB,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,gBAAgB;IAC9B,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,yBAAyB;IAC3B,CAAC,CAAC;IACF,MAAM,MAAM,GAAW;QACrB,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,GAAW,EAAE,CAAC,MAAM;KAC5B,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC"}