@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
@@ -0,0 +1,241 @@
1
+ import { resolveEndpoint } from '../catalogue/endpoints.js';
2
+ import { requestHashOptions, responseHashOptions, signatureFieldName } from '../catalogue/hash-options.js';
3
+ import { credentialParameterValue } from '../config/credentials.js';
4
+ import { classifyResponse } from '../domain/response-codes.js';
5
+ import { hashesMatch, computeSecureHash } from '../domain/secure-hash.js';
6
+ import { normaliseValue, toParameters, } from '../domain/types.js';
7
+ import { JazzCashGatewayError, JazzCashValidationError } from '../errors.js';
8
+ import { redactForLog, REDACTED } from '../telemetry/redaction.js';
9
+ import { validatePayload } from '../validation/payload-validator.js';
10
+ import { guardGatewayCall } from './guards.js';
11
+ import { createHttpClient } from './http-client.js';
12
+ import { describeTransportMismatch } from './transport.js';
13
+ /**
14
+ * Verify the response hash.
15
+ *
16
+ * Assumption A2: no guide states which response fields feed the response hash,
17
+ * so a mismatch is reported as `unverified`, never as a failure. Telling a
18
+ * merchant their integration is broken on the strength of an unconfirmed rule
19
+ * would be worse than saying nothing.
20
+ */
21
+ function checkResponseHash(flow, response, integritySalt) {
22
+ const field = flow.response.hashField;
23
+ // A flow whose responses carry no signature has no field to read. Reporting an
24
+ // absent hash for a field the provider never sends reads as a fault in the
25
+ // merchant's integration, and would have them chasing a hash that was never
26
+ // part of the contract.
27
+ if (field === undefined) {
28
+ return {
29
+ verdict: 'absent',
30
+ note: `${flow.id} declares no response signature, so there was nothing to verify. This is the provider's design, not a fault in the integration.`,
31
+ };
32
+ }
33
+ const supplied = response[field];
34
+ if (typeof supplied !== 'string' || supplied.trim() === '') {
35
+ return {
36
+ verdict: 'absent',
37
+ field,
38
+ note: `The response carried no ${field}, so there was nothing to verify.`,
39
+ };
40
+ }
41
+ // Response field selection is NOT the request's. See catalogue/hash-options.ts.
42
+ const recomputed = computeSecureHash(toParameters(response), integritySalt, responseHashOptions(flow));
43
+ if (hashesMatch(recomputed, supplied)) {
44
+ return { verdict: 'verified', field, note: `${field} matches a hash recomputed over the response fields.` };
45
+ }
46
+ return {
47
+ verdict: 'unverified',
48
+ field,
49
+ note: `${field} did not match a hash recomputed over all non-empty response fields. JazzCash does not document which fields feed the response hash, so this is UNVERIFIED rather than a failure — do not treat it as evidence that the integration is broken. Confirm the rule with JazzCash (assumption A2).`,
50
+ };
51
+ }
52
+ /**
53
+ * Choose the transport: per-call client, then the injected one, then a default.
54
+ *
55
+ * The injected tier exists so that orchestration tools which expose no transport
56
+ * argument of their own can still be tested without calling the live gateway.
57
+ */
58
+ function resolveHttpClient(deps, perCall) {
59
+ return perCall ?? deps.httpClient ?? createHttpClient({ timeoutMs: deps.config.httpTimeoutMs, logger: deps.logger });
60
+ }
61
+ function buildNextSteps(flow, classification) {
62
+ const steps = [...classification.nextSteps];
63
+ if (classification.classification === 'completed' && flow.responseContext === 'payment') {
64
+ steps.push('Reconcile against the IPN notification, and record pp_RetreivalReferenceNo for support enquiries.');
65
+ }
66
+ if (classification.classification === 'pending' || classification.classification === 'unknown') {
67
+ steps.push(`Call the Status Inquiry API (${flow.companionFlows.find((id) => id.startsWith('status-inquiry')) ?? 'status-inquiry-v1.1'}) at least ten minutes after the transaction time.`);
68
+ }
69
+ return steps;
70
+ }
71
+ /**
72
+ * Resolve a credential parameter from the profile rather than from the caller.
73
+ *
74
+ * Shares `credentialParameterValue` with the builder so the two cannot drift,
75
+ * but excludes `pp_ReturnURL`: that one is registered rather than secret and is
76
+ * filled below only when the caller left it empty, for the reason given there.
77
+ */
78
+ function profileCredential(name, profile) {
79
+ return name === 'pp_ReturnURL' ? undefined : credentialParameterValue(name, profile);
80
+ }
81
+ /**
82
+ * Fill the credential fields from the resolved profile before anything is signed.
83
+ *
84
+ * Credentials are never tool arguments (see `docs/mcp/SAFETY.md`), so the payload
85
+ * a caller holds — from `jazzcash_build_transaction_parameters`, or copied out of
86
+ * a log — carries them masked. They are refilled here, ahead of validation and
87
+ * signing, so that the transmitted map and its hash both carry the real values.
88
+ *
89
+ * The overwrite is unconditional for the identity fields: the Integrity Salt used
90
+ * to sign comes from this profile, so a caller-supplied merchant ID or password
91
+ * belonging to another profile could only produce a request signed by one
92
+ * merchant while claiming to be another.
93
+ *
94
+ * `pp_ReturnURL` is registered rather than secret, and the gateway treats any
95
+ * difference from the registered value as an authentication failure, so a
96
+ * supplied value is left alone for `returnUrlRule` to report. The profile only
97
+ * supplies it when the caller left it empty.
98
+ */
99
+ function withProfileCredentials(flow, parameters, profile) {
100
+ const filled = { ...parameters };
101
+ for (const parameter of flow.parameters) {
102
+ const credential = profileCredential(parameter.name, profile);
103
+ if (credential !== undefined) {
104
+ filled[parameter.name] = credential;
105
+ continue;
106
+ }
107
+ const supplied = normaliseValue(filled[parameter.name]);
108
+ if (parameter.name === 'pp_ReturnURL' && profile.returnUrl !== undefined && supplied === '') {
109
+ filled[parameter.name] = profile.returnUrl;
110
+ }
111
+ }
112
+ return filled;
113
+ }
114
+ /**
115
+ * Refuse a payload still carrying the redaction sentinel.
116
+ *
117
+ * A masked value is not a value: `[redacted]` passes every presence check, would
118
+ * be HMAC'd with the real Integrity Salt and POSTed to a live gateway, and the
119
+ * merchant would be left with an authentication failure they cannot explain.
120
+ * Credentials have already been refilled by this point, so anything still masked
121
+ * is data only the caller can restore. The hash field is exempt because it is
122
+ * recomputed below.
123
+ */
124
+ function assertNoRedactedValues(flow, parameters) {
125
+ const recomputed = new Set(flow.parameters.filter((parameter) => parameter.valueType === 'secure-hash').map((parameter) => parameter.name));
126
+ const masked = Object.keys(parameters).filter((name) => !recomputed.has(name) && normaliseValue(parameters[name]) === REDACTED);
127
+ if (masked.length === 0) {
128
+ return;
129
+ }
130
+ throw new JazzCashValidationError(`Refusing to send a ${flow.id} payload in which ${masked.join(', ')} still holds the literal redaction placeholder "${REDACTED}". Credential fields are filled from the server configuration, but these values are not recoverable here: supply the real ones, or rebuild the payload with jazzcash_build_transaction_parameters.`, { details: { fields: masked } });
131
+ }
132
+ /** How much of an unparseable body to quote back: enough to recognise it, no more. */
133
+ const RESPONSE_SNIPPET_LIMIT = 500;
134
+ /**
135
+ * Quote a bounded excerpt of a body that could not be parsed.
136
+ *
137
+ * A proxy's HTML 502, a WAF block page and a maintenance notice are all "not a
138
+ * JSON object", and telling a merchant only that leaves them nothing to act on.
139
+ * The excerpt is bounded and whitespace-collapsed because a gateway response is
140
+ * not trusted input, and it is masked on the way out by `toolError`.
141
+ */
142
+ function responseSnippet(rawText) {
143
+ const collapsed = rawText.replace(/\s+/gu, ' ').trim();
144
+ if (collapsed === '') {
145
+ return '(the body was empty)';
146
+ }
147
+ return collapsed.length <= RESPONSE_SNIPPET_LIMIT ? collapsed : `${collapsed.slice(0, RESPONSE_SNIPPET_LIMIT)}…`;
148
+ }
149
+ /**
150
+ * Refill, validate and sign, in that order, returning the exact map to transmit.
151
+ *
152
+ * The order is the whole of it. Credentials are refilled before validation so a
153
+ * masked payload is not rejected for a field the server itself supplies, and the
154
+ * signature is computed last, from the normalised map rather than from the
155
+ * caller's, so the digest covers the bytes that actually go on the wire. The
156
+ * field it is written into comes from the flow, because `pp_SecureHash` is one
157
+ * provider's name for it.
158
+ *
159
+ * @throws JazzCashValidationError when the payload is masked or invalid, before
160
+ * anything is signed or sent.
161
+ */
162
+ function signedPayloadFor(flow, parameters, profile) {
163
+ const filled = withProfileCredentials(flow, parameters, profile);
164
+ assertNoRedactedValues(flow, filled);
165
+ const validation = validatePayload(flow, filled, {
166
+ registeredReturnUrl: profile.returnUrl,
167
+ });
168
+ if (!validation.valid) {
169
+ throw new JazzCashValidationError(`Refusing to send an invalid ${flow.id} payload. ${validation.errors.map((entry) => `${entry.field ?? 'payload'}: ${entry.message}`).join(' ')}`, { details: { errors: validation.errors } });
170
+ }
171
+ const signatureField = signatureFieldName(flow);
172
+ // A flow that declares no signature field is transmitted unsigned rather than
173
+ // gaining one under a borrowed name: writing a digest into `pp_SecureHash` for
174
+ // a provider that never reads it sends a field the gateway ignores and omits
175
+ // the one it checks, which is a rejected transaction with nothing in the
176
+ // response to explain it.
177
+ if (signatureField === undefined) {
178
+ return validation.normalisedPayload;
179
+ }
180
+ return {
181
+ ...validation.normalisedPayload,
182
+ [signatureField]: computeSecureHash(validation.normalisedPayload, profile.integritySalt, requestHashOptions(flow)),
183
+ };
184
+ }
185
+ /** Send one REST request and interpret the result. */
186
+ export async function executeFlow(deps, options) {
187
+ const { flow, environment } = options;
188
+ if (flow.transport !== 'rest') {
189
+ throw new JazzCashValidationError(describeTransportMismatch(flow, 'rest'));
190
+ }
191
+ const { profile, warnings } = guardGatewayCall(deps, {
192
+ flow,
193
+ environment,
194
+ confirmLiveEnvironment: options.confirmLiveEnvironment,
195
+ });
196
+ const signed = signedPayloadFor(flow, options.parameters, profile);
197
+ const endpoint = resolveEndpoint(flow, environment);
198
+ const httpClient = resolveHttpClient(deps, options.httpClient);
199
+ deps.logger.info('Sending gateway request', {
200
+ flowId: flow.id,
201
+ environment,
202
+ endpoint,
203
+ movesMoney: flow.movesMoney,
204
+ });
205
+ const httpResponse = await httpClient.postJson(endpoint, signed, {
206
+ // Only a read may be retried. Retrying a payment or refund could debit twice.
207
+ retryable: !flow.movesMoney,
208
+ });
209
+ if (typeof httpResponse.body !== 'object' || httpResponse.body === null) {
210
+ const snippet = responseSnippet(httpResponse.rawText);
211
+ throw new JazzCashGatewayError(`The gateway returned HTTP ${String(httpResponse.status)} with a body that is not a JSON object. The transaction outcome is UNKNOWN: resolve it with the Status Inquiry API rather than resending. The body began: ${snippet}`, { details: { status: httpResponse.status, bodySnippet: snippet } });
212
+ }
213
+ const response = httpResponse.body;
214
+ // The flow's own success contract, so that a provider whose service-level code
215
+ // says only "request accepted" is not read as a completed payment: the
216
+ // settlement level it declares is checked as well. A no-op for every JazzCash
217
+ // flow, which reports one outcome in one documented field.
218
+ const classification = classifyResponse(response, flow.responseContext, flow.response);
219
+ const responseHash = checkResponseHash(flow, response, profile.integritySalt);
220
+ deps.logger.info('Gateway request completed', {
221
+ flowId: flow.id,
222
+ httpStatus: httpResponse.status,
223
+ classification: classification.classification,
224
+ responseHash: responseHash.verdict,
225
+ durationMs: httpResponse.durationMs,
226
+ });
227
+ return {
228
+ flowId: flow.id,
229
+ environment,
230
+ endpoint,
231
+ requestPreview: redactForLog(signed),
232
+ response,
233
+ httpStatus: httpResponse.status,
234
+ durationMs: httpResponse.durationMs,
235
+ classification,
236
+ responseHash,
237
+ warnings,
238
+ nextSteps: buildNextSteps(flow, classification),
239
+ };
240
+ }
241
+ //# sourceMappingURL=rest-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest-client.js","sourceRoot":"","sources":["../../src/gateway/rest-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { IntegrationFlow, Transport } from '../catalogue/types.js';
2
+ /**
3
+ * Say what `flow` actually is, and what to reach for instead.
4
+ *
5
+ * `wanted` is the transport the caller's tool or artefact kind implies, so the
6
+ * message names both halves of the mismatch rather than only the flow.
7
+ *
8
+ * The switch is exhaustive by construction: the `never` binding stops a third
9
+ * transport compiling until it has a sentence of its own, rather than letting it
10
+ * inherit whichever refusal happened to be written last — which is precisely how
11
+ * a previous transport came to be described as both a browser form and a REST API.
12
+ */
13
+ export declare function describeTransportMismatch(flow: IntegrationFlow, wanted: Transport): string;
14
+ /**
15
+ * Say how a flow this server has just built a payload for is actually sent.
16
+ *
17
+ * The success-path counterpart to {@link describeTransportMismatch}, which
18
+ * refuses. A tool that has produced a valid payload still has to say what to do
19
+ * with it, and that sentence was written at the call site as one ternary: a
20
+ * browser-form instruction for `form-post` and a JSON one for everything else,
21
+ * which tells the caller of any future non-JSON transport to POST JSON to an
22
+ * endpoint that does not parse it. The payload is correct and the advice sends
23
+ * it to be rejected.
24
+ *
25
+ * Both halves come from the same table as the refusals above, so a flow cannot
26
+ * be one thing when this server declines to perform it and another when it
27
+ * succeeds. The switch is exhaustive by construction for the same reason: a
28
+ * third transport must be given its own sentence rather than inheriting one.
29
+ */
30
+ export declare function describeHowToSend(flow: IntegrationFlow): string;
31
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/gateway/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAmBxE;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,GAAG,MAAM,CAe1F;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAe/D"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * One explanation for every refusal to perform a flow the way it was asked for.
3
+ *
4
+ * Three sites used to word this themselves and disagreed: for one transport the
5
+ * REST client called a flow a browser form post, the checkout-form tool called
6
+ * the same flow a REST API, and the generator offered "rest-client" as the kind
7
+ * that suits it and then refused that kind. A caller following any two of them
8
+ * is sent in a circle between tools each blaming the other, with nothing that
9
+ * says what the flow actually is.
10
+ */
11
+ /** How each transport reads in a sentence, so no two refusals can describe it differently. */
12
+ const TRANSPORT_DESCRIPTION = {
13
+ rest: 'a server-to-server REST API',
14
+ 'form-post': 'a browser form post',
15
+ };
16
+ /**
17
+ * Say what `flow` actually is, and what to reach for instead.
18
+ *
19
+ * `wanted` is the transport the caller's tool or artefact kind implies, so the
20
+ * message names both halves of the mismatch rather than only the flow.
21
+ *
22
+ * The switch is exhaustive by construction: the `never` binding stops a third
23
+ * transport compiling until it has a sentence of its own, rather than letting it
24
+ * inherit whichever refusal happened to be written last — which is precisely how
25
+ * a previous transport came to be described as both a browser form and a REST API.
26
+ */
27
+ export function describeTransportMismatch(flow, wanted) {
28
+ const opening = `${flow.id} is ${TRANSPORT_DESCRIPTION[flow.transport]}, not ${TRANSPORT_DESCRIPTION[wanted]}.`;
29
+ switch (flow.transport) {
30
+ case 'rest':
31
+ return `${opening} Send it with jazzcash_send_gateway_request, or generate the "rest-client" artefact for it.`;
32
+ case 'form-post':
33
+ return `${opening} It cannot be performed headlessly: the customer completes it in a browser, entering an MPIN or card details. Use jazzcash_build_checkout_form, or generate the "checkout-redirect" artefact, then confirm the outcome with the Status Inquiry API.`;
34
+ /* c8 ignore start -- unreachable: the switch above is exhaustive, and the assignment below is what proves it */
35
+ default: {
36
+ const unreachable = flow.transport;
37
+ return unreachable;
38
+ }
39
+ /* c8 ignore stop */
40
+ }
41
+ }
42
+ /**
43
+ * Say how a flow this server has just built a payload for is actually sent.
44
+ *
45
+ * The success-path counterpart to {@link describeTransportMismatch}, which
46
+ * refuses. A tool that has produced a valid payload still has to say what to do
47
+ * with it, and that sentence was written at the call site as one ternary: a
48
+ * browser-form instruction for `form-post` and a JSON one for everything else,
49
+ * which tells the caller of any future non-JSON transport to POST JSON to an
50
+ * endpoint that does not parse it. The payload is correct and the advice sends
51
+ * it to be rejected.
52
+ *
53
+ * Both halves come from the same table as the refusals above, so a flow cannot
54
+ * be one thing when this server declines to perform it and another when it
55
+ * succeeds. The switch is exhaustive by construction for the same reason: a
56
+ * third transport must be given its own sentence rather than inheriting one.
57
+ */
58
+ export function describeHowToSend(flow) {
59
+ const description = TRANSPORT_DESCRIPTION[flow.transport];
60
+ switch (flow.transport) {
61
+ case 'rest':
62
+ return `This flow is ${description}. Send the payload as a JSON POST body to the endpoint, or pass it to jazzcash_send_gateway_request, which validates, re-signs and sends it for you.`;
63
+ case 'form-post':
64
+ return `This flow is ${description}. Render every field as a hidden input and submit it to the endpoint, or use jazzcash_build_checkout_form, which produces that page for you.`;
65
+ /* c8 ignore start -- unreachable: the switch above is exhaustive, and the assignment below is what proves it */
66
+ default: {
67
+ const unreachable = flow.transport;
68
+ return unreachable;
69
+ }
70
+ /* c8 ignore stop */
71
+ }
72
+ }
73
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/gateway/transport.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,8FAA8F;AAC9F,MAAM,qBAAqB,GAAwC;IACjE,IAAI,EAAE,6BAA6B;IACnC,WAAW,EAAE,qBAAqB;CACnC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAqB,EAAE,MAAiB;IAChF,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,EAAE,OAAO,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,qBAAqB,CAAC,MAAM,CAAC,GAAG,CAAC;IAEhH,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;QACvB,KAAK,MAAM;YACT,OAAO,GAAG,OAAO,6FAA6F,CAAC;QACjH,KAAK,WAAW;YACd,OAAO,GAAG,OAAO,qPAAqP,CAAC;QACzQ,gHAAgH;QAChH,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,WAAW,GAAU,IAAI,CAAC,SAAS,CAAC;YAC1C,OAAO,WAAW,CAAC;QACrB,CAAC;QACD,oBAAoB;IACtB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAqB;IACrD,MAAM,WAAW,GAAG,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAE1D,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;QACvB,KAAK,MAAM;YACT,OAAO,gBAAgB,WAAW,sJAAsJ,CAAC;QAC3L,KAAK,WAAW;YACd,OAAO,gBAAgB,WAAW,8IAA8I,CAAC;QACnL,gHAAgH;QAChH,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,WAAW,GAAU,IAAI,CAAC,SAAS,CAAC;YAC1C,OAAO,WAAW,CAAC;QACrB,CAAC;QACD,oBAAoB;IACtB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { describeError, JazzCashError } from './errors.js';
4
+ import { createServer, createServerDependencies } from './server.js';
5
+ import { createLogger } from './telemetry/logger.js';
6
+ /**
7
+ * Executable entry point.
8
+ *
9
+ * Nothing here may write to stdout: on the stdio transport that channel carries
10
+ * JSON-RPC framing. Start-up failures and signals are reported on stderr.
11
+ */
12
+ async function main() {
13
+ // Credentials come from the process environment, which the MCP client supplies
14
+ // through its own `env` block, or from JAZZCASH_CREDENTIALS_FILE. The server
15
+ // deliberately does NOT read a `.env`: an IDE spawns it with the merchant's
16
+ // workspace as the working directory, so a dotenv loader would silently adopt
17
+ // whatever credentials that project happens to hold — possibly production.
18
+ // Which environment is in play must always be a decision, never a side effect.
19
+ const deps = createServerDependencies();
20
+ const server = createServer(deps);
21
+ const transport = new StdioServerTransport();
22
+ let shuttingDown = false;
23
+ /**
24
+ * Close the server and leave with an exit code that describes why.
25
+ *
26
+ * The code is a parameter rather than a hardcoded 0 because `process.exit(0)`
27
+ * overrides anything already recorded in `process.exitCode`: a supervisor
28
+ * would read a clean exit for a run that had already failed. A requested 0
29
+ * therefore defers to whatever the process has recorded.
30
+ */
31
+ const shutdown = (reason, requestedExitCode) => {
32
+ if (shuttingDown) {
33
+ return;
34
+ }
35
+ shuttingDown = true;
36
+ deps.logger.info('Shutting down', { reason, exitCode: requestedExitCode });
37
+ void server
38
+ .close()
39
+ .catch((error) => {
40
+ deps.logger.error('Error during shutdown', { error: describeError(error) });
41
+ })
42
+ .finally(() => {
43
+ process.exit(requestedExitCode === 0 ? process.exitCode : requestedExitCode);
44
+ });
45
+ };
46
+ process.on('SIGINT', (signal) => {
47
+ shutdown(signal, 0);
48
+ });
49
+ process.on('SIGTERM', (signal) => {
50
+ shutdown(signal, 0);
51
+ });
52
+ process.on('unhandledRejection', (reason) => {
53
+ deps.logger.error('Unhandled promise rejection', { error: describeError(reason) });
54
+ // A rejection nothing handled leaves the server in an unknown state. This is
55
+ // a payment server: continuing to accept money-moving tool calls from there
56
+ // is worse than stopping, so the same shutdown path runs with a failure code
57
+ // rather than merely recording one and serving on.
58
+ shutdown('unhandledRejection', 1);
59
+ });
60
+ process.on('uncaughtException', (error) => {
61
+ deps.logger.error('Uncaught exception', { error: describeError(error) });
62
+ process.exit(1);
63
+ });
64
+ await server.connect(transport);
65
+ deps.logger.info('JazzCash MCP server ready on stdio');
66
+ }
67
+ main().catch((error) => {
68
+ // The logger may not exist yet if configuration itself failed, so build a
69
+ // minimal one rather than risking a second failure.
70
+ const logger = createLogger({ level: 'error' });
71
+ const hint = error instanceof JazzCashError ? ` (${error.code})` : '';
72
+ logger.error(`Failed to start JazzCash MCP server${hint}`, { error: describeError(error) });
73
+ process.exit(1);
74
+ });
75
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { type HarnessDescriptor, type ServerEntry } from './harnesses.js';
2
+ /**
3
+ * `npm run deploy` — register this MCP server with the AI harnesses on this
4
+ * machine.
5
+ *
6
+ * Every write preserves the rest of the file, lands atomically, and leaves a
7
+ * timestamped backup beside the original. That backup is a full copy of a file
8
+ * that may hold credentials, so it is written owner-only and reported to the
9
+ * user for deletion. Nothing is installed without being asked for, either
10
+ * interactively or through `--target`.
11
+ */
12
+ interface Options {
13
+ readonly targets: readonly string[];
14
+ readonly all: boolean;
15
+ readonly list: boolean;
16
+ readonly remove: boolean;
17
+ readonly dryRun: boolean;
18
+ readonly name: string;
19
+ readonly help: boolean;
20
+ }
21
+ export declare function parseArguments(argv: readonly string[]): Options;
22
+ interface TargetState {
23
+ readonly harness: HarnessDescriptor;
24
+ /** Existing config files, most canonical first. Empty when none exist. */
25
+ readonly present: readonly string[];
26
+ readonly installed: boolean;
27
+ }
28
+ export declare function inspect(harness: HarnessDescriptor, name: string): TargetState;
29
+ interface WriteOutcome {
30
+ readonly path: string;
31
+ readonly action: 'written' | 'would-write' | 'skipped';
32
+ readonly backupPath?: string;
33
+ readonly reason?: string;
34
+ }
35
+ export declare function applyToFile(harness: HarnessDescriptor, path: string, name: string, entry: ServerEntry | undefined, dryRun: boolean): WriteOutcome;
36
+ export declare function apply(state: TargetState, name: string, remove: boolean, dryRun: boolean): readonly WriteOutcome[];
37
+ export {};
38
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/install/cli.ts"],"names":[],"mappings":"AAOA,OAAO,EAOL,KAAK,iBAAiB,EACtB,KAAK,WAAW,EACjB,MAAM,gBAAgB,CAAC;AAExB;;;;;;;;;GASG;AAEH,UAAU,OAAO;IACf,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAoB/D;AAoBD,UAAU,WAAW;IACnB,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAe7E;AAuCD,UAAU,YAAY;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,iBAAiB,EAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,GAAG,SAAS,EAC9B,MAAM,EAAE,OAAO,GACd,YAAY,CAsBd;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,YAAY,EAAE,CAcjH"}