@lerianstudio/matcher-mcp 5.0.0-beta.13 → 5.0.0-beta.131

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 (273) hide show
  1. package/README.md +28 -13
  2. package/dist/auth/request-token.js +11 -69
  3. package/dist/auth/request-token.js.map +1 -1
  4. package/dist/config.js +6 -21
  5. package/dist/config.js.map +1 -1
  6. package/dist/copilot/agent.js +5 -9
  7. package/dist/copilot/agent.js.map +1 -1
  8. package/dist/copilot/provider-anthropic.js +75 -23
  9. package/dist/copilot/provider-anthropic.js.map +1 -1
  10. package/dist/copilot/provider-openrouter.js +5 -18
  11. package/dist/copilot/provider-openrouter.js.map +1 -1
  12. package/dist/copilot/provider-shared.js +11 -0
  13. package/dist/copilot/provider-shared.js.map +1 -1
  14. package/dist/copilot/speech-provider.js +84 -0
  15. package/dist/copilot/speech-provider.js.map +1 -0
  16. package/dist/copilot/sse.js +5 -0
  17. package/dist/copilot/sse.js.map +1 -1
  18. package/dist/copilot/system-prompt.js +6 -2
  19. package/dist/copilot/system-prompt.js.map +1 -1
  20. package/dist/copilot/tools.js +14 -65
  21. package/dist/copilot/tools.js.map +1 -1
  22. package/dist/copilot/transcribe-handler.js +8 -93
  23. package/dist/copilot/transcribe-handler.js.map +1 -1
  24. package/dist/copilot/turn-request.js +76 -0
  25. package/dist/copilot/turn-request.js.map +1 -0
  26. package/dist/copilot/turns-handler.js +11 -102
  27. package/dist/copilot/turns-handler.js.map +1 -1
  28. package/dist/matcher/client.js +14 -0
  29. package/dist/matcher/client.js.map +1 -1
  30. package/dist/matcher/idempotency.js +94 -0
  31. package/dist/matcher/idempotency.js.map +1 -0
  32. package/dist/observability/otel.js +7 -29
  33. package/dist/observability/otel.js.map +1 -1
  34. package/dist/server.js +12 -81
  35. package/dist/server.js.map +1 -1
  36. package/dist/spec/curated-operations.js +111 -95
  37. package/dist/spec/curated-operations.js.map +1 -1
  38. package/dist/spec/enum-policy.js +21 -26
  39. package/dist/spec/enum-policy.js.map +1 -1
  40. package/dist/spec/openapi.yaml +875 -64
  41. package/dist/spec/schema-parity.js +23 -28
  42. package/dist/spec/schema-parity.js.map +1 -1
  43. package/dist/tools/context/create.js +14 -3
  44. package/dist/tools/context/create.js.map +1 -1
  45. package/dist/tools/context/index.js +137 -17
  46. package/dist/tools/context/index.js.map +1 -1
  47. package/dist/tools/context/list.js +9 -35
  48. package/dist/tools/context/list.js.map +1 -1
  49. package/dist/tools/context/setup-progress.js +3 -2
  50. package/dist/tools/context/setup-progress.js.map +1 -1
  51. package/dist/tools/context/shared.js +7 -48
  52. package/dist/tools/context/shared.js.map +1 -1
  53. package/dist/tools/context/update.js +15 -7
  54. package/dist/tools/context/update.js.map +1 -1
  55. package/dist/tools/curated-tool.js +39 -0
  56. package/dist/tools/curated-tool.js.map +1 -0
  57. package/dist/tools/dashboard/index.js +124 -19
  58. package/dist/tools/dashboard/index.js.map +1 -1
  59. package/dist/tools/dashboard/shared.js +9 -68
  60. package/dist/tools/dashboard/shared.js.map +1 -1
  61. package/dist/tools/dispute/close.js +5 -5
  62. package/dist/tools/dispute/close.js.map +1 -1
  63. package/dist/tools/dispute/index.js +34 -6
  64. package/dist/tools/dispute/index.js.map +1 -1
  65. package/dist/tools/dispute/list.js +18 -47
  66. package/dist/tools/dispute/list.js.map +1 -1
  67. package/dist/tools/dispute/shared.js +4 -43
  68. package/dist/tools/dispute/shared.js.map +1 -1
  69. package/dist/tools/dispute/submit-evidence.js +5 -5
  70. package/dist/tools/dispute/submit-evidence.js.map +1 -1
  71. package/dist/tools/exception/add-comment.js +3 -2
  72. package/dist/tools/exception/add-comment.js.map +1 -1
  73. package/dist/tools/exception/adjust-entry.js +5 -5
  74. package/dist/tools/exception/adjust-entry.js.map +1 -1
  75. package/dist/tools/exception/bulk-assign.js +3 -2
  76. package/dist/tools/exception/bulk-assign.js.map +1 -1
  77. package/dist/tools/exception/bulk-dispatch.js +12 -4
  78. package/dist/tools/exception/bulk-dispatch.js.map +1 -1
  79. package/dist/tools/exception/bulk-resolve.js +3 -2
  80. package/dist/tools/exception/bulk-resolve.js.map +1 -1
  81. package/dist/tools/exception/dispatch.js +13 -5
  82. package/dist/tools/exception/dispatch.js.map +1 -1
  83. package/dist/tools/exception/force-match.js +3 -2
  84. package/dist/tools/exception/force-match.js.map +1 -1
  85. package/dist/tools/exception/history.js +8 -24
  86. package/dist/tools/exception/history.js.map +1 -1
  87. package/dist/tools/exception/index.js +88 -18
  88. package/dist/tools/exception/index.js.map +1 -1
  89. package/dist/tools/exception/list.js +14 -57
  90. package/dist/tools/exception/list.js.map +1 -1
  91. package/dist/tools/exception/open-dispute.js +3 -2
  92. package/dist/tools/exception/open-dispute.js.map +1 -1
  93. package/dist/tools/exception/shared.js +10 -46
  94. package/dist/tools/exception/shared.js.map +1 -1
  95. package/dist/tools/fee-rule/create.js +5 -5
  96. package/dist/tools/fee-rule/create.js.map +1 -1
  97. package/dist/tools/fee-rule/index.js +50 -8
  98. package/dist/tools/fee-rule/index.js.map +1 -1
  99. package/dist/tools/fee-rule/list.js +9 -29
  100. package/dist/tools/fee-rule/list.js.map +1 -1
  101. package/dist/tools/fee-rule/shared.js +5 -47
  102. package/dist/tools/fee-rule/shared.js.map +1 -1
  103. package/dist/tools/fee-rule/update.js +5 -5
  104. package/dist/tools/fee-rule/update.js.map +1 -1
  105. package/dist/tools/fee-schedule/create.js +8 -3
  106. package/dist/tools/fee-schedule/create.js.map +1 -1
  107. package/dist/tools/fee-schedule/index.js +62 -11
  108. package/dist/tools/fee-schedule/index.js.map +1 -1
  109. package/dist/tools/fee-schedule/list.js +8 -24
  110. package/dist/tools/fee-schedule/list.js.map +1 -1
  111. package/dist/tools/fee-schedule/shared.js +5 -44
  112. package/dist/tools/fee-schedule/shared.js.map +1 -1
  113. package/dist/tools/fee-schedule/simulate.js +5 -5
  114. package/dist/tools/fee-schedule/simulate.js.map +1 -1
  115. package/dist/tools/fee-schedule/update.js +5 -5
  116. package/dist/tools/fee-schedule/update.js.map +1 -1
  117. package/dist/tools/field-map/create.js +3 -2
  118. package/dist/tools/field-map/create.js.map +1 -1
  119. package/dist/tools/field-map/index.js +65 -11
  120. package/dist/tools/field-map/index.js.map +1 -1
  121. package/dist/tools/field-map/list.js +9 -29
  122. package/dist/tools/field-map/list.js.map +1 -1
  123. package/dist/tools/field-map/shared.js +6 -42
  124. package/dist/tools/field-map/shared.js.map +1 -1
  125. package/dist/tools/field-map/update.js +3 -2
  126. package/dist/tools/field-map/update.js.map +1 -1
  127. package/dist/tools/generic/invoke.js +16 -39
  128. package/dist/tools/generic/invoke.js.map +1 -1
  129. package/dist/tools/ingestion/index.js +100 -12
  130. package/dist/tools/ingestion/index.js.map +1 -1
  131. package/dist/tools/ingestion/job-transactions-list.js +10 -40
  132. package/dist/tools/ingestion/job-transactions-list.js.map +1 -1
  133. package/dist/tools/ingestion/jobs-list.js +9 -35
  134. package/dist/tools/ingestion/jobs-list.js.map +1 -1
  135. package/dist/tools/ingestion/shared.js +4 -41
  136. package/dist/tools/ingestion/shared.js.map +1 -1
  137. package/dist/tools/ingestion/transactions-search.js +9 -44
  138. package/dist/tools/ingestion/transactions-search.js.map +1 -1
  139. package/dist/tools/ingestion/upload.js +3 -2
  140. package/dist/tools/ingestion/upload.js.map +1 -1
  141. package/dist/tools/input-fields.js +51 -0
  142. package/dist/tools/input-fields.js.map +1 -0
  143. package/dist/tools/match-rule/index.js +130 -13
  144. package/dist/tools/match-rule/index.js.map +1 -1
  145. package/dist/tools/match-rule/list.js +9 -33
  146. package/dist/tools/match-rule/list.js.map +1 -1
  147. package/dist/tools/match-rule/shared.js +16 -46
  148. package/dist/tools/match-rule/shared.js.map +1 -1
  149. package/dist/tools/match-rule/update.js +7 -11
  150. package/dist/tools/match-rule/update.js.map +1 -1
  151. package/dist/tools/matching/get.js +5 -5
  152. package/dist/tools/matching/get.js.map +1 -1
  153. package/dist/tools/matching/groups.js +6 -14
  154. package/dist/tools/matching/groups.js.map +1 -1
  155. package/dist/tools/matching/index.js +77 -5
  156. package/dist/tools/matching/index.js.map +1 -1
  157. package/dist/tools/matching/list.js +9 -32
  158. package/dist/tools/matching/list.js.map +1 -1
  159. package/dist/tools/matching/shared.js +5 -46
  160. package/dist/tools/matching/shared.js.map +1 -1
  161. package/dist/tools/query-handler.js +9 -0
  162. package/dist/tools/query-handler.js.map +1 -0
  163. package/dist/tools/report/index.js +260 -30
  164. package/dist/tools/report/index.js.map +1 -1
  165. package/dist/tools/report/shared.js +24 -98
  166. package/dist/tools/report/shared.js.map +1 -1
  167. package/dist/tools/request-fields.js +17 -0
  168. package/dist/tools/request-fields.js.map +1 -0
  169. package/dist/tools/shared-dispatch.js +38 -0
  170. package/dist/tools/shared-dispatch.js.map +1 -0
  171. package/dist/tools/source/create.js +146 -23
  172. package/dist/tools/source/create.js.map +1 -1
  173. package/dist/tools/source/index.js +101 -13
  174. package/dist/tools/source/index.js.map +1 -1
  175. package/dist/tools/source/list.js +9 -32
  176. package/dist/tools/source/list.js.map +1 -1
  177. package/dist/tools/source/shared.js +5 -42
  178. package/dist/tools/source/shared.js.map +1 -1
  179. package/dist/tools/source/update.js +16 -33
  180. package/dist/tools/source/update.js.map +1 -1
  181. package/dist/tools/workspace/usage.js +27 -41
  182. package/dist/tools/workspace/usage.js.map +1 -1
  183. package/package.json +4 -4
  184. package/dist/tools/context/archive.js +0 -37
  185. package/dist/tools/context/archive.js.map +0 -1
  186. package/dist/tools/context/get.js +0 -31
  187. package/dist/tools/context/get.js.map +0 -1
  188. package/dist/tools/context/next-step.js +0 -99
  189. package/dist/tools/context/next-step.js.map +0 -1
  190. package/dist/tools/context/restore.js +0 -34
  191. package/dist/tools/context/restore.js.map +0 -1
  192. package/dist/tools/dashboard/aggregates.js +0 -37
  193. package/dist/tools/dashboard/aggregates.js.map +0 -1
  194. package/dist/tools/dashboard/cash-impact.js +0 -37
  195. package/dist/tools/dashboard/cash-impact.js.map +0 -1
  196. package/dist/tools/dashboard/match-rate.js +0 -37
  197. package/dist/tools/dashboard/match-rate.js.map +0 -1
  198. package/dist/tools/dashboard/metrics.js +0 -37
  199. package/dist/tools/dashboard/metrics.js.map +0 -1
  200. package/dist/tools/dashboard/sla.js +0 -34
  201. package/dist/tools/dashboard/sla.js.map +0 -1
  202. package/dist/tools/dashboard/source-breakdown.js +0 -37
  203. package/dist/tools/dashboard/source-breakdown.js.map +0 -1
  204. package/dist/tools/dashboard/volume.js +0 -37
  205. package/dist/tools/dashboard/volume.js.map +0 -1
  206. package/dist/tools/dispute/get.js +0 -27
  207. package/dist/tools/dispute/get.js.map +0 -1
  208. package/dist/tools/exception/delete-comment.js +0 -40
  209. package/dist/tools/exception/delete-comment.js.map +0 -1
  210. package/dist/tools/exception/get.js +0 -34
  211. package/dist/tools/exception/get.js.map +0 -1
  212. package/dist/tools/exception/list-comments.js +0 -35
  213. package/dist/tools/exception/list-comments.js.map +0 -1
  214. package/dist/tools/fee-rule/delete.js +0 -27
  215. package/dist/tools/fee-rule/delete.js.map +0 -1
  216. package/dist/tools/fee-rule/get.js +0 -27
  217. package/dist/tools/fee-rule/get.js.map +0 -1
  218. package/dist/tools/fee-schedule/delete.js +0 -32
  219. package/dist/tools/fee-schedule/delete.js.map +0 -1
  220. package/dist/tools/fee-schedule/get.js +0 -30
  221. package/dist/tools/fee-schedule/get.js.map +0 -1
  222. package/dist/tools/field-map/delete.js +0 -37
  223. package/dist/tools/field-map/delete.js.map +0 -1
  224. package/dist/tools/field-map/get.js +0 -43
  225. package/dist/tools/field-map/get.js.map +0 -1
  226. package/dist/tools/ingestion/job-errors-list.js +0 -45
  227. package/dist/tools/ingestion/job-errors-list.js.map +0 -1
  228. package/dist/tools/ingestion/job-get.js +0 -42
  229. package/dist/tools/ingestion/job-get.js.map +0 -1
  230. package/dist/tools/ingestion/transaction-ignore.js +0 -51
  231. package/dist/tools/ingestion/transaction-ignore.js.map +0 -1
  232. package/dist/tools/match-rule/create.js +0 -67
  233. package/dist/tools/match-rule/create.js.map +0 -1
  234. package/dist/tools/match-rule/delete.js +0 -35
  235. package/dist/tools/match-rule/delete.js.map +0 -1
  236. package/dist/tools/match-rule/get.js +0 -32
  237. package/dist/tools/match-rule/get.js.map +0 -1
  238. package/dist/tools/match-rule/reorder.js +0 -45
  239. package/dist/tools/match-rule/reorder.js.map +0 -1
  240. package/dist/tools/matching/start.js +0 -81
  241. package/dist/tools/matching/start.js.map +0 -1
  242. package/dist/tools/report/count-exceptions.js +0 -46
  243. package/dist/tools/report/count-exceptions.js.map +0 -1
  244. package/dist/tools/report/count-matched.js +0 -47
  245. package/dist/tools/report/count-matched.js.map +0 -1
  246. package/dist/tools/report/count-transactions.js +0 -45
  247. package/dist/tools/report/count-transactions.js.map +0 -1
  248. package/dist/tools/report/count-unmatched.js +0 -45
  249. package/dist/tools/report/count-unmatched.js.map +0 -1
  250. package/dist/tools/report/export-exceptions.js +0 -48
  251. package/dist/tools/report/export-exceptions.js.map +0 -1
  252. package/dist/tools/report/export-matched.js +0 -49
  253. package/dist/tools/report/export-matched.js.map +0 -1
  254. package/dist/tools/report/export-summary.js +0 -49
  255. package/dist/tools/report/export-summary.js.map +0 -1
  256. package/dist/tools/report/export-unmatched.js +0 -49
  257. package/dist/tools/report/export-unmatched.js.map +0 -1
  258. package/dist/tools/report/export-variance.js +0 -48
  259. package/dist/tools/report/export-variance.js.map +0 -1
  260. package/dist/tools/report/matched.js +0 -48
  261. package/dist/tools/report/matched.js.map +0 -1
  262. package/dist/tools/report/summary.js +0 -43
  263. package/dist/tools/report/summary.js.map +0 -1
  264. package/dist/tools/report/unmatched.js +0 -48
  265. package/dist/tools/report/unmatched.js.map +0 -1
  266. package/dist/tools/report/variance.js +0 -48
  267. package/dist/tools/report/variance.js.map +0 -1
  268. package/dist/tools/source/archive.js +0 -46
  269. package/dist/tools/source/archive.js.map +0 -1
  270. package/dist/tools/source/get.js +0 -57
  271. package/dist/tools/source/get.js.map +0 -1
  272. package/dist/tools/source/restore.js +0 -39
  273. package/dist/tools/source/restore.js.map +0 -1
@@ -11,11 +11,13 @@
11
11
  // - the five exports: the common date filter plus a csv|pdf format, returning
12
12
  // a base64 STRING the caller must decode.
13
13
  //
14
- // This module factors the path builder, the three reusable query builders, and
15
- // the relay/error-mapping boilerplate exactly once so the thirteen tools stay
16
- // thin (just "name the suffix + pick the query builder"). The relay shape is
17
- // identical to the source / fee-schedule / match-rule verticals so curated and
18
- // generic surfaces map matcher errors through the same path (toToolError).
14
+ // This module factors the path builder, the contextId field builder and the
15
+ // three reusable query builders exactly once so each of the thirteen tools is
16
+ // one table row in index.ts (just "name the suffix + pick the query builder").
17
+ // The relay itself lives in shared-dispatch.ts, reached through the shared
18
+ // registration loop and shared with the source / fee-schedule / match-rule
19
+ // verticals, so curated and generic surfaces map matcher errors through the
20
+ // same path (toToolError).
19
21
  //
20
22
  // Security: the bearer token is never read here directly — requireMatcherClient
21
23
  // owns the request-scoped relay and fails closed when no usable credential was
@@ -31,8 +33,8 @@
31
33
  // out explicitly so a model reads the warning before it reports a windowed
32
34
  // number as the whole reconciliation result.
33
35
  import { z } from 'zod';
34
- import { requireMatcherClient, UnauthenticatedError, } from '../../auth/request-token.js';
35
- import { isMatcherApiError, toToolError } from '../tool-error.js';
36
+ import { pageLimit, reportDateFrom, reportDateTo } from '../input-fields.js';
37
+ import { pickQuery } from '../request-fields.js';
36
38
  /** Sort-order enum shared by the paginated report ops (created_at asc|desc). */
37
39
  export const REPORT_SORT_ORDERS = ['asc', 'desc'];
38
40
  /** Export-format enum shared by the five export ops (csv|pdf). */
@@ -47,27 +49,22 @@ export const REPORT_EXPORT_FORMATS = ['csv', 'pdf'];
47
49
  export function contextReportPath(contextId, suffix) {
48
50
  return `/v1/reports/contexts/${encodeURIComponent(contextId)}/${suffix}`;
49
51
  }
52
+ /**
53
+ * Build a row's `contextId` path field. Every report op declares the same
54
+ * validation and differs only in the sentence naming what it reports on, so the
55
+ * description is supplied verbatim per row and nothing else is repeated.
56
+ */
57
+ export function contextIdField(description) {
58
+ return z.string().min(1).describe(description);
59
+ }
50
60
  /**
51
61
  * The common date-window + source filter every report op accepts. Factored as a
52
62
  * raw-shape fragment so each op's inputSchema spreads it in and stays focused on
53
63
  * what is unique to that op. No tenant field — matcher scopes to the token.
54
64
  */
55
65
  export const reportFilterInputShape = {
56
- date_from: z
57
- .string()
58
- .optional()
59
- .describe('Start date (YYYY-MM-DD), inclusive. Optional — if omitted (with ' +
60
- 'date_to), matcher defaults to the last ~30 days, SILENTLY EXCLUDING ' +
61
- 'everything older. A windowed result is NOT "the reconciliation ' +
62
- 'result" — for a complete picture, pass an explicit date_from/date_to ' +
63
- '(max 90-day span).'),
64
- date_to: z
65
- .string()
66
- .optional()
67
- .describe('End date (YYYY-MM-DD), inclusive. Optional — if omitted, matcher ' +
68
- 'defaults to tomorrow (UTC). Combined with an omitted date_from this ' +
69
- 'silently clips the window to the last ~30 days; pass an explicit ' +
70
- 'date_from/date_to (max 90-day span) for the full picture.'),
66
+ date_from: reportDateFrom,
67
+ date_to: reportDateTo,
71
68
  source_id: z
72
69
  .string()
73
70
  .optional()
@@ -80,13 +77,7 @@ export const reportPaginationInputShape = {
80
77
  .optional()
81
78
  .describe('Opaque pagination cursor from a prior response. Re-call with the ' +
82
79
  'returned pagination.next to page forward (there is no auto-pagination).'),
83
- limit: z
84
- .number()
85
- .int()
86
- .min(1)
87
- .max(200)
88
- .optional()
89
- .describe('Maximum number of records to return (1–200, default 20).'),
80
+ limit: pageLimit,
90
81
  sort_order: z
91
82
  .enum(REPORT_SORT_ORDERS)
92
83
  .optional()
@@ -99,91 +90,26 @@ export const reportFormatInputShape = {
99
90
  .optional()
100
91
  .describe('Export format (csv|pdf, default csv).'),
101
92
  };
102
- /** Append the date-window + source filter, omitting unset knobs. */
103
- function appendReportFilter(query, args) {
104
- if (args.date_from !== undefined) {
105
- query.date_from = args.date_from;
106
- }
107
- if (args.date_to !== undefined) {
108
- query.date_to = args.date_to;
109
- }
110
- if (args.source_id !== undefined) {
111
- query.source_id = args.source_id;
112
- }
113
- }
93
+ const REPORT_FILTER_KEYS = ['date_from', 'date_to', 'source_id'];
114
94
  /**
115
95
  * Build the query for a count or summary op: the date filter only. Returns
116
96
  * undefined when nothing is set so the request URL stays bare.
117
97
  */
118
98
  export function buildReportFilterQuery(args) {
119
- const query = {};
120
- appendReportFilter(query, args);
121
- return Object.keys(query).length > 0 ? query : undefined;
99
+ return pickQuery(args, REPORT_FILTER_KEYS);
122
100
  }
123
101
  /**
124
102
  * Build the query for a paginated "get report" op: the date filter plus
125
103
  * cursor/limit/sort_order. Returns undefined when nothing is set.
126
104
  */
127
105
  export function buildReportPaginatedQuery(args) {
128
- const query = {};
129
- appendReportFilter(query, args);
130
- if (args.cursor !== undefined) {
131
- query.cursor = args.cursor;
132
- }
133
- if (args.limit !== undefined) {
134
- query.limit = args.limit;
135
- }
136
- if (args.sort_order !== undefined) {
137
- query.sort_order = args.sort_order;
138
- }
139
- return Object.keys(query).length > 0 ? query : undefined;
106
+ return pickQuery(args, [...REPORT_FILTER_KEYS, 'cursor', 'limit', 'sort_order']);
140
107
  }
141
108
  /**
142
109
  * Build the query for an export op: the date filter plus the csv|pdf format.
143
110
  * Returns undefined when nothing is set.
144
111
  */
145
112
  export function buildReportExportQuery(args) {
146
- const query = {};
147
- appendReportFilter(query, args);
148
- if (args.format !== undefined) {
149
- query.format = args.format;
150
- }
151
- return Object.keys(query).length > 0 ? query : undefined;
152
- }
153
- /**
154
- * Run one assembled request through the relay: fail-closed auth, dispatch, and
155
- * RFC 9457 → tool-error mapping — identical to the generic invoke's dispatch so
156
- * both surfaces produce the same structured error shape.
157
- *
158
- * `clientFor` is injectable for tests; production callers pass nothing and get
159
- * the request-scoped, fail-closed `requireMatcherClient`.
160
- */
161
- export async function dispatchReport(request, extra, clientFor = requireMatcherClient) {
162
- let client;
163
- try {
164
- // Fail-closed on a missing / empty / non-Bearer credential.
165
- client = clientFor(extra);
166
- }
167
- catch (err) {
168
- if (err instanceof UnauthenticatedError) {
169
- return { isError: true, content: [{ type: 'text', text: err.message }] };
170
- }
171
- throw err;
172
- }
173
- try {
174
- const result = await client.request(request);
175
- // Success → matcher's JSON returned as-is. Exports return a base64 STRING
176
- // here verbatim (the caller decodes it); a 204/empty body → null.
177
- return { content: [{ type: 'text', text: JSON.stringify(result ?? null) }] };
178
- }
179
- catch (err) {
180
- // RFC 9457 problem → the SHARED structured tool error (status/title/detail/
181
- // code preserved). A non-matcher error is a bug, not a matcher failure, and
182
- // is re-thrown rather than masqueraded as one.
183
- if (isMatcherApiError(err)) {
184
- return toToolError(err);
185
- }
186
- throw err;
187
- }
113
+ return pickQuery(args, [...REPORT_FILTER_KEYS, 'format']);
188
114
  }
189
115
  //# sourceMappingURL=shared.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/tools/report/shared.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/tools/report/shared.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /** Omit only unset knobs; keep zero and empty strings for Matcher to validate. */
2
+ export function optionalQuery(fields) {
3
+ const entries = Object.entries(fields).filter(([, value]) => value !== undefined);
4
+ return entries.length > 0 ? Object.fromEntries(entries) : undefined;
5
+ }
6
+ /** Explicit allowlist: routing ids and other input fields never leak into queries. */
7
+ export function pickQuery(args, keys) {
8
+ return optionalQuery(Object.fromEntries(keys.map((key) => [key, args[key]])));
9
+ }
10
+ /** Preserve object-rest body semantics, including explicit undefined and null. */
11
+ export function bodyWithout(args, keys) {
12
+ const body = { ...args };
13
+ for (const key of keys)
14
+ delete body[key];
15
+ return body;
16
+ }
17
+ //# sourceMappingURL=request-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-fields.js","sourceRoot":"","sources":["../../src/tools/request-fields.ts"],"names":[],"mappings":"AAIA,kFAAkF;AAClF,MAAM,UAAU,aAAa,CAC3B,MAAkC;IAElC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAA;IACjF,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACrE,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,SAAS,CACvB,IAAsC,EACtC,IAAoB;IAEpB,OAAO,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAC/E,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,WAAW,CACzB,IAAU,EACV,IAAoB;IAEpB,MAAM,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,CAAA;IACxB,KAAK,MAAM,GAAG,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAA;IACxC,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -0,0 +1,38 @@
1
+ // Shared execution for curated tool families and the generic invoker.
2
+ //
3
+ // Curated families and the generic invoker all use the same relay contract:
4
+ // resolve the request-scoped client, fail closed without a bearer credential,
5
+ // return JSON on success, and preserve MatcherApiError details as structured
6
+ // tool output. A caller may provide a result transform for tools whose product
7
+ // contract projects the Matcher response (for example, matching rule stats).
8
+ import { requireMatcherClient, UnauthenticatedError, } from '../auth/request-token.js';
9
+ import { isMatcherApiError, toToolError } from './tool-error.js';
10
+ /**
11
+ * Run one assembled request through the fail-closed relay and common tool
12
+ * result mapping. The optional transform is applied only after a successful
13
+ * Matcher response; errors always retain the shared structured shape.
14
+ */
15
+ export async function dispatchToolRequest(request, extra, clientFor = requireMatcherClient, transform) {
16
+ let client;
17
+ try {
18
+ client = clientFor(extra);
19
+ }
20
+ catch (err) {
21
+ if (err instanceof UnauthenticatedError) {
22
+ return { isError: true, content: [{ type: 'text', text: err.message }] };
23
+ }
24
+ throw err;
25
+ }
26
+ try {
27
+ const result = await client.request(request);
28
+ const output = transform ? transform(result) : result;
29
+ return { content: [{ type: 'text', text: JSON.stringify(output ?? null) }] };
30
+ }
31
+ catch (err) {
32
+ if (isMatcherApiError(err)) {
33
+ return toToolError(err);
34
+ }
35
+ throw err;
36
+ }
37
+ }
38
+ //# sourceMappingURL=shared-dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-dispatch.js","sourceRoot":"","sources":["../../src/tools/shared-dispatch.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,+EAA+E;AAC/E,6EAA6E;AAG7E,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GAErB,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAQhE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAuB,EACvB,KAAmC,EACnC,YAAkC,oBAAoB,EACtD,SAA+B;IAE/B,IAAI,MAAqB,CAAA;IACzB,IAAI,CAAC;QACH,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,oBAAoB,EAAE,CAAC;YACxC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAA;QAC1E,CAAC;QACD,MAAM,GAAG,CAAA;IACX,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAC5C,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;QACrD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,CAAC,EAAE,CAAA;IAC9E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,WAAW,CAAC,GAAG,CAAC,CAAA;QACzB,CAAC;QACD,MAAM,GAAG,CAAA;IACX,CAAC;AACH,CAAC"}
@@ -11,7 +11,9 @@
11
11
  // relayed token's tenant), NOT a tenant field. No tenant field exists in the
12
12
  // schema: the source is created for the tenant of the relayed bearer token.
13
13
  import { z } from 'zod';
14
- import { contextSourcesPath, dispatchSource } from './shared.js';
14
+ import { bodyWithout } from '../request-fields.js';
15
+ import { dispatchToolRequest } from '../shared-dispatch.js';
16
+ import { contextSourcesPath } from './shared.js';
15
17
  /** Origin of the source data (LEDGER ledger / BANK feed / GATEWAY / CUSTOM / FETCHER pull). */
16
18
  export const SOURCE_TYPES = [
17
19
  'LEDGER',
@@ -22,6 +24,142 @@ export const SOURCE_TYPES = [
22
24
  ];
23
25
  /** Matching side this source feeds — the two sides reconciled against each other. */
24
26
  export const SOURCE_SIDES = ['LEFT', 'RIGHT'];
27
+ // --- Reserved `config` vocabularies -----------------------------------------
28
+ //
29
+ // CLOSED, SLOW-MOVING ALGEBRAS, so they are modeled as closed Zod enums per the
30
+ // enum policy (docs/enum-policy.md): a file encoding, a CSV delimiter, an ISO
31
+ // 20022 element choice and a duplicate-collision strategy do not grow with the
32
+ // connector roadmap. Each set is the one the OpenAPI contract publishes, which
33
+ // the Go domain builds from its own vocabulary slices — so the parity gate keeps
34
+ // these honest rather than a comment promising it.
35
+ /** File character encoding. Default utf-8. */
36
+ export const DIALECT_ENCODINGS = [
37
+ 'utf-8',
38
+ 'utf-8-sig',
39
+ 'cp1252',
40
+ 'iso-8859-1',
41
+ ];
42
+ /** CSV field separator. Default comma. */
43
+ export const DIALECT_DELIMITERS = ['comma', 'semicolon', 'tab', 'pipe'];
44
+ /** Amount decimal convention: dot is 1234.56, comma is 1.234,56. Default dot. */
45
+ export const DIALECT_DECIMAL_STYLES = ['dot', 'comma'];
46
+ /** Date convention. Default iso. */
47
+ export const DIALECT_DATE_STYLES = ['iso', 'iso_offset', 'dmy', 'mdy'];
48
+ /**
49
+ * What happens to a row repeating the duplicate key. The default first, and all
50
+ * three offered with EQUAL WEIGHT: the tool adds no confirmation field, no second
51
+ * step and no extra permission around KEEP_FIRST. Describing what each one does
52
+ * is the tool's whole product; the enum's only job is refusing a fourth value
53
+ * before it costs a round trip.
54
+ */
55
+ export const DUPLICATE_POLICIES = [
56
+ 'FLAG_AS_EXCEPTION',
57
+ 'KEEP_FIRST',
58
+ 'REJECT',
59
+ ];
60
+ /** The canonical field-map names a duplicate key may be built from. */
61
+ export const DUPLICATE_KEY_FIELDS = [
62
+ 'external_id',
63
+ 'amount',
64
+ 'currency',
65
+ 'date',
66
+ 'description',
67
+ 'fee_amount',
68
+ 'fee_currency',
69
+ ];
70
+ /** What happens to a row whose mapped external id is blank. Default REJECT. */
71
+ export const BLANK_EXTERNAL_ID_POLICIES = ['REJECT', 'NEEDS_REVIEW'];
72
+ /** camt.053 entry-date element. Default booking. */
73
+ export const CAMT053_DATE_BASES = ['booking', 'valuation'];
74
+ /** camt.053 entry-reference element. Default ntry_ref. */
75
+ export const CAMT053_EXTERNAL_ID_SOURCES = [
76
+ 'ntry_ref',
77
+ 'end_to_end_id',
78
+ 'tx_id',
79
+ ];
80
+ /**
81
+ * The source `config` object.
82
+ *
83
+ * `.passthrough()` is load-bearing, not laziness: the object stays OPEN because a
84
+ * source pulling from an aggregator or a fetcher carries connector keys nobody
85
+ * enumerates here (connection_config_name above all), and the contract keeps it
86
+ * open too. What the seven reserved keys buy is a local refusal — an operator
87
+ * driving this tool blind is told "DISCARD is not a duplicate policy" here rather
88
+ * than after a round trip.
89
+ *
90
+ * duplicate_key_changed_at is DELIBERATELY ABSENT from the seven, and the open
91
+ * object still accepts it. Not offering it is the whole signal: matcher stamps the
92
+ * key itself and discards a client-sent value, so nothing is gained by refusing it
93
+ * here — and something is lost. The key is published on RESPONSES, so an assistant
94
+ * that reads a source and sends the object back carries the stamp it was handed,
95
+ * and a local refusal would fail a payload the server accepts over a value the
96
+ * assistant never authored.
97
+ */
98
+ export const sourceConfigSchema = z
99
+ .object({
100
+ dialect: z
101
+ .object({
102
+ encoding: z.enum(DIALECT_ENCODINGS).optional(),
103
+ delimiter: z.enum(DIALECT_DELIMITERS).optional(),
104
+ decimal_style: z.enum(DIALECT_DECIMAL_STYLES).optional(),
105
+ date_style: z.enum(DIALECT_DATE_STYLES).optional(),
106
+ })
107
+ .optional()
108
+ .describe("How this source's delimited files are encoded and formatted. " +
109
+ 'Declaration-driven only — there is no auto-detection. An absent object, ' +
110
+ 'or an absent sub-key, keeps the defaults (utf-8, comma, dot, iso).'),
111
+ duplicate_policy: z
112
+ .enum(DUPLICATE_POLICIES)
113
+ .optional()
114
+ .describe("What happens to a row that repeats this source's duplicate key. " +
115
+ 'FLAG_AS_EXCEPTION (the default when the key is absent) keeps the repeat ' +
116
+ 'out of the import and raises a duplicate exception on the row it ' +
117
+ 'repeated. KEEP_FIRST drops the repeat and raises nothing, so the ' +
118
+ 'collision leaves no trace anyone can act on. REJECT counts the repeat ' +
119
+ 'as an import error.'),
120
+ duplicate_key: z
121
+ .array(z.enum(DUPLICATE_KEY_FIELDS))
122
+ .min(1)
123
+ .optional()
124
+ .describe('The ordered list of mapped fields that make two rows the same row. Omit ' +
125
+ 'it and rows are deduplicated on external_id alone. A component this ' +
126
+ "source's field map does not fill is refused, because a key over an " +
127
+ 'always-empty field makes every row a duplicate of every other. A source ' +
128
+ 'bound to an aggregator connection (reserved key connection_config_name) ' +
129
+ 'cannot carry a key of its own — the aggregator retracts a movement by ' +
130
+ 'naming its external id, so that id has to stay the row identity, and a ' +
131
+ 'config holding both is refused in either direction. Editing this list ' +
132
+ 'governs later imports only: rows already imported keep the key they were ' +
133
+ 'deduplicated under.'),
134
+ blank_external_id: z
135
+ .enum(BLANK_EXTERNAL_ID_POLICIES)
136
+ .optional()
137
+ .describe('What happens to a row whose mapped external id is blank. REJECT (the ' +
138
+ 'default) fails the row. NEEDS_REVIEW imports it under a synthetic ' +
139
+ 'reference with status PENDING_REVIEW, so a blank reference becomes a ' +
140
+ 'reviewable import instead of an import failure.'),
141
+ camt053: z
142
+ .object({
143
+ date_basis: z.enum(CAMT053_DATE_BASES).optional(),
144
+ external_id_source: z.enum(CAMT053_EXTERNAL_ID_SOURCES).optional(),
145
+ })
146
+ .optional()
147
+ .describe("How this source's camt.053 files map onto the canonical fields; every " +
148
+ 'other field is fixed by ISO 20022 itself. date_basis picks the entry ' +
149
+ 'date (booking = BookgDt/Dt, valuation = ValDt/Dt); external_id_source ' +
150
+ 'picks the reference (ntry_ref = NtryRef, end_to_end_id and tx_id read ' +
151
+ 'NtryDtls/TxDtls/Refs). Absent keeps the ISO defaults (booking, ntry_ref).'),
152
+ fail_on_error_rate_percent: z
153
+ .number()
154
+ .int()
155
+ .min(1)
156
+ .max(99)
157
+ .optional()
158
+ .describe('Fail the whole import when the percentage of failed rows exceeds this ' +
159
+ 'whole number. Absent means never auto-fail. The ceiling is 99, not 100: ' +
160
+ 'the comparison is strict, so 100 could never fire.'),
161
+ })
162
+ .passthrough();
25
163
  /** Zod raw shape for `source_create` input — mirrors CreateSourceRequest. */
26
164
  export const createSourceInputShape = {
27
165
  contextId: z
@@ -44,35 +182,20 @@ export const createSourceInputShape = {
44
182
  .enum(SOURCE_SIDES)
45
183
  .describe('Matching side this source feeds. LEFT and RIGHT are the two sides ' +
46
184
  'reconciled against each other.'),
47
- config: z
48
- .record(z.string(), z.unknown())
185
+ config: sourceConfigSchema
49
186
  .optional()
50
187
  .describe('Source-specific configuration object (connection and parsing settings). ' +
51
- 'Optional; defaults to an empty object server-side when omitted. Its ' +
52
- 'shape depends on the source type and is validated server-side. ' +
53
- 'Reserved key duplicate_key: the ordered list of mapped fields that ' +
54
- 'make two rows the same row (any of external_id, amount, currency, ' +
55
- 'date, description, fee_amount, fee_currency); omit it and rows are ' +
56
- 'deduplicated on external_id alone. A field the field map of this ' +
57
- 'source does not fill is refused. A source bound to an aggregator ' +
58
- 'connection (reserved key connection_config_name) cannot carry a ' +
59
- 'duplicate key of its own — the aggregator retracts a movement by ' +
60
- 'naming its external id, so that id has to stay the row identity; a ' +
61
- 'config holding both is refused, so drop duplicate_key or disconnect ' +
62
- 'the aggregator first. Reserved key duplicate_policy: what ' +
63
- 'happens to a row repeating that key — FLAG_AS_EXCEPTION (the default: ' +
64
- 'the repeat is kept out of the import and raised as a duplicate ' +
65
- 'exception on the row it repeated), KEEP_FIRST (dropped, nothing ' +
66
- 'raised) or REJECT (counted as an import error).'),
188
+ 'Optional; defaults to an empty object server-side when omitted. The seven ' +
189
+ 'reserved keys below are validated here AND server-side; any other key ' +
190
+ '(connector settings, connection_config_name for an aggregator-backed ' +
191
+ 'source) is passed through untouched.'),
67
192
  };
68
193
  /**
69
194
  * Build the POST body from the input minus the path-only `contextId`. Only the
70
195
  * CreateSourceRequest fields are sent; contextId travels in the path.
71
196
  */
72
197
  export function buildCreateBody(args) {
73
- const { contextId: _contextId, ...body } = args;
74
- void _contextId;
75
- return body;
198
+ return bodyWithout(args, ['contextId']);
76
199
  }
77
200
  /**
78
201
  * Register `source_create`. Substitutes contextId into the path, builds the body
@@ -93,7 +216,7 @@ export function registerSourceCreateTool(server) {
93
216
  'that contextId and perform the action it names, repeating until ready.',
94
217
  inputSchema: createSourceInputShape,
95
218
  }, async (args, extra) => {
96
- return dispatchSource({
219
+ return dispatchToolRequest({
97
220
  method: 'POST',
98
221
  path: contextSourcesPath(args.contextId),
99
222
  body: buildCreateBody(args),
@@ -1 +1 @@
1
- {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/tools/source/create.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,EAAE;AACF,iFAAiF;AACjF,iFAAiF;AACjF,iFAAiF;AACjF,6EAA6E;AAC7E,gFAAgF;AAChF,mBAAmB;AACnB,EAAE;AACF,2EAA2E;AAC3E,6EAA6E;AAC7E,4EAA4E;AAE5E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEhE,+FAA+F;AAC/F,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,QAAQ;IACR,MAAM;IACN,SAAS;IACT,QAAQ;IACR,SAAS;CACD,CAAA;AAEV,qFAAqF;AACrF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,OAAO,CAAU,CAAA;AAEtD,6EAA6E;AAC7E,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,wEAAwE;QACtE,yEAAyE;QACzE,iCAAiC,CACpC;IACH,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,EAAE,CAAC;SACP,QAAQ,CAAC,iDAAiD,CAAC;IAC9D,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,YAAY,CAAC;SAClB,QAAQ,CACP,2EAA2E;QACzE,0EAA0E;QAC1E,qCAAqC,CACxC;IACH,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,YAAY,CAAC;SAClB,QAAQ,CACP,oEAAoE;QAClE,gCAAgC,CACnC;IACH,MAAM,EAAE,CAAC;SACN,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;SAC/B,QAAQ,EAAE;SACV,QAAQ,CACP,0EAA0E;QACxE,sEAAsE;QACtE,iEAAiE;QACjE,qEAAqE;QACrE,oEAAoE;QACpE,qEAAqE;QACrE,mEAAmE;QACnE,mEAAmE;QACnE,kEAAkE;QAClE,mEAAmE;QACnE,qEAAqE;QACrE,sEAAsE;QACtE,4DAA4D;QAC5D,wEAAwE;QACxE,iEAAiE;QACjE,kEAAkE;QAClE,iDAAiD,CACpD;CACJ,CAAA;AAOD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAuB;IAEvB,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAA;IAC/C,KAAK,UAAU,CAAA;IACf,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAiB;IACxD,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,WAAW,EACT,oEAAoE;YACpE,4DAA4D;YAC5D,kEAAkE;YAClE,wEAAwE;YACxE,kDAAkD;YAClD,yEAAyE;YACzE,sEAAsE;YACtE,yEAAyE;YACzE,wEAAwE;QAC1E,WAAW,EAAE,sBAAsB;KACpC,EACD,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,OAAO,cAAc,CACnB;YACE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC;YACxC,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC;SAC5B,EACD,KAAK,CACN,CAAA;IACH,CAAC,CACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/tools/source/create.ts"],"names":[],"mappings":"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"}
@@ -5,23 +5,111 @@
5
5
  // explicit that archiving reserves the source name until restore, a trap the
6
6
  // generic invoke surface left implicit.) Sources are fully context-nested on
7
7
  // every op (single-resource ops keep contextId, unlike fee-rules). Each tool
8
- // shares the fail-closed relay (shared.ts) and the RFC 9457 → tool-error mapping
9
- // (toToolError) with the generic surface, so curated and generic map matcher
10
- // errors identically. No tool carries a tenant field; contextId is a routing
11
- // path param matcher validates against the relayed token's tenant.
12
- import { registerSourceArchiveTool } from './archive.js';
8
+ // shares the fail-closed relay (shared-dispatch.ts) and the RFC 9457 →
9
+ // tool-error mapping (toToolError) with the generic surface, so curated and
10
+ // generic map matcher errors identically. No tool carries a tenant field;
11
+ // contextId is a routing path param matcher validates against the relayed
12
+ // token's tenant.
13
+ //
14
+ // The three id-only tools (get, archive, restore) differ only in their name,
15
+ // their method, their path suffix and their description, so they are declared
16
+ // as three rows and registered by the one shared loop; create, list and update
17
+ // carry request bodies or query builders and stay as files.
18
+ import { z } from 'zod';
19
+ import { registerCuratedTools } from '../curated-tool.js';
20
+ import { contextRoutingId } from '../input-fields.js';
13
21
  import { registerSourceCreateTool } from './create.js';
14
- import { registerSourceGetTool } from './get.js';
15
22
  import { registerSourceListTool } from './list.js';
16
- import { registerSourceRestoreTool } from './restore.js';
23
+ import { contextSourcePath } from './shared.js';
17
24
  import { registerSourceUpdateTool } from './update.js';
25
+ /**
26
+ * The source registration list, IN PUBLISHED ORDER: thin tools inline as data
27
+ * rows, the tools that still need their own file by their register function.
28
+ * This list is the order `tools/list` returns, so moving an entry moves what a
29
+ * client renders and what an agent prompt built from it reads first.
30
+ *
31
+ * Every description string is the hand-tuned LLM guidance a client sees
32
+ * verbatim; the published-surface golden is what proves an edit here dropped no
33
+ * character and moved no tool.
34
+ *
35
+ * `source_get`'s text is where an operator reads the duplicate-key
36
+ * declaration back.
37
+ */
38
+ const SOURCE_TOOLS = [
39
+ registerSourceCreateTool,
40
+ registerSourceListTool,
41
+ {
42
+ name: 'source_get',
43
+ description: 'Fetch a single reconciliation source by id (UUID) within a context. ' +
44
+ 'Provide both contextId and sourceId (path params; contextId is not a ' +
45
+ "tenant field). The source must belong to your token's tenant. Returns " +
46
+ 'the source, or a structured RFC 9457 error (e.g. 404 if it does not ' +
47
+ 'exist or is not yours). In the returned config, duplicate_key is the ' +
48
+ 'ordered list of mapped fields that make two rows the same row — absent ' +
49
+ 'means rows are deduplicated on external_id alone — and ' +
50
+ 'duplicate_key_changed_at is the server-set RFC 3339 moment ' +
51
+ 'duplicate-key detection last changed meaning on this source: either ' +
52
+ 'that list changing, or the field map remapping the column a declared ' +
53
+ 'field reads. Rows imported before it keep the key they were ' +
54
+ 'deduplicated under, so a duplicate straddling that moment is not ' +
55
+ 'detected. duplicate_policy is what happens to a repeat: ' +
56
+ 'FLAG_AS_EXCEPTION (the default), KEEP_FIRST or REJECT.',
57
+ inputShape: {
58
+ contextId: contextRoutingId,
59
+ sourceId: z
60
+ .string()
61
+ .min(1)
62
+ .describe('The reconciliation source id (UUID) to fetch.'),
63
+ },
64
+ request: (args) => ({
65
+ method: 'GET',
66
+ path: contextSourcePath(String(args.contextId), String(args.sourceId)),
67
+ }),
68
+ },
69
+ registerSourceUpdateTool,
70
+ {
71
+ name: 'source_archive',
72
+ description: 'Archive (soft-delete) a reconciliation source by id (UUID) within a ' +
73
+ "context. Archiving never erases the source's imported transactions " +
74
+ 'or field map — the source is simply excluded from listings, readiness ' +
75
+ 'counts, clone reads, and the matching working set. The archived name ' +
76
+ 'stays reserved until you restore it, so you cannot create a new source ' +
77
+ 'reusing that name in the context. Provide contextId and sourceId (path ' +
78
+ 'params; contextId is not a tenant field). Returns no content (204), or ' +
79
+ 'a structured RFC 9457 error.',
80
+ inputShape: {
81
+ contextId: contextRoutingId,
82
+ sourceId: z
83
+ .string()
84
+ .min(1)
85
+ .describe('The reconciliation source id (UUID) to archive.'),
86
+ },
87
+ request: (args) => ({
88
+ method: 'POST',
89
+ path: `${contextSourcePath(String(args.contextId), String(args.sourceId))}/archive`,
90
+ }),
91
+ },
92
+ {
93
+ name: 'source_restore',
94
+ description: 'Restore an archived reconciliation source by id (UUID) back into the ' +
95
+ 'live working set, so it counts toward readiness and feeds matching ' +
96
+ 'again. Provide contextId and sourceId (path params; contextId is not a ' +
97
+ 'tenant field). Returns no content (204), or a structured RFC 9457 error.',
98
+ inputShape: {
99
+ contextId: contextRoutingId,
100
+ sourceId: z
101
+ .string()
102
+ .min(1)
103
+ .describe('The archived reconciliation source id (UUID) to restore.'),
104
+ },
105
+ request: (args) => ({
106
+ method: 'POST',
107
+ path: `${contextSourcePath(String(args.contextId), String(args.sourceId))}/restore`,
108
+ }),
109
+ },
110
+ ];
18
111
  /** Register all curated source tools on the given server. */
19
112
  export function registerSourceTools(server) {
20
- registerSourceCreateTool(server);
21
- registerSourceListTool(server);
22
- registerSourceGetTool(server);
23
- registerSourceUpdateTool(server);
24
- registerSourceArchiveTool(server);
25
- registerSourceRestoreTool(server);
113
+ registerCuratedTools(server, SOURCE_TOOLS);
26
114
  }
27
115
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/source/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,gFAAgF;AAChF,gFAAgF;AAChF,iFAAiF;AACjF,6EAA6E;AAC7E,6EAA6E;AAC7E,6EAA6E;AAC7E,iFAAiF;AACjF,6EAA6E;AAC7E,6EAA6E;AAC7E,mEAAmE;AAInE,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAEtD,6DAA6D;AAC7D,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,wBAAwB,CAAC,MAAM,CAAC,CAAA;IAChC,sBAAsB,CAAC,MAAM,CAAC,CAAA;IAC9B,qBAAqB,CAAC,MAAM,CAAC,CAAA;IAC7B,wBAAwB,CAAC,MAAM,CAAC,CAAA;IAChC,yBAAyB,CAAC,MAAM,CAAC,CAAA;IACjC,yBAAyB,CAAC,MAAM,CAAC,CAAA;AACnC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/source/index.ts"],"names":[],"mappings":"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"}