@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,15 @@
1
+ import { type CorpusSource } from './source.js';
2
+ import { type CorpusDocument, type DocumentSection } from './types.js';
3
+ export declare function documentUri(docId: string, sectionId?: string): string;
4
+ export interface KnowledgeCorpus {
5
+ readonly corpusVersion: string;
6
+ documents(): readonly CorpusDocument[];
7
+ document(docId: string): CorpusDocument;
8
+ findDocument(docId: string): CorpusDocument | undefined;
9
+ section(docId: string, sectionId: string): DocumentSection;
10
+ sections(): readonly DocumentSection[];
11
+ documentsForFlow(flowId: string): readonly CorpusDocument[];
12
+ }
13
+ /** Load and index the documentation corpus. Throws if it is malformed. */
14
+ export declare function loadKnowledgeCorpus(source?: CorpusSource | string): KnowledgeCorpus;
15
+ //# sourceMappingURL=corpus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corpus.d.ts","sourceRoot":"","sources":["../../src/knowledge/corpus.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAuB,KAAK,cAAc,EAAyB,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AA4BnH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAErE;AA+DD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,SAAS,IAAI,SAAS,cAAc,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAAC;IACxC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IACxD,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,eAAe,CAAC;IAC3D,QAAQ,IAAI,SAAS,eAAe,EAAE,CAAC;IACvC,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,cAAc,EAAE,CAAC;CAC7D;AAED,0EAA0E;AAC1E,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,YAAY,GAAG,MAA8B,GAAG,eAAe,CAgE1G"}
@@ -0,0 +1,129 @@
1
+ import { JazzCashConfigError, JazzCashNotFoundError } from '../errors.js';
2
+ import { knowledgePath } from '../paths.js';
3
+ import { toCorpusSource } from './source.js';
4
+ import { documentIndexSchema } from './types.js';
5
+ /**
6
+ * Loader for the curated documentation corpus in `knowledge/docs/`.
7
+ *
8
+ * Document metadata comes from `index.json`; sections are derived from the
9
+ * markdown headings themselves, so a heading and its index entry cannot drift
10
+ * apart. Every section is addressable as `jazzcash://docs/{docId}#{sectionId}`.
11
+ *
12
+ * Files arrive through a `CorpusSource`, so the same loader indexes a corpus
13
+ * that is not a directory on this machine.
14
+ */
15
+ /** The manifest naming every document in the corpus. */
16
+ const INDEX_ENTRY = 'index.json';
17
+ /** Matches `## Section title {#section-id}`. */
18
+ const SECTION_HEADING = /^##\s+(.+?)\s*\{#([a-z0-9-]+)\}\s*$/;
19
+ /**
20
+ * Matches an anchored heading nested deeper than `##`.
21
+ *
22
+ * Only `##` headings become addressable sections, so an anchor on a `###`
23
+ * heading is a citation target that can never resolve. Rejecting it at load
24
+ * turns a silently broken link into a start-up failure.
25
+ */
26
+ const NESTED_ANCHORED_HEADING = /^#{3,}\s+.+?\{#([a-z0-9-]+)\}\s*$/;
27
+ export function documentUri(docId, sectionId) {
28
+ return sectionId === undefined ? `jazzcash://docs/${docId}` : `jazzcash://docs/${docId}#${sectionId}`;
29
+ }
30
+ function parseSections(metadata, markdown) {
31
+ const lines = markdown.split(/\r?\n/);
32
+ const sections = [];
33
+ const preambleLines = [];
34
+ let current;
35
+ const flush = () => {
36
+ if (current === undefined) {
37
+ return;
38
+ }
39
+ sections.push({
40
+ docId: metadata.docId,
41
+ sectionId: current.sectionId,
42
+ title: current.title,
43
+ text: current.body.join('\n').trim(),
44
+ uri: documentUri(metadata.docId, current.sectionId),
45
+ });
46
+ };
47
+ for (const line of lines) {
48
+ const nested = NESTED_ANCHORED_HEADING.exec(line);
49
+ if (nested !== null) {
50
+ throw new JazzCashConfigError(`Document ${metadata.docId} anchors "{#${nested[1] ?? ''}}" on a heading deeper than "##". Only "##" headings become addressable sections, so that anchor could never be cited. Promote the heading to "##".`);
51
+ }
52
+ const heading = SECTION_HEADING.exec(line);
53
+ if (heading !== null) {
54
+ flush();
55
+ current = { title: heading[1] ?? '', sectionId: heading[2] ?? '', body: [] };
56
+ continue;
57
+ }
58
+ if (current === undefined) {
59
+ preambleLines.push(line);
60
+ }
61
+ else {
62
+ current.body.push(line);
63
+ }
64
+ }
65
+ flush();
66
+ if (sections.length === 0) {
67
+ throw new JazzCashConfigError(`Document ${metadata.docId} declares no sections. Every section needs a heading of the form "## Title {#section-id}".`);
68
+ }
69
+ const duplicates = sections.map((section) => section.sectionId).filter((id, index, all) => all.indexOf(id) !== index);
70
+ if (duplicates.length > 0) {
71
+ throw new JazzCashConfigError(`Document ${metadata.docId} declares duplicate section anchors: ${[...new Set(duplicates)].join(', ')}. Anchors must be unique so citations resolve.`);
72
+ }
73
+ return { preamble: preambleLines.join('\n').trim(), sections };
74
+ }
75
+ /** Load and index the documentation corpus. Throws if it is malformed. */
76
+ export function loadKnowledgeCorpus(source = knowledgePath('docs')) {
77
+ const files = toCorpusSource(source);
78
+ let indexJson;
79
+ try {
80
+ indexJson = JSON.parse(files.readText(INDEX_ENTRY));
81
+ }
82
+ catch (cause) {
83
+ throw new JazzCashConfigError(`Unable to read the documentation index at ${files.locate(INDEX_ENTRY)}.`, {
84
+ cause,
85
+ });
86
+ }
87
+ const parsed = documentIndexSchema.safeParse(indexJson);
88
+ if (!parsed.success) {
89
+ const issues = parsed.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`).join('; ');
90
+ throw new JazzCashConfigError(`The documentation index is invalid. ${issues}`);
91
+ }
92
+ const documents = parsed.data.documents.map((metadata) => {
93
+ const entry = `${metadata.docId}.md`;
94
+ let markdown;
95
+ try {
96
+ markdown = files.readText(entry);
97
+ }
98
+ catch (cause) {
99
+ throw new JazzCashConfigError(`Document ${metadata.docId} is listed in index.json but ${files.locate(entry)} could not be read.`, { cause });
100
+ }
101
+ const { preamble, sections } = parseSections(metadata, markdown);
102
+ return { metadata, preamble, sections, markdown };
103
+ });
104
+ const byId = new Map(documents.map((document) => [document.metadata.docId, document]));
105
+ const allSections = documents.flatMap((document) => document.sections);
106
+ return {
107
+ corpusVersion: parsed.data.corpusVersion,
108
+ documents: () => documents,
109
+ findDocument: (docId) => byId.get(docId),
110
+ document(docId) {
111
+ const document = byId.get(docId);
112
+ if (document === undefined) {
113
+ throw new JazzCashNotFoundError(`No document with id "${docId}". Available documents: ${[...byId.keys()].join(', ')}.`);
114
+ }
115
+ return document;
116
+ },
117
+ section(docId, sectionId) {
118
+ const document = this.document(docId);
119
+ const section = document.sections.find((entry) => entry.sectionId === sectionId);
120
+ if (section === undefined) {
121
+ throw new JazzCashNotFoundError(`Document "${docId}" has no section "${sectionId}". Available sections: ${document.sections.map((entry) => entry.sectionId).join(', ')}.`);
122
+ }
123
+ return section;
124
+ },
125
+ sections: () => allSections,
126
+ documentsForFlow: (flowId) => documents.filter((document) => document.metadata.flowIds.includes(flowId)),
127
+ };
128
+ }
129
+ //# sourceMappingURL=corpus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corpus.js","sourceRoot":"","sources":["../../src/knowledge/corpus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { KnowledgeCorpus } from './corpus.js';
2
+ /**
3
+ * Split text into searchable tokens.
4
+ *
5
+ * Underscores are preserved so `pp_SecureHash` survives as one token, and the
6
+ * bare word forms are emitted too, so a query for "secure hash" still matches it.
7
+ */
8
+ export declare function tokenise(text: string): string[];
9
+ export interface SearchResult {
10
+ readonly docId: string;
11
+ readonly sectionId: string;
12
+ readonly documentTitle: string;
13
+ readonly sectionTitle: string;
14
+ readonly uri: string;
15
+ readonly score: number;
16
+ /** Passage around the strongest match, for display without the whole section. */
17
+ readonly excerpt: string;
18
+ }
19
+ export interface SearchOptions {
20
+ /** Restrict results to documents describing this flow. */
21
+ readonly flowId?: string | undefined;
22
+ readonly limit?: number | undefined;
23
+ }
24
+ export interface KnowledgeSearchIndex {
25
+ search(query: string, options?: SearchOptions): readonly SearchResult[];
26
+ }
27
+ /** Build a search index over the corpus. Cheap enough to build once at start-up. */
28
+ export declare function buildSearchIndex(corpus: KnowledgeCorpus): KnowledgeSearchIndex;
29
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/knowledge/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAwEnD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAoB/C;AAiBD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,YAAY,EAAE,CAAC;CACzE;AAyBD,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,oBAAoB,CA6E9E"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Offline lexical search over the documentation corpus.
3
+ *
4
+ * BM25 over section text, with boosts for the section title, the document title
5
+ * and the curated keyword list. Deliberately dependency-free and deterministic:
6
+ * the server must give the same answer on an air-gapped merchant machine as it
7
+ * does anywhere else, and a payment integration tool should not be shipping
8
+ * merchant questions to a third-party embedding service.
9
+ */
10
+ const BM25_K1 = 1.5;
11
+ const BM25_B = 0.75;
12
+ /**
13
+ * Boosts are applied by repeating high-signal text before tokenising, which
14
+ * keeps the scoring function a plain BM25 with no special cases. They must
15
+ * therefore be whole numbers of repetitions.
16
+ */
17
+ const TITLE_BOOST = 3;
18
+ const KEYWORD_BOOST = 3;
19
+ const DOC_TITLE_BOOST = 2;
20
+ function repeatText(text, times) {
21
+ return Array.from({ length: times }, () => text).join(' ');
22
+ }
23
+ /** Very small suffix stripper. Full stemming is not worth the failure modes here. */
24
+ function stem(token) {
25
+ for (const suffix of ['ing', 'ies', 'es', 's']) {
26
+ if (token.length > suffix.length + 2 && token.endsWith(suffix)) {
27
+ return token.slice(0, -suffix.length);
28
+ }
29
+ }
30
+ return token;
31
+ }
32
+ const STOP_WORDS = new Set([
33
+ 'a',
34
+ 'an',
35
+ 'and',
36
+ 'are',
37
+ 'as',
38
+ 'at',
39
+ 'be',
40
+ 'but',
41
+ 'by',
42
+ 'do',
43
+ 'for',
44
+ 'from',
45
+ 'how',
46
+ 'i',
47
+ 'in',
48
+ 'is',
49
+ 'it',
50
+ 'my',
51
+ 'of',
52
+ 'on',
53
+ 'or',
54
+ 'the',
55
+ 'to',
56
+ 'was',
57
+ 'what',
58
+ 'when',
59
+ 'why',
60
+ 'with',
61
+ 'you',
62
+ 'your',
63
+ ]);
64
+ /**
65
+ * Split text into searchable tokens.
66
+ *
67
+ * Underscores are preserved so `pp_SecureHash` survives as one token, and the
68
+ * bare word forms are emitted too, so a query for "secure hash" still matches it.
69
+ */
70
+ export function tokenise(text) {
71
+ const tokens = [];
72
+ for (const raw of text.toLowerCase().split(/[^a-z0-9_.]+/)) {
73
+ if (raw === '') {
74
+ continue;
75
+ }
76
+ if (!STOP_WORDS.has(raw)) {
77
+ tokens.push(stem(raw));
78
+ }
79
+ if (raw.includes('_')) {
80
+ for (const part of raw.split('_')) {
81
+ if (part.length > 1 && !STOP_WORDS.has(part)) {
82
+ tokens.push(stem(part));
83
+ }
84
+ }
85
+ }
86
+ }
87
+ return tokens;
88
+ }
89
+ function termFrequencies(tokens) {
90
+ const counts = new Map();
91
+ for (const token of tokens) {
92
+ counts.set(token, (counts.get(token) ?? 0) + 1);
93
+ }
94
+ return counts;
95
+ }
96
+ /** Pick the passage around the densest concentration of query terms. */
97
+ function buildExcerpt(text, queryTokens, maxLength = 400) {
98
+ const paragraphs = text.split(/\n{2,}/).filter((paragraph) => paragraph.trim() !== '');
99
+ if (paragraphs.length === 0) {
100
+ return text.slice(0, maxLength);
101
+ }
102
+ let best = paragraphs[0] ?? '';
103
+ let bestScore = -1;
104
+ for (const paragraph of paragraphs) {
105
+ const tokens = new Set(tokenise(paragraph));
106
+ const score = queryTokens.filter((token) => tokens.has(token)).length;
107
+ if (score > bestScore) {
108
+ bestScore = score;
109
+ best = paragraph;
110
+ }
111
+ }
112
+ const trimmed = best.trim();
113
+ return trimmed.length <= maxLength ? trimmed : `${trimmed.slice(0, maxLength)}…`;
114
+ }
115
+ /** Build a search index over the corpus. Cheap enough to build once at start-up. */
116
+ export function buildSearchIndex(corpus) {
117
+ const indexed = [];
118
+ for (const document of corpus.documents()) {
119
+ const { metadata } = document;
120
+ for (const section of document.sections) {
121
+ const boosted = [
122
+ section.text,
123
+ repeatText(section.title, TITLE_BOOST),
124
+ repeatText(metadata.title, DOC_TITLE_BOOST),
125
+ repeatText(metadata.keywords.join(' '), KEYWORD_BOOST),
126
+ ].join(' ');
127
+ const tokens = tokenise(boosted);
128
+ indexed.push({
129
+ section,
130
+ frequencies: termFrequencies(tokens),
131
+ length: tokens.length,
132
+ flowIds: metadata.flowIds,
133
+ });
134
+ }
135
+ }
136
+ const averageLength = indexed.reduce((total, entry) => total + entry.length, 0) / Math.max(indexed.length, 1);
137
+ const documentFrequency = new Map();
138
+ for (const entry of indexed) {
139
+ for (const token of entry.frequencies.keys()) {
140
+ documentFrequency.set(token, (documentFrequency.get(token) ?? 0) + 1);
141
+ }
142
+ }
143
+ const titleByDocId = new Map(corpus.documents().map((document) => [document.metadata.docId, document.metadata.title]));
144
+ return {
145
+ search(query, options = {}) {
146
+ const queryTokens = tokenise(query);
147
+ if (queryTokens.length === 0) {
148
+ return [];
149
+ }
150
+ const { flowId } = options;
151
+ const candidates = flowId === undefined ? indexed : indexed.filter((entry) => entry.flowIds.includes(flowId));
152
+ const scored = candidates
153
+ .map((entry) => {
154
+ let score = 0;
155
+ for (const token of new Set(queryTokens)) {
156
+ const frequency = entry.frequencies.get(token);
157
+ if (frequency === undefined) {
158
+ continue;
159
+ }
160
+ const containing = documentFrequency.get(token) ?? 0;
161
+ const idf = Math.log(1 + (indexed.length - containing + 0.5) / (containing + 0.5));
162
+ const normalisation = BM25_K1 * (1 - BM25_B + (BM25_B * entry.length) / averageLength);
163
+ score += idf * ((frequency * (BM25_K1 + 1)) / (frequency + normalisation));
164
+ }
165
+ return {
166
+ docId: entry.section.docId,
167
+ sectionId: entry.section.sectionId,
168
+ documentTitle: titleByDocId.get(entry.section.docId) ?? entry.section.docId,
169
+ sectionTitle: entry.section.title,
170
+ uri: entry.section.uri,
171
+ score: Number(score.toFixed(4)),
172
+ excerpt: buildExcerpt(entry.section.text, queryTokens),
173
+ };
174
+ })
175
+ .filter((result) => result.score > 0)
176
+ .sort((left, right) => right.score - left.score);
177
+ return scored.slice(0, options.limit ?? 5);
178
+ },
179
+ };
180
+ }
181
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/knowledge/search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Where the loaders read corpus files from.
3
+ *
4
+ * Each source is rooted at one part of the corpus — the flow specifications, the
5
+ * documents, the templates, the diagnostics — and addresses entries by name
6
+ * within it. Every loader takes one instead of calling `node:fs` itself, so a
7
+ * corpus served from somewhere other than a sibling directory costs one new
8
+ * implementation of this interface rather than an edit to every loader.
9
+ *
10
+ * Deliberately synchronous. The loaders run at start-up, on a synchronous path
11
+ * that reaches the composition root; making the seam asynchronous would push
12
+ * `await` through every caller for no benefit while the only implementation
13
+ * reads local files.
14
+ */
15
+ export interface CorpusSource {
16
+ /** The root this source reads from. Named in errors so a failure says where it looked. */
17
+ readonly location: string;
18
+ /** Where `segments` resolves to. For error messages; never opened. */
19
+ locate(...segments: readonly string[]): string;
20
+ /** Read one entry as UTF-8 text. Throws when it cannot be read. */
21
+ readText(...segments: readonly string[]): string;
22
+ /** Names of the entries directly under `segments`. Throws when there is no such directory. */
23
+ entryNames(...segments: readonly string[]): readonly string[];
24
+ }
25
+ /**
26
+ * Read corpus entries from a local directory.
27
+ *
28
+ * Nothing is cached here. A source that memoised reads would serve an edited
29
+ * flow specification or template stale until the process restarts, which is the
30
+ * failure mode `loadTemplate` is deliberately built to avoid.
31
+ */
32
+ export declare function localCorpusSource(directory: string): CorpusSource;
33
+ /**
34
+ * Read corpus entries from a map held in memory, keyed by entry name.
35
+ *
36
+ * The published package cannot rely on a corpus directory surviving beside it.
37
+ * A consumer that installs the server gets whatever `files` shipped, and a
38
+ * flow specification read from disk at run time is one packaging mistake away
39
+ * from a start-up failure on someone else's machine. Serialising the
40
+ * specifications into generated source and handing the loaders this source
41
+ * instead makes the catalogue part of the module graph: it is present wherever
42
+ * the code is, and the loaders keep their existing behaviour because they never
43
+ * knew what was behind the seam.
44
+ *
45
+ * Keys are the '/'-joined segments a loader addresses, so `flows/a.json` is
46
+ * reached as `readText('flows', 'a.json')` or, from a source already rooted at
47
+ * the flows, as `readText('a.json')`.
48
+ *
49
+ * Nothing is cached beyond the map itself. The map is the corpus, so there is
50
+ * no slower store behind it for a cache to spare.
51
+ */
52
+ export declare function memoryCorpusSource(entries: Readonly<Record<string, string>>, location?: string): CorpusSource;
53
+ /**
54
+ * Accept either a source or a plain directory.
55
+ *
56
+ * The loaders have always taken a directory, and a caller pointing at one on
57
+ * disk should not have to construct a source to do it.
58
+ */
59
+ export declare function toCorpusSource(source: CorpusSource | string): CorpusSource;
60
+ //# sourceMappingURL=source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/knowledge/source.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,YAAY;IAC3B,0FAA0F;IAC1F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,sEAAsE;IACtE,MAAM,CAAC,GAAG,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC;IAC/C,mEAAmE;IACnE,QAAQ,CAAC,GAAG,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC;IACjD,8FAA8F;IAC9F,UAAU,CAAC,GAAG,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE,CAAC;CAC/D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CAOjE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,QAAQ,SAAa,GAAG,YAAY,CA6CjH;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,YAAY,CAE1E"}
@@ -0,0 +1,91 @@
1
+ import { readFileSync, readdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ /**
4
+ * Read corpus entries from a local directory.
5
+ *
6
+ * Nothing is cached here. A source that memoised reads would serve an edited
7
+ * flow specification or template stale until the process restarts, which is the
8
+ * failure mode `loadTemplate` is deliberately built to avoid.
9
+ */
10
+ export function localCorpusSource(directory) {
11
+ return {
12
+ location: directory,
13
+ locate: (...segments) => join(directory, ...segments),
14
+ readText: (...segments) => readFileSync(join(directory, ...segments), 'utf8'),
15
+ entryNames: (...segments) => readdirSync(join(directory, ...segments)),
16
+ };
17
+ }
18
+ /**
19
+ * Read corpus entries from a map held in memory, keyed by entry name.
20
+ *
21
+ * The published package cannot rely on a corpus directory surviving beside it.
22
+ * A consumer that installs the server gets whatever `files` shipped, and a
23
+ * flow specification read from disk at run time is one packaging mistake away
24
+ * from a start-up failure on someone else's machine. Serialising the
25
+ * specifications into generated source and handing the loaders this source
26
+ * instead makes the catalogue part of the module graph: it is present wherever
27
+ * the code is, and the loaders keep their existing behaviour because they never
28
+ * knew what was behind the seam.
29
+ *
30
+ * Keys are the '/'-joined segments a loader addresses, so `flows/a.json` is
31
+ * reached as `readText('flows', 'a.json')` or, from a source already rooted at
32
+ * the flows, as `readText('a.json')`.
33
+ *
34
+ * Nothing is cached beyond the map itself. The map is the corpus, so there is
35
+ * no slower store behind it for a cache to spare.
36
+ */
37
+ export function memoryCorpusSource(entries, location = '<memory>') {
38
+ return {
39
+ location,
40
+ locate: (...segments) => `${location}:${segments.join('/')}`,
41
+ readText: (...segments) => {
42
+ const key = segments.join('/');
43
+ const text = entries[key];
44
+ if (text === undefined) {
45
+ throw new Error(`No entry "${key}" in ${location}.`);
46
+ }
47
+ return text;
48
+ },
49
+ entryNames: (...segments) => {
50
+ // With no prefix the whole map is the answer, keys intact. A source built
51
+ // for one part of the corpus is flat, and a loader that lists the root
52
+ // and reads each name back expects the names it can read.
53
+ if (segments.length === 0) {
54
+ return Object.keys(entries).sort();
55
+ }
56
+ const prefix = `${segments.join('/')}/`;
57
+ const names = new Set();
58
+ for (const key of Object.keys(entries)) {
59
+ if (!key.startsWith(prefix)) {
60
+ continue;
61
+ }
62
+ // Entries nested deeper than the prefix contribute only the segment
63
+ // directly beneath it, matching what `readdirSync` reports for a
64
+ // subdirectory rather than leaking the whole path. Sliced at the
65
+ // separator rather than destructured from `split`, because
66
+ // `noUncheckedIndexedAccess` would type the first element as possibly
67
+ // absent and the guard against that could never run — `split` always
68
+ // yields at least one element.
69
+ const remainder = key.slice(prefix.length);
70
+ const boundary = remainder.indexOf('/');
71
+ const name = boundary === -1 ? remainder : remainder.slice(0, boundary);
72
+ // An entry whose name *is* the prefix addresses the directory itself and
73
+ // names nothing under it.
74
+ if (name !== '') {
75
+ names.add(name);
76
+ }
77
+ }
78
+ return [...names].sort();
79
+ },
80
+ };
81
+ }
82
+ /**
83
+ * Accept either a source or a plain directory.
84
+ *
85
+ * The loaders have always taken a directory, and a caller pointing at one on
86
+ * disk should not have to construct a source to do it.
87
+ */
88
+ export function toCorpusSource(source) {
89
+ return typeof source === 'string' ? localCorpusSource(source) : source;
90
+ }
91
+ //# sourceMappingURL=source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/knowledge/source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { z } from 'zod';
2
+ /** Metadata for one curated document, from `knowledge/docs/index.json`. */
3
+ export declare const documentMetadataSchema: z.ZodObject<{
4
+ docId: z.ZodString;
5
+ title: z.ZodString;
6
+ sourcePdf: z.ZodString;
7
+ version: z.ZodString;
8
+ flowIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
9
+ keywords: z.ZodDefault<z.ZodArray<z.ZodString>>;
10
+ }, z.core.$strip>;
11
+ export declare const documentIndexSchema: z.ZodObject<{
12
+ corpusVersion: z.ZodString;
13
+ note: z.ZodOptional<z.ZodString>;
14
+ documents: z.ZodArray<z.ZodObject<{
15
+ docId: z.ZodString;
16
+ title: z.ZodString;
17
+ sourcePdf: z.ZodString;
18
+ version: z.ZodString;
19
+ flowIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
20
+ keywords: z.ZodDefault<z.ZodArray<z.ZodString>>;
21
+ }, z.core.$strip>>;
22
+ }, z.core.$strict>;
23
+ export type DocumentMetadata = z.infer<typeof documentMetadataSchema>;
24
+ /** One `## Heading {#anchor}` block within a document. */
25
+ export interface DocumentSection {
26
+ readonly docId: string;
27
+ readonly sectionId: string;
28
+ readonly title: string;
29
+ readonly text: string;
30
+ /** `jazzcash://docs/{docId}#{sectionId}` */
31
+ readonly uri: string;
32
+ }
33
+ export interface CorpusDocument {
34
+ readonly metadata: DocumentMetadata;
35
+ /** Everything before the first `##` heading. */
36
+ readonly preamble: string;
37
+ readonly sections: readonly DocumentSection[];
38
+ readonly markdown: string;
39
+ }
40
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/knowledge/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,2EAA2E;AAC3E,eAAO,MAAM,sBAAsB;;;;;;;iBAUjC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;kBAI9B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,0DAA0D;AAC1D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B"}
@@ -0,0 +1,19 @@
1
+ import { z } from 'zod';
2
+ /** Metadata for one curated document, from `knowledge/docs/index.json`. */
3
+ export const documentMetadataSchema = z.object({
4
+ docId: z.string().min(1),
5
+ title: z.string().min(1),
6
+ /** Path of the PDF this was transcribed from, for provenance and re-checking. */
7
+ sourcePdf: z.string().min(1),
8
+ version: z.string().min(1),
9
+ /** Flows this document describes, used to scope a search. */
10
+ flowIds: z.array(z.string()).default([]),
11
+ /** Search boosts. Terms a merchant is likely to use that the prose may not contain. */
12
+ keywords: z.array(z.string()).default([]),
13
+ });
14
+ export const documentIndexSchema = z.strictObject({
15
+ corpusVersion: z.string().min(1),
16
+ note: z.string().optional(),
17
+ documents: z.array(documentMetadataSchema).min(1),
18
+ });
19
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/knowledge/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,2EAA2E;AAC3E,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,iFAAiF;IACjF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,6DAA6D;IAC7D,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACxC,uFAAuF;IACvF,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC1C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,YAAY,CAAC;IAChD,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAChC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CAClD,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Walk upwards to the nearest directory that owns a `package.json`.
3
+ *
4
+ * Exported so the walk can be exercised from somewhere other than this module's
5
+ * own directory, which is the only way to prove that moving the corpus leaves
6
+ * root discovery intact.
7
+ */
8
+ export declare function findPackageRoot(startDirectory: string): string;
9
+ /** Absolute path to the package root. Cached after the first successful walk. */
10
+ export declare function packageRoot(): string;
11
+ /**
12
+ * Absolute path to the directory holding the bundled corpus.
13
+ *
14
+ * Derived from the package root rather than being what identifies it, so this is
15
+ * the single place that has to change if the corpus stops shipping beside the
16
+ * code — and the single place `MCP_CORPUS_DIR` has to override.
17
+ *
18
+ * The override is validated on every call rather than memoised: the check is one
19
+ * `stat` in front of a file read that is about to happen anyway, and a cached
20
+ * answer would make the variable unreadable to anything that sets it after this
21
+ * module was first imported.
22
+ */
23
+ export declare function corpusRoot(): string;
24
+ /** Absolute path to `knowledge/`, optionally joined with further segments. */
25
+ export declare function knowledgePath(...segments: readonly string[]): string;
26
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAkDA;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAe9D;AAED,iFAAiF;AACjF,wBAAgB,WAAW,IAAI,MAAM,CAGpC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,IAAI,MAAM,CA4BnC;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,GAAG,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAEpE"}