@ttctl/mcp 0.0.0 → 0.1.0-rc.2

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 (195) hide show
  1. package/README.md +72 -9
  2. package/dist/auth.d.ts +40 -0
  3. package/dist/auth.d.ts.map +1 -0
  4. package/dist/auth.js +69 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/data-handling.d.ts +91 -0
  7. package/dist/data-handling.d.ts.map +1 -0
  8. package/dist/data-handling.js +129 -0
  9. package/dist/data-handling.js.map +1 -0
  10. package/dist/diagnostic.d.ts +262 -0
  11. package/dist/diagnostic.d.ts.map +1 -0
  12. package/dist/diagnostic.js +362 -0
  13. package/dist/diagnostic.js.map +1 -0
  14. package/dist/errors.d.ts +54 -0
  15. package/dist/errors.d.ts.map +1 -0
  16. package/dist/errors.js +48 -0
  17. package/dist/errors.js.map +1 -0
  18. package/dist/index.d.ts +8 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +7 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/kill-switch-hook.d.ts +67 -0
  23. package/dist/kill-switch-hook.d.ts.map +1 -0
  24. package/dist/kill-switch-hook.js +61 -0
  25. package/dist/kill-switch-hook.js.map +1 -0
  26. package/dist/server.d.ts +100 -0
  27. package/dist/server.d.ts.map +1 -0
  28. package/dist/server.js +157 -0
  29. package/dist/server.js.map +1 -0
  30. package/dist/tools/_shared.d.ts +227 -0
  31. package/dist/tools/_shared.d.ts.map +1 -0
  32. package/dist/tools/_shared.js +238 -0
  33. package/dist/tools/_shared.js.map +1 -0
  34. package/dist/tools/applications.d.ts +27 -0
  35. package/dist/tools/applications.d.ts.map +1 -0
  36. package/dist/tools/applications.js +192 -0
  37. package/dist/tools/applications.js.map +1 -0
  38. package/dist/tools/availability.d.ts +33 -0
  39. package/dist/tools/availability.d.ts.map +1 -0
  40. package/dist/tools/availability.js +272 -0
  41. package/dist/tools/availability.js.map +1 -0
  42. package/dist/tools/contracts.d.ts +29 -0
  43. package/dist/tools/contracts.d.ts.map +1 -0
  44. package/dist/tools/contracts.js +157 -0
  45. package/dist/tools/contracts.js.map +1 -0
  46. package/dist/tools/engagements.d.ts +36 -0
  47. package/dist/tools/engagements.d.ts.map +1 -0
  48. package/dist/tools/engagements.js +408 -0
  49. package/dist/tools/engagements.js.map +1 -0
  50. package/dist/tools/file-upload.d.ts +133 -0
  51. package/dist/tools/file-upload.d.ts.map +1 -0
  52. package/dist/tools/file-upload.js +247 -0
  53. package/dist/tools/file-upload.js.map +1 -0
  54. package/dist/tools/index.d.ts +28 -0
  55. package/dist/tools/index.d.ts.map +1 -0
  56. package/dist/tools/index.js +133 -0
  57. package/dist/tools/index.js.map +1 -0
  58. package/dist/tools/jobs.d.ts +37 -0
  59. package/dist/tools/jobs.d.ts.map +1 -0
  60. package/dist/tools/jobs.js +505 -0
  61. package/dist/tools/jobs.js.map +1 -0
  62. package/dist/tools/output-schemas.d.ts +129 -0
  63. package/dist/tools/output-schemas.d.ts.map +1 -0
  64. package/dist/tools/output-schemas.js +138 -0
  65. package/dist/tools/output-schemas.js.map +1 -0
  66. package/dist/tools/payments.d.ts +36 -0
  67. package/dist/tools/payments.d.ts.map +1 -0
  68. package/dist/tools/payments.js +373 -0
  69. package/dist/tools/payments.js.map +1 -0
  70. package/dist/tools/profile/certifications.d.ts +18 -0
  71. package/dist/tools/profile/certifications.d.ts.map +1 -0
  72. package/dist/tools/profile/certifications.js +219 -0
  73. package/dist/tools/profile/certifications.js.map +1 -0
  74. package/dist/tools/profile/education.d.ts +23 -0
  75. package/dist/tools/profile/education.d.ts.map +1 -0
  76. package/dist/tools/profile/education.js +222 -0
  77. package/dist/tools/profile/education.js.map +1 -0
  78. package/dist/tools/profile/employment.d.ts +23 -0
  79. package/dist/tools/profile/employment.d.ts.map +1 -0
  80. package/dist/tools/profile/employment.js +254 -0
  81. package/dist/tools/profile/employment.js.map +1 -0
  82. package/dist/tools/profile/industries.d.ts +30 -0
  83. package/dist/tools/profile/industries.d.ts.map +1 -0
  84. package/dist/tools/profile/industries.js +196 -0
  85. package/dist/tools/profile/industries.js.map +1 -0
  86. package/dist/tools/profile/portfolio.d.ts +22 -0
  87. package/dist/tools/profile/portfolio.d.ts.map +1 -0
  88. package/dist/tools/profile/portfolio.js +341 -0
  89. package/dist/tools/profile/portfolio.js.map +1 -0
  90. package/dist/tools/profile/resume.d.ts +16 -0
  91. package/dist/tools/profile/resume.d.ts.map +1 -0
  92. package/dist/tools/profile/resume.js +107 -0
  93. package/dist/tools/profile/resume.js.map +1 -0
  94. package/dist/tools/profile/shared.d.ts +85 -0
  95. package/dist/tools/profile/shared.d.ts.map +1 -0
  96. package/dist/tools/profile/shared.js +128 -0
  97. package/dist/tools/profile/shared.js.map +1 -0
  98. package/dist/tools/profile/visas.d.ts +15 -0
  99. package/dist/tools/profile/visas.d.ts.map +1 -0
  100. package/dist/tools/profile/visas.js +170 -0
  101. package/dist/tools/profile/visas.js.map +1 -0
  102. package/dist/tools/profile_basic_photo_show.d.ts +14 -0
  103. package/dist/tools/profile_basic_photo_show.d.ts.map +1 -0
  104. package/dist/tools/profile_basic_photo_show.js +59 -0
  105. package/dist/tools/profile_basic_photo_show.js.map +1 -0
  106. package/dist/tools/profile_basic_photo_upload.d.ts +24 -0
  107. package/dist/tools/profile_basic_photo_upload.d.ts.map +1 -0
  108. package/dist/tools/profile_basic_photo_upload.js +90 -0
  109. package/dist/tools/profile_basic_photo_upload.js.map +1 -0
  110. package/dist/tools/profile_basic_show.d.ts +64 -0
  111. package/dist/tools/profile_basic_show.d.ts.map +1 -0
  112. package/dist/tools/profile_basic_show.js +108 -0
  113. package/dist/tools/profile_basic_show.js.map +1 -0
  114. package/dist/tools/profile_basic_update.d.ts +37 -0
  115. package/dist/tools/profile_basic_update.d.ts.map +1 -0
  116. package/dist/tools/profile_basic_update.js +97 -0
  117. package/dist/tools/profile_basic_update.js.map +1 -0
  118. package/dist/tools/profile_external_advanced_wizard_show.d.ts +14 -0
  119. package/dist/tools/profile_external_advanced_wizard_show.d.ts.map +1 -0
  120. package/dist/tools/profile_external_advanced_wizard_show.js +56 -0
  121. package/dist/tools/profile_external_advanced_wizard_show.js.map +1 -0
  122. package/dist/tools/profile_external_custom_requirements_set.d.ts +13 -0
  123. package/dist/tools/profile_external_custom_requirements_set.d.ts.map +1 -0
  124. package/dist/tools/profile_external_custom_requirements_set.js +75 -0
  125. package/dist/tools/profile_external_custom_requirements_set.js.map +1 -0
  126. package/dist/tools/profile_external_custom_requirements_show.d.ts +14 -0
  127. package/dist/tools/profile_external_custom_requirements_show.d.ts.map +1 -0
  128. package/dist/tools/profile_external_custom_requirements_show.js +56 -0
  129. package/dist/tools/profile_external_custom_requirements_show.js.map +1 -0
  130. package/dist/tools/profile_external_readiness.d.ts +12 -0
  131. package/dist/tools/profile_external_readiness.d.ts.map +1 -0
  132. package/dist/tools/profile_external_readiness.js +54 -0
  133. package/dist/tools/profile_external_readiness.js.map +1 -0
  134. package/dist/tools/profile_external_recommendations.d.ts +15 -0
  135. package/dist/tools/profile_external_recommendations.d.ts.map +1 -0
  136. package/dist/tools/profile_external_recommendations.js +57 -0
  137. package/dist/tools/profile_external_recommendations.js.map +1 -0
  138. package/dist/tools/profile_external_show.d.ts +15 -0
  139. package/dist/tools/profile_external_show.d.ts.map +1 -0
  140. package/dist/tools/profile_external_show.js +59 -0
  141. package/dist/tools/profile_external_show.js.map +1 -0
  142. package/dist/tools/profile_external_update.d.ts +14 -0
  143. package/dist/tools/profile_external_update.d.ts.map +1 -0
  144. package/dist/tools/profile_external_update.js +79 -0
  145. package/dist/tools/profile_external_update.js.map +1 -0
  146. package/dist/tools/profile_reviews_approve_item.d.ts +17 -0
  147. package/dist/tools/profile_reviews_approve_item.d.ts.map +1 -0
  148. package/dist/tools/profile_reviews_approve_item.js +77 -0
  149. package/dist/tools/profile_reviews_approve_item.js.map +1 -0
  150. package/dist/tools/profile_reviews_approve_section.d.ts +15 -0
  151. package/dist/tools/profile_reviews_approve_section.d.ts.map +1 -0
  152. package/dist/tools/profile_reviews_approve_section.js +70 -0
  153. package/dist/tools/profile_reviews_approve_section.js.map +1 -0
  154. package/dist/tools/profile_reviews_list.d.ts +16 -0
  155. package/dist/tools/profile_reviews_list.d.ts.map +1 -0
  156. package/dist/tools/profile_reviews_list.js +58 -0
  157. package/dist/tools/profile_reviews_list.js.map +1 -0
  158. package/dist/tools/profile_reviews_submit_for_review.d.ts +14 -0
  159. package/dist/tools/profile_reviews_submit_for_review.d.ts.map +1 -0
  160. package/dist/tools/profile_reviews_submit_for_review.js +56 -0
  161. package/dist/tools/profile_reviews_submit_for_review.js.map +1 -0
  162. package/dist/tools/profile_skills_add.d.ts +4 -0
  163. package/dist/tools/profile_skills_add.d.ts.map +1 -0
  164. package/dist/tools/profile_skills_add.js +52 -0
  165. package/dist/tools/profile_skills_add.js.map +1 -0
  166. package/dist/tools/profile_skills_autocomplete.d.ts +4 -0
  167. package/dist/tools/profile_skills_autocomplete.d.ts.map +1 -0
  168. package/dist/tools/profile_skills_autocomplete.js +78 -0
  169. package/dist/tools/profile_skills_autocomplete.js.map +1 -0
  170. package/dist/tools/profile_skills_list.d.ts +16 -0
  171. package/dist/tools/profile_skills_list.d.ts.map +1 -0
  172. package/dist/tools/profile_skills_list.js +65 -0
  173. package/dist/tools/profile_skills_list.js.map +1 -0
  174. package/dist/tools/profile_skills_readiness.d.ts +4 -0
  175. package/dist/tools/profile_skills_readiness.d.ts.map +1 -0
  176. package/dist/tools/profile_skills_readiness.js +53 -0
  177. package/dist/tools/profile_skills_readiness.js.map +1 -0
  178. package/dist/tools/profile_skills_remove.d.ts +4 -0
  179. package/dist/tools/profile_skills_remove.d.ts.map +1 -0
  180. package/dist/tools/profile_skills_remove.js +53 -0
  181. package/dist/tools/profile_skills_remove.js.map +1 -0
  182. package/dist/tools/profile_skills_show.d.ts +4 -0
  183. package/dist/tools/profile_skills_show.d.ts.map +1 -0
  184. package/dist/tools/profile_skills_show.js +51 -0
  185. package/dist/tools/profile_skills_show.js.map +1 -0
  186. package/dist/tools/profile_skills_update.d.ts +11 -0
  187. package/dist/tools/profile_skills_update.d.ts.map +1 -0
  188. package/dist/tools/profile_skills_update.js +97 -0
  189. package/dist/tools/profile_skills_update.js.map +1 -0
  190. package/dist/tools/timesheet.d.ts +29 -0
  191. package/dist/tools/timesheet.d.ts.map +1 -0
  192. package/dist/tools/timesheet.js +257 -0
  193. package/dist/tools/timesheet.js.map +1 -0
  194. package/package.json +33 -13
  195. package/index.js +0 -7
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Status discriminator for {@link McpToolInvokeEndRecord}. Three values
3
+ * cover the per-call outcome lattice:
4
+ *
5
+ * - `"ok"` — tool callback resolved and returned a success-shaped
6
+ * `ToolSuccessResponse` (no `isError: true`).
7
+ * - `"error"` — tool callback resolved with a `ToolErrorResponse`
8
+ * (typed domain failure, e.g. `(UNAUTHENTICATED): No auth token
9
+ * found`). The MCP wire protocol carries this back to the client
10
+ * verbatim; it is NOT an uncaught exception.
11
+ * - `"throw"` — tool callback threw an exception that bubbled out of
12
+ * the wrapper. The wrapper re-throws after emission so the MCP
13
+ * SDK's default error path runs.
14
+ *
15
+ * Separating `"error"` from `"throw"` lets operators triage typed
16
+ * domain failures (expected, recoverable) from uncaught exceptions
17
+ * (unexpected, often a bug).
18
+ */
19
+ export type McpToolInvokeStatus = "ok" | "error" | "throw";
20
+ /**
21
+ * Common base for every MCP-side diagnostic record. Mirrors the base
22
+ * fields on `configWriter.ts`'s `DebugRecordBase` so a single
23
+ * `jq 'select(.event == ...)'` filter works across both taxonomies.
24
+ *
25
+ * - `ts` — wall-clock ISO-8601 timestamp; useful for cross-process
26
+ * correlation when an MCP session and a CLI invocation interleave.
27
+ * - `event` — discriminator naming the variant.
28
+ */
29
+ interface McpDebugRecordBase {
30
+ ts: string;
31
+ }
32
+ /**
33
+ * `mcp_tool_invoke_start` — emitted BEFORE the tool callback runs.
34
+ * Pairs 1:1 with a downstream `mcp_tool_invoke_end` (`{tool, ts}` join key,
35
+ * plus `duration_ms` on the end record).
36
+ *
37
+ * `args_redacted` is the redacted form of the tool input. The redaction
38
+ * runs through `redactBody` from `@ttctl/core` so the canonical bearer
39
+ * pattern (`user_<24hex>_<20alnum>`), cookie strings, and secret-named
40
+ * fields (`password`, `token`, etc. per `SECRET_BODY_FIELD_NAMES`) are
41
+ * replaced with `***REDACTED***` BEFORE the record is constructed. The
42
+ * resulting object is safe to serialize.
43
+ */
44
+ export interface McpToolInvokeStartRecord extends McpDebugRecordBase {
45
+ event: "mcp_tool_invoke_start";
46
+ tool: string;
47
+ args_redacted: unknown;
48
+ }
49
+ /**
50
+ * `mcp_tool_invoke_end` — emitted AFTER the tool callback completes (or
51
+ * throws). `duration_ms` is `performance.now()`-derived monotonic elapsed
52
+ * milliseconds rounded to integer, so the value stays accurate across
53
+ * wall-clock adjustments during the call.
54
+ *
55
+ * The `status` field discriminates the three outcomes (see
56
+ * {@link McpToolInvokeStatus}).
57
+ */
58
+ export interface McpToolInvokeEndRecord extends McpDebugRecordBase {
59
+ event: "mcp_tool_invoke_end";
60
+ tool: string;
61
+ duration_ms: number;
62
+ status: McpToolInvokeStatus;
63
+ }
64
+ /**
65
+ * `mcp_auth_resolve` — emitted on every auth-resolver invocation (every
66
+ * tool call hits the resolver). Useful for cache-miss diagnostics in
67
+ * long-running MCP sessions: a token rotation via a sibling
68
+ * `ttctl auth signin` shows up as `token_fresh: true` on the FIRST
69
+ * post-rotation tool call.
70
+ *
71
+ * Fields:
72
+ * - `mtime_ms` — mtime of the captured config path at resolve time,
73
+ * or `null` if the stat failed (file removed, permissions changed
74
+ * mid-session). Stat overhead is bounded — POSIX stat is microseconds
75
+ * and only fires when emission is active.
76
+ * - `token_fresh` — `true` when this resolve produced a token AND the
77
+ * mtime differs from the prior resolve's mtime, `false` otherwise.
78
+ * The "first resolve" case (no prior mtime) reports `true` if a
79
+ * token was found, `false` if `auth.token` was undefined.
80
+ * - `outcome` — discriminates the three resolve outcomes: `"ok"` when
81
+ * a token was returned, `"unauthenticated"` when `auth.token` was
82
+ * undefined, `"config_error"` when the resolver rejected with a
83
+ * `ConfigError` (NO_CREDS, PARSE, VALIDATION, PERMISSION, LOCKED).
84
+ *
85
+ * The bearer value itself is NEVER in the record — only the boolean
86
+ * presence signal.
87
+ */
88
+ export interface McpAuthResolveRecord extends McpDebugRecordBase {
89
+ event: "mcp_auth_resolve";
90
+ mtime_ms: number | null;
91
+ token_fresh: boolean;
92
+ outcome: "ok" | "unauthenticated" | "config_error";
93
+ }
94
+ /**
95
+ * `mcp_transport_error` — emitted when a transport-layer error
96
+ * (`Cf403Error`, `Cf403PersistentError`, `SchedulerBearerExpired`,
97
+ * other named transport throws) bubbles out of a tool callback.
98
+ * Separates transport-cause failures from domain-cause failures so
99
+ * Cloudflare regressions show up as a single grep target.
100
+ *
101
+ * Fields:
102
+ * - `tool` — name of the tool whose handler observed the error.
103
+ * - `surface` — `"talent-profile"` / `"mobile-gateway"` / `"scheduler"`
104
+ * / `"unknown"`. Extracted from the error class where possible
105
+ * (`Cf403Error` carries `surface` verbatim); otherwise `"unknown"`.
106
+ * - `error_class` — `err.name` (`"Cf403Error"`,
107
+ * `"Cf403PersistentError"`, …). Stable across messages.
108
+ * - `status` — HTTP status code when the error carries one, else
109
+ * `null`. `Cf403Error`/`Cf403PersistentError` -> 403,
110
+ * `SchedulerBearerExpired` -> 401.
111
+ */
112
+ export interface McpTransportErrorRecord extends McpDebugRecordBase {
113
+ event: "mcp_transport_error";
114
+ tool: string;
115
+ surface: "talent-profile" | "mobile-gateway" | "scheduler" | "unknown";
116
+ error_class: string;
117
+ status: number | null;
118
+ }
119
+ /**
120
+ * Discriminated union of every MCP-side diagnostic record. The type
121
+ * system is the FIRST line of bearer-absence enforcement: no variant
122
+ * here admits a bearer-shaped field. The runtime substring-assertion in
123
+ * `__tests__/diagnostic.test.ts` is the SECOND line — catches any
124
+ * accidental bearer leakage via `args_redacted` (the only slot where
125
+ * client-supplied data flows in).
126
+ */
127
+ export type McpDebugRecord = McpToolInvokeStartRecord | McpToolInvokeEndRecord | McpAuthResolveRecord | McpTransportErrorRecord;
128
+ /**
129
+ * Logger signature: receives a fully-constructed record and emits it
130
+ * somewhere observable (stderr by default; an in-memory array in tests).
131
+ *
132
+ * The logger MUST NOT throw — diagnostic emission is a fire-and-forget
133
+ * side channel and an exception here would unwind the tool call. The
134
+ * default emitter catches and swallows any `process.stderr.write` error
135
+ * (rare on stdio; pipe-broken EPIPE during teardown is the only realistic
136
+ * case). Custom loggers should follow the same posture.
137
+ */
138
+ export type McpDiagnosticLogger = (record: McpDebugRecord) => void;
139
+ /**
140
+ * Replace the active MCP diagnostic logger. Wired in production by
141
+ * `runMcpStdio()` at server startup; called by tests in `beforeEach`
142
+ * to inject a capturing logger.
143
+ *
144
+ * Production callers pass `defaultLogger` (re-exported via the index)
145
+ * or any custom logger conforming to {@link McpDiagnosticLogger}.
146
+ */
147
+ export declare function setMcpDiagnosticLogger(logger: McpDiagnosticLogger): void;
148
+ /**
149
+ * Read the currently-installed logger. Tests use this for round-trip
150
+ * verification ("set, then read, then call"). Production code reads via
151
+ * {@link emitMcpDebug} instead.
152
+ */
153
+ export declare function getMcpDiagnosticLogger(): McpDiagnosticLogger;
154
+ /**
155
+ * Restore the default env-gated stderr logger AND clear the mtime
156
+ * tracker. Tests MUST call this in `afterEach` to avoid state bleeding
157
+ * across cases — both the logger override and the mtime baseline are
158
+ * module-scoped state.
159
+ */
160
+ export declare function resetMcpDiagnosticLogger(): void;
161
+ /**
162
+ * Emit a structured MCP debug record via the current logger. Lazy
163
+ * construction via the `makeRecord` thunk keeps the disabled path
164
+ * zero-allocation when `currentLogger === defaultLogger` and
165
+ * `DEBUG_ENABLED === false`: V8 inlines `defaultLogger` to a no-op and
166
+ * the thunk body is dead code.
167
+ *
168
+ * When a custom logger is installed (test injection), the thunk runs
169
+ * unconditionally — the logger sees every event regardless of env state.
170
+ * This is intentional: tests assert on emission shape without needing
171
+ * to manipulate `process.env`.
172
+ */
173
+ export declare function emitMcpDebug(makeRecord: () => McpDebugRecord): void;
174
+ /**
175
+ * Emit a `mcp_auth_resolve` record summarizing an auth-resolver
176
+ * invocation. Called by the three resolver factories
177
+ * (`createToolAuthResolver`, `createTokenLoader`, `createTokenResolver`)
178
+ * AFTER each per-call `resolveConfig` returns (or throws). The bearer
179
+ * itself is NEVER passed in — only `hasToken: boolean`.
180
+ *
181
+ * `mtime_ms` is captured via a synchronous `statSync` on the captured
182
+ * config path. Sync stat is microseconds and only fires when emission
183
+ * is active (the env-gate / injected-logger fast-path skips the stat
184
+ * entirely on the disabled path). On stat failure (file removed
185
+ * mid-session, permissions changed), `mtime_ms` is `null` and
186
+ * `token_fresh` is `false` (cannot prove freshness without a baseline).
187
+ */
188
+ export declare function emitMcpAuthResolve(configPath: string, outcome: McpAuthResolveRecord["outcome"], hasToken: boolean): void;
189
+ /**
190
+ * Helper: redact tool args for {@link McpToolInvokeStartRecord}. Two-pass
191
+ * defense:
192
+ *
193
+ * 1. `redactBody` from `@ttctl/core` replaces FIELD values whose key
194
+ * matches `SECRET_BODY_FIELD_NAMES` (`password`, `token`, etc.).
195
+ * 2. {@link scrubBearerPatternInStrings} walks the result and replaces
196
+ * any STRING value that matches the canonical bearer pattern
197
+ * (`user_<24hex>_<20alnum>`). This catches the case where an LLM
198
+ * client pastes a bearer-shaped value into a free-text arg like
199
+ * `{ note: "user_abc..." }` that the field-name pass would miss.
200
+ *
201
+ * The MCP tool surface accepts arbitrary client-supplied JSON, so the
202
+ * second pass is the load-bearing defense for bearer-absence in
203
+ * `args_redacted`. The transport-side `redactBody` doesn't need it
204
+ * because GraphQL variables are typed and the bearer never appears in
205
+ * any documented variable slot — MCP args have no such guarantee.
206
+ */
207
+ export declare function redactToolArgs(args: unknown): unknown;
208
+ /**
209
+ * Extract the transport `surface` from an error-shaped value. The
210
+ * `Cf403Error` / `Cf403PersistentError` classes carry `surface` verbatim;
211
+ * `SchedulerBearerExpired` implies `"scheduler"`. Anything else returns
212
+ * `"unknown"` — the operator triages from `error_class` directly.
213
+ *
214
+ * Exported for tests; production code routes through
215
+ * {@link emitMcpTransportError}.
216
+ */
217
+ export declare function extractTransportSurface(err: unknown): McpTransportErrorRecord["surface"];
218
+ /**
219
+ * Extract HTTP status from a transport error. `Cf403Error` /
220
+ * `Cf403PersistentError` are 403 by construction; `SchedulerBearerExpired`
221
+ * is 401. Errors carrying a numeric `status` field return that value.
222
+ * Anything else returns `null`.
223
+ */
224
+ export declare function extractTransportStatus(err: unknown): number | null;
225
+ /**
226
+ * Recognize transport-class errors so the wrapper can emit
227
+ * {@link McpTransportErrorRecord} only for transport-cause failures
228
+ * (Cloudflare 403, scheduler bearer expired, etc.) and skip domain-cause
229
+ * throws (which the MCP error contract surfaces via `ToolErrorResponse`).
230
+ */
231
+ export declare function isTransportError(err: unknown): boolean;
232
+ /**
233
+ * Helper for wrapping a tool callback with the start/end/transport-error
234
+ * emission contract. The wrapped handler:
235
+ *
236
+ * 1. Captures a monotonic start time.
237
+ * 2. Emits `mcp_tool_invoke_start` with `redactToolArgs(input)`.
238
+ * 3. Runs the original handler with all forwarded arguments.
239
+ * 4. On success: emits `mcp_tool_invoke_end` with status `"ok"` /
240
+ * `"error"` derived from the response shape, plus `duration_ms`.
241
+ * 5. On throw: emits `mcp_tool_invoke_end` with status `"throw"`,
242
+ * then `mcp_transport_error` if the error class is transport-typed,
243
+ * then re-throws.
244
+ *
245
+ * The wrapper is a closure over the tool name so the same factory
246
+ * produces a per-tool wrapper that names itself correctly in every
247
+ * emission.
248
+ *
249
+ * The MCP SDK's `ToolCallback<Args>` accepts a two-argument callback
250
+ * `(input, extra)` (where `extra` is `RequestHandlerExtra` carrying
251
+ * the active session / abort signal). Some tool callbacks accept zero
252
+ * arguments (no inputSchema) — the SDK calls them with `(extra)` only.
253
+ * The wrapper forwards `...rest` so both shapes work without per-shape
254
+ * branching at the call site.
255
+ */
256
+ export declare function wrapToolHandler<THandler extends (...args: any[]) => Promise<{
257
+ isError?: boolean;
258
+ }> | {
259
+ isError?: boolean;
260
+ }>(toolName: string, handler: THandler): THandler;
261
+ export {};
262
+ //# sourceMappingURL=diagnostic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic.d.ts","sourceRoot":"","sources":["../src/diagnostic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,362 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ /**
4
+ * MCP-side structured-event diagnostic taxonomy (issue #224). Mirrors the
5
+ * config-write debug taxonomy in `@ttctl/core/configWriter.ts`
6
+ * (`TTCTL_DEBUG_CONFIG=1`) but scoped to the MCP entry point: tool
7
+ * invocations, auth-resolver re-reads, and transport errors observed
8
+ * inside the long-lived MCP process.
9
+ *
10
+ * Two emission paths:
11
+ *
12
+ * 1. **Default env-gated stderr emitter.** Reads `TTCTL_DEBUG_MCP=1`
13
+ * ONCE at module load so the disabled path constant-folds to a single
14
+ * comparison in V8 (NFR: zero-cost-when-disabled). Writes one
15
+ * JSON-encoded record per line to `process.stderr` — the stdio
16
+ * data channel (`process.stdout`, owned by the MCP protocol) is
17
+ * never touched.
18
+ * 2. **Injected logger.** Tests (and any future SSE/HTTP transport
19
+ * wrapper) call {@link setMcpDiagnosticLogger} to replace the
20
+ * default emitter with a fake that captures records into an array.
21
+ * The injection point in production code is
22
+ * {@link runMcpStdio} — wiring the logger ONCE at the entry point
23
+ * so per-tool callsites stay free of conditional logger plumbing.
24
+ *
25
+ * Bearer-absence is a load-bearing invariant: no record variant in the
26
+ * {@link McpDebugRecord} discriminated union carries a bearer-shaped
27
+ * field, and the runtime `redactBody` pass on `args_redacted` covers
28
+ * the one slot that could plausibly admit one (tool args contributed by
29
+ * the LLM client). The test suite asserts substring-absence across every
30
+ * emission path; the type system enforces it at the call-site.
31
+ */
32
+ import { statSync } from "node:fs";
33
+ import { performance } from "node:perf_hooks";
34
+ import { BEARER_PATTERN_SOURCE, REDACTED, redactBody } from "@ttctl/core";
35
+ /**
36
+ * Module-load capture of `TTCTL_DEBUG_MCP=1`. Read ONCE so the disabled
37
+ * path constant-folds to a single `if (DEBUG_ENABLED)` comparison in V8 —
38
+ * the env-unset path pays zero runtime overhead per-event.
39
+ *
40
+ * Tests that exercise both env-set and env-unset paths re-import the
41
+ * module via dynamic `import()` after mutating `process.env`. The
42
+ * injection path via {@link setMcpDiagnosticLogger} sidesteps the env
43
+ * gate entirely (the injected logger is always called) and is the
44
+ * preferred pattern for new tests.
45
+ */
46
+ const DEBUG_ENABLED = process.env["TTCTL_DEBUG_MCP"] === "1";
47
+ /**
48
+ * Default logger: env-gated stderr emitter. When `TTCTL_DEBUG_MCP=1`,
49
+ * writes one JSON-encoded record per line to `process.stderr`. When
50
+ * unset (or any other value), no-op.
51
+ *
52
+ * The env gate is captured at module load (see {@link DEBUG_ENABLED})
53
+ * so a JIT'd V8 inlines this function down to either:
54
+ * - `() => undefined` (env unset; constant-folded dead branch), or
55
+ * - `(record) => process.stderr.write(JSON.stringify(record) + '\n')`
56
+ * (env set).
57
+ *
58
+ * Stderr is chosen so the stdio data channel (stdout, owned by the MCP
59
+ * JSON-RPC protocol) stays uncontaminated.
60
+ */
61
+ const defaultLogger = (record) => {
62
+ if (!DEBUG_ENABLED)
63
+ return;
64
+ try {
65
+ process.stderr.write(JSON.stringify(record) + "\n");
66
+ }
67
+ catch {
68
+ // EPIPE during teardown; nothing meaningful to do. Diagnostic
69
+ // emission must never unwind a tool call.
70
+ }
71
+ };
72
+ /**
73
+ * Module-scoped logger holder. Mirrors the `currentLevel` pattern in
74
+ * `@ttctl/core/lib/diagnostic-log.ts`: one global, set at entry-point
75
+ * wiring time, read on every emit. Module isolation keeps per-tool
76
+ * callsites focused on their domain (no logger parameter threading)
77
+ * while exposing a single test-injection point.
78
+ */
79
+ let currentLogger = defaultLogger;
80
+ /**
81
+ * Replace the active MCP diagnostic logger. Wired in production by
82
+ * `runMcpStdio()` at server startup; called by tests in `beforeEach`
83
+ * to inject a capturing logger.
84
+ *
85
+ * Production callers pass `defaultLogger` (re-exported via the index)
86
+ * or any custom logger conforming to {@link McpDiagnosticLogger}.
87
+ */
88
+ export function setMcpDiagnosticLogger(logger) {
89
+ currentLogger = logger;
90
+ }
91
+ /**
92
+ * Read the currently-installed logger. Tests use this for round-trip
93
+ * verification ("set, then read, then call"). Production code reads via
94
+ * {@link emitMcpDebug} instead.
95
+ */
96
+ export function getMcpDiagnosticLogger() {
97
+ return currentLogger;
98
+ }
99
+ /**
100
+ * Restore the default env-gated stderr logger AND clear the mtime
101
+ * tracker. Tests MUST call this in `afterEach` to avoid state bleeding
102
+ * across cases — both the logger override and the mtime baseline are
103
+ * module-scoped state.
104
+ */
105
+ export function resetMcpDiagnosticLogger() {
106
+ currentLogger = defaultLogger;
107
+ lastSeenMtime.clear();
108
+ }
109
+ /**
110
+ * Emit a structured MCP debug record via the current logger. Lazy
111
+ * construction via the `makeRecord` thunk keeps the disabled path
112
+ * zero-allocation when `currentLogger === defaultLogger` and
113
+ * `DEBUG_ENABLED === false`: V8 inlines `defaultLogger` to a no-op and
114
+ * the thunk body is dead code.
115
+ *
116
+ * When a custom logger is installed (test injection), the thunk runs
117
+ * unconditionally — the logger sees every event regardless of env state.
118
+ * This is intentional: tests assert on emission shape without needing
119
+ * to manipulate `process.env`.
120
+ */
121
+ export function emitMcpDebug(makeRecord) {
122
+ // Fast-path: default logger + env unset → skip the thunk entirely.
123
+ // Any custom logger (test injection) bypasses the gate.
124
+ if (currentLogger === defaultLogger && !DEBUG_ENABLED)
125
+ return;
126
+ currentLogger(makeRecord());
127
+ }
128
+ /**
129
+ * Module-scoped tracker of the last-observed mtime per config path.
130
+ * Lets {@link emitMcpAuthResolve} report `token_fresh: true` on the
131
+ * FIRST tool call after a sibling `ttctl auth signin` rotates the
132
+ * bearer (mtime moves; fresh resolve picks up the new value).
133
+ *
134
+ * Keyed by absolute config path so multi-session callers (theoretical
135
+ * future SSE transport hosting two clients) don't collide. Production
136
+ * use today is single-path: one MCP session = one captured path.
137
+ *
138
+ * Reset by {@link resetMcpDiagnosticLogger} so tests get a clean slate
139
+ * between cases.
140
+ */
141
+ const lastSeenMtime = new Map();
142
+ /**
143
+ * Emit a `mcp_auth_resolve` record summarizing an auth-resolver
144
+ * invocation. Called by the three resolver factories
145
+ * (`createToolAuthResolver`, `createTokenLoader`, `createTokenResolver`)
146
+ * AFTER each per-call `resolveConfig` returns (or throws). The bearer
147
+ * itself is NEVER passed in — only `hasToken: boolean`.
148
+ *
149
+ * `mtime_ms` is captured via a synchronous `statSync` on the captured
150
+ * config path. Sync stat is microseconds and only fires when emission
151
+ * is active (the env-gate / injected-logger fast-path skips the stat
152
+ * entirely on the disabled path). On stat failure (file removed
153
+ * mid-session, permissions changed), `mtime_ms` is `null` and
154
+ * `token_fresh` is `false` (cannot prove freshness without a baseline).
155
+ */
156
+ export function emitMcpAuthResolve(configPath, outcome, hasToken) {
157
+ if (currentLogger === defaultLogger && !DEBUG_ENABLED)
158
+ return;
159
+ let mtime_ms;
160
+ try {
161
+ mtime_ms = statSync(configPath).mtimeMs;
162
+ }
163
+ catch {
164
+ mtime_ms = null;
165
+ }
166
+ const prior = lastSeenMtime.get(configPath);
167
+ // token_fresh is true ONLY when we have a NEW mtime AND a token.
168
+ // - First call (no prior): true if hasToken (the token "appears fresh"
169
+ // from the resolver's POV).
170
+ // - mtime moved forward: true if hasToken.
171
+ // - mtime unchanged: false (same file, no rotation since last call).
172
+ // - mtime null: false (cannot prove freshness).
173
+ const token_fresh = mtime_ms !== null && hasToken && (prior === undefined || mtime_ms !== prior);
174
+ if (mtime_ms !== null)
175
+ lastSeenMtime.set(configPath, mtime_ms);
176
+ currentLogger({
177
+ ts: new Date().toISOString(),
178
+ event: "mcp_auth_resolve",
179
+ mtime_ms,
180
+ token_fresh,
181
+ outcome,
182
+ });
183
+ }
184
+ /**
185
+ * Helper: redact tool args for {@link McpToolInvokeStartRecord}. Two-pass
186
+ * defense:
187
+ *
188
+ * 1. `redactBody` from `@ttctl/core` replaces FIELD values whose key
189
+ * matches `SECRET_BODY_FIELD_NAMES` (`password`, `token`, etc.).
190
+ * 2. {@link scrubBearerPatternInStrings} walks the result and replaces
191
+ * any STRING value that matches the canonical bearer pattern
192
+ * (`user_<24hex>_<20alnum>`). This catches the case where an LLM
193
+ * client pastes a bearer-shaped value into a free-text arg like
194
+ * `{ note: "user_abc..." }` that the field-name pass would miss.
195
+ *
196
+ * The MCP tool surface accepts arbitrary client-supplied JSON, so the
197
+ * second pass is the load-bearing defense for bearer-absence in
198
+ * `args_redacted`. The transport-side `redactBody` doesn't need it
199
+ * because GraphQL variables are typed and the bearer never appears in
200
+ * any documented variable slot — MCP args have no such guarantee.
201
+ */
202
+ export function redactToolArgs(args) {
203
+ return scrubBearerPatternInStrings(redactBody(args));
204
+ }
205
+ /**
206
+ * Walk an arbitrary structure (object / array / scalar) and replace any
207
+ * string value matching the canonical Toptal session bearer pattern
208
+ * with {@link REDACTED}. The pattern source comes from `@ttctl/core` so
209
+ * we never duplicate the bearer regex — the lint-time leakage check
210
+ * uses the same constant.
211
+ *
212
+ * Pure — does not mutate the input. Designed to compose AFTER
213
+ * `redactBody`: any field already replaced with `***REDACTED***` is a
214
+ * non-matching scalar and passes through unchanged.
215
+ */
216
+ function scrubBearerPatternInStrings(input) {
217
+ if (input === null || input === undefined)
218
+ return input;
219
+ if (typeof input === "string") {
220
+ return input.match(new RegExp(BEARER_PATTERN_SOURCE)) !== null ? REDACTED : input;
221
+ }
222
+ if (Array.isArray(input))
223
+ return input.map((item) => scrubBearerPatternInStrings(item));
224
+ if (typeof input !== "object")
225
+ return input;
226
+ const out = {};
227
+ for (const [key, value] of Object.entries(input)) {
228
+ out[key] = scrubBearerPatternInStrings(value);
229
+ }
230
+ return out;
231
+ }
232
+ /**
233
+ * Extract the transport `surface` from an error-shaped value. The
234
+ * `Cf403Error` / `Cf403PersistentError` classes carry `surface` verbatim;
235
+ * `SchedulerBearerExpired` implies `"scheduler"`. Anything else returns
236
+ * `"unknown"` — the operator triages from `error_class` directly.
237
+ *
238
+ * Exported for tests; production code routes through
239
+ * {@link emitMcpTransportError}.
240
+ */
241
+ export function extractTransportSurface(err) {
242
+ if (typeof err !== "object" || err === null)
243
+ return "unknown";
244
+ const name = err.name;
245
+ if (name === "SchedulerBearerExpired")
246
+ return "scheduler";
247
+ const surface = err.surface;
248
+ if (surface === "talent-profile" || surface === "mobile-gateway" || surface === "scheduler")
249
+ return surface;
250
+ return "unknown";
251
+ }
252
+ /**
253
+ * Extract HTTP status from a transport error. `Cf403Error` /
254
+ * `Cf403PersistentError` are 403 by construction; `SchedulerBearerExpired`
255
+ * is 401. Errors carrying a numeric `status` field return that value.
256
+ * Anything else returns `null`.
257
+ */
258
+ export function extractTransportStatus(err) {
259
+ if (typeof err !== "object" || err === null)
260
+ return null;
261
+ const name = err.name;
262
+ if (name === "Cf403Error" || name === "Cf403PersistentError")
263
+ return 403;
264
+ if (name === "SchedulerBearerExpired")
265
+ return 401;
266
+ const status = err.status;
267
+ if (typeof status === "number")
268
+ return status;
269
+ return null;
270
+ }
271
+ /**
272
+ * Recognize transport-class errors so the wrapper can emit
273
+ * {@link McpTransportErrorRecord} only for transport-cause failures
274
+ * (Cloudflare 403, scheduler bearer expired, etc.) and skip domain-cause
275
+ * throws (which the MCP error contract surfaces via `ToolErrorResponse`).
276
+ */
277
+ export function isTransportError(err) {
278
+ if (typeof err !== "object" || err === null)
279
+ return false;
280
+ const name = err.name;
281
+ return name === "Cf403Error" || name === "Cf403PersistentError" || name === "SchedulerBearerExpired";
282
+ }
283
+ /**
284
+ * Helper for wrapping a tool callback with the start/end/transport-error
285
+ * emission contract. The wrapped handler:
286
+ *
287
+ * 1. Captures a monotonic start time.
288
+ * 2. Emits `mcp_tool_invoke_start` with `redactToolArgs(input)`.
289
+ * 3. Runs the original handler with all forwarded arguments.
290
+ * 4. On success: emits `mcp_tool_invoke_end` with status `"ok"` /
291
+ * `"error"` derived from the response shape, plus `duration_ms`.
292
+ * 5. On throw: emits `mcp_tool_invoke_end` with status `"throw"`,
293
+ * then `mcp_transport_error` if the error class is transport-typed,
294
+ * then re-throws.
295
+ *
296
+ * The wrapper is a closure over the tool name so the same factory
297
+ * produces a per-tool wrapper that names itself correctly in every
298
+ * emission.
299
+ *
300
+ * The MCP SDK's `ToolCallback<Args>` accepts a two-argument callback
301
+ * `(input, extra)` (where `extra` is `RequestHandlerExtra` carrying
302
+ * the active session / abort signal). Some tool callbacks accept zero
303
+ * arguments (no inputSchema) — the SDK calls them with `(extra)` only.
304
+ * The wrapper forwards `...rest` so both shapes work without per-shape
305
+ * branching at the call site.
306
+ */
307
+ export function wrapToolHandler(toolName, handler) {
308
+ const wrapped = async (...args) => {
309
+ const input = args[0];
310
+ const start = performance.now();
311
+ emitMcpDebug(() => {
312
+ return {
313
+ ts: new Date().toISOString(),
314
+ event: "mcp_tool_invoke_start",
315
+ tool: toolName,
316
+ args_redacted: redactToolArgs(input),
317
+ };
318
+ });
319
+ try {
320
+ const result = (await handler(...args));
321
+ const duration_ms = Math.round(performance.now() - start);
322
+ const status = result.isError === true ? "error" : "ok";
323
+ emitMcpDebug(() => {
324
+ return {
325
+ ts: new Date().toISOString(),
326
+ event: "mcp_tool_invoke_end",
327
+ tool: toolName,
328
+ duration_ms,
329
+ status,
330
+ };
331
+ });
332
+ return result;
333
+ }
334
+ catch (err) {
335
+ const duration_ms = Math.round(performance.now() - start);
336
+ emitMcpDebug(() => {
337
+ return {
338
+ ts: new Date().toISOString(),
339
+ event: "mcp_tool_invoke_end",
340
+ tool: toolName,
341
+ duration_ms,
342
+ status: "throw",
343
+ };
344
+ });
345
+ if (isTransportError(err)) {
346
+ emitMcpDebug(() => {
347
+ return {
348
+ ts: new Date().toISOString(),
349
+ event: "mcp_transport_error",
350
+ tool: toolName,
351
+ surface: extractTransportSurface(err),
352
+ error_class: err.name ?? "Error",
353
+ status: extractTransportStatus(err),
354
+ };
355
+ });
356
+ }
357
+ throw err;
358
+ }
359
+ };
360
+ return wrapped;
361
+ }
362
+ //# sourceMappingURL=diagnostic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic.js","sourceRoot":"","sources":["../src/diagnostic.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1E;;;;;;;;;;GAUG;AACH,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,GAAG,CAAC;AAwJ7D;;;;;;;;;;;;;GAaG;AACH,MAAM,aAAa,GAAwB,CAAC,MAAsB,EAAQ,EAAE;IAC1E,IAAI,CAAC,aAAa;QAAE,OAAO;IAC3B,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,8DAA8D;QAC9D,0CAA0C;IAC5C,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,IAAI,aAAa,GAAwB,aAAa,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAA2B;IAChE,aAAa,GAAG,MAAM,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB;IACtC,aAAa,GAAG,aAAa,CAAC;IAC9B,aAAa,CAAC,KAAK,EAAE,CAAC;AACxB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAC,UAAgC;IAC3D,mEAAmE;IACnE,wDAAwD;IACxD,IAAI,aAAa,KAAK,aAAa,IAAI,CAAC,aAAa;QAAE,OAAO;IAC9D,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,aAAa,GAAwB,IAAI,GAAG,EAAE,CAAC;AAErD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,kBAAkB,CAChC,UAAkB,EAClB,OAAwC,EACxC,QAAiB;IAEjB,IAAI,aAAa,KAAK,aAAa,IAAI,CAAC,aAAa;QAAE,OAAO;IAC9D,IAAI,QAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IACD,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC5C,iEAAiE;IACjE,uEAAuE;IACvE,8BAA8B;IAC9B,2CAA2C;IAC3C,qEAAqE;IACrE,gDAAgD;IAChD,MAAM,WAAW,GAAG,QAAQ,KAAK,IAAI,IAAI,QAAQ,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,QAAQ,KAAK,KAAK,CAAC,CAAC;IACjG,IAAI,QAAQ,KAAK,IAAI;QAAE,aAAa,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC/D,aAAa,CAAC;QACZ,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,KAAK,EAAE,kBAAkB;QACzB,QAAQ;QACR,WAAW;QACX,OAAO;KACR,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,cAAc,CAAC,IAAa;IAC1C,OAAO,2BAA2B,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,2BAA2B,CAAC,KAAc;IACjD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,qBAAqB,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;IACpF,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAa,EAAE,EAAE,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC;IACjG,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;QAC5E,GAAG,CAAC,GAAG,CAAC,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAY;IAClD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAC9D,MAAM,IAAI,GAAI,GAA0B,CAAC,IAAI,CAAC;IAC9C,IAAI,IAAI,KAAK,wBAAwB;QAAE,OAAO,WAAW,CAAC;IAC1D,MAAM,OAAO,GAAI,GAA6B,CAAC,OAAO,CAAC;IACvD,IAAI,OAAO,KAAK,gBAAgB,IAAI,OAAO,KAAK,gBAAgB,IAAI,OAAO,KAAK,WAAW;QAAE,OAAO,OAAO,CAAC;IAC5G,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAY;IACjD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACzD,MAAM,IAAI,GAAI,GAA0B,CAAC,IAAI,CAAC;IAC9C,IAAI,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,sBAAsB;QAAE,OAAO,GAAG,CAAC;IACzE,IAAI,IAAI,KAAK,wBAAwB;QAAE,OAAO,GAAG,CAAC;IAClD,MAAM,MAAM,GAAI,GAA4B,CAAC,MAAM,CAAC;IACpD,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC9C,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC1D,MAAM,IAAI,GAAI,GAA0B,CAAC,IAAI,CAAC;IAC9C,OAAO,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,sBAAsB,IAAI,IAAI,KAAK,wBAAwB,CAAC;AACvG,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,eAAe,CAG7B,QAAgB,EAAE,OAAiB;IACnC,MAAM,OAAO,GAAG,KAAK,EAAE,GAAG,IAA0B,EAA0C,EAAE;QAC9F,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAY,CAAC;QACjC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,YAAY,CAAC,GAA6B,EAAE;YAC1C,OAAO;gBACL,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBAC5B,KAAK,EAAE,uBAAuB;gBAC9B,IAAI,EAAE,QAAQ;gBACd,aAAa,EAAE,cAAc,CAAC,KAAK,CAAC;aACrC,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,IAAI,CAAC,CAAkC,CAAC;YACzE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC;YAC1D,MAAM,MAAM,GAAwB,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;YAC7E,YAAY,CAAC,GAA2B,EAAE;gBACxC,OAAO;oBACL,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBAC5B,KAAK,EAAE,qBAAqB;oBAC5B,IAAI,EAAE,QAAQ;oBACd,WAAW;oBACX,MAAM;iBACP,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC;YAC1D,YAAY,CAAC,GAA2B,EAAE;gBACxC,OAAO;oBACL,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBAC5B,KAAK,EAAE,qBAAqB;oBAC5B,IAAI,EAAE,QAAQ;oBACd,WAAW;oBACX,MAAM,EAAE,OAAO;iBAChB,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,IAAI,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,YAAY,CAAC,GAA4B,EAAE;oBACzC,OAAO;wBACL,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;wBAC5B,KAAK,EAAE,qBAAqB;wBAC5B,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,uBAAuB,CAAC,GAAG,CAAC;wBACrC,WAAW,EAAG,GAAyB,CAAC,IAAI,IAAI,OAAO;wBACvD,MAAM,EAAE,sBAAsB,CAAC,GAAG,CAAC;qBACpC,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;IACF,OAAO,OAA8B,CAAC;AACxC,CAAC"}