@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,505 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { jobs } from "@ttctl/core";
4
+ import { z } from "zod";
5
+ import { ttctlErrorToToolResponseOrNull } from "../errors.js";
6
+ import { buildMcpDryRunPreview, dryRunResponse } from "./_shared.js";
7
+ const DRY_RUN_FIELD = z
8
+ .boolean()
9
+ .optional()
10
+ .describe("Preview the request without executing. Returns `{ ok: true, dryRun: true, preview }` with operationName + variables + redacted bearer header. Default: false.");
11
+ /**
12
+ * Build the variables payload `core.jobs` (`buildListVariables` in
13
+ * `core/services/jobs/index.ts`) sends to `JobsList` so a dry-run
14
+ * preview from the MCP layer matches the apply path's wire shape.
15
+ * Mirrors the apply-path "empty/undefined → null" coercion so listed
16
+ * filters render the same way as the actual wire call.
17
+ */
18
+ function buildJobsListVariables(opts, extras) {
19
+ const variables = {
20
+ skills: opts.skills && opts.skills.length > 0 ? opts.skills : null,
21
+ keywords: opts.keywords && opts.keywords.length > 0 ? opts.keywords : null,
22
+ excludeSkills: opts.excludeSkills && opts.excludeSkills.length > 0 ? opts.excludeSkills : null,
23
+ excludeKeywords: opts.excludeKeywords && opts.excludeKeywords.length > 0 ? opts.excludeKeywords : null,
24
+ commitments: opts.commitments && opts.commitments.length > 0 ? opts.commitments : null,
25
+ workTypes: opts.workTypes && opts.workTypes.length > 0 ? opts.workTypes : null,
26
+ estimatedLengths: opts.estimatedLengths && opts.estimatedLengths.length > 0 ? opts.estimatedLengths : null,
27
+ sortTarget: opts.sortTarget ?? null,
28
+ saved: extras.saved !== undefined ? { eq: extras.saved } : null,
29
+ notInterested: extras.notInterested !== undefined ? { eq: extras.notInterested } : null,
30
+ };
31
+ return variables;
32
+ }
33
+ /**
34
+ * Register the `ttctl_jobs_*` MCP tools per #148. Tool names use the
35
+ * `ttctl_` prefix and the canonical CLI path joined with `_`. Per the
36
+ * AC, MCP tools use the canonical `jobs_*` prefix only — no
37
+ * `opportunities_*` aliasing (MCP tool names must be deterministic for
38
+ * LLM clients).
39
+ *
40
+ * Tool surface (13 tools):
41
+ * - `ttctl_jobs_list`
42
+ * - `ttctl_jobs_show`
43
+ * - `ttctl_jobs_save`
44
+ * - `ttctl_jobs_unsave`
45
+ * - `ttctl_jobs_saved`
46
+ * - `ttctl_jobs_viewed`
47
+ * - `ttctl_jobs_mark_viewed`
48
+ * - `ttctl_jobs_not_interested`
49
+ * - `ttctl_jobs_not_interested_list`
50
+ * - `ttctl_jobs_clear_interest`
51
+ * - `ttctl_jobs_search_list`
52
+ * - `ttctl_jobs_search_save`
53
+ * - `ttctl_jobs_search_remove`
54
+ *
55
+ * **Wire-shape notes** (R1 / R2): `jobs_viewed` is scoped to the first
56
+ * page (≤20 jobs, client-side filter); `jobs_search_*` operates on a
57
+ * single subscription per user. The tool descriptions surface these.
58
+ *
59
+ * Dry-run path (issue #165): every tool accepts `dryRun?: boolean`. Read
60
+ * tools build the preview at the MCP layer; the 7 mutations (save,
61
+ * unsave, mark_viewed, not_interested, clear_interest, search_save,
62
+ * search_remove) passthrough-forward `{ dryRun: true }` to the core
63
+ * (which already supports dryRun per #162) and reformat the
64
+ * `{ kind: "preview", preview }` outcome as the uniform envelope.
65
+ */
66
+ export function registerJobsTools(server, ctx) {
67
+ // -------- list ---------------------------------------------------------
68
+ server.registerTool("ttctl_jobs_list", {
69
+ title: "Browse current job opportunities",
70
+ description: [
71
+ "Browse the user's current job opportunities on Toptal Talent.",
72
+ "Returns the first page of eligible jobs (≤20).",
73
+ "",
74
+ "Optional filters:",
75
+ " - `skills` / `keywords`: AND-across filter on required skills / free text",
76
+ " - `excludeSkills` / `excludeKeywords`: exclusion filters",
77
+ " - `commitments`: e.g. FULL_TIME, PART_TIME",
78
+ " - `workTypes`: e.g. REMOTE, ONSITE",
79
+ " - `estimatedLengths`: e.g. SHORT_TERM, LONG_TERM",
80
+ " - `sortTarget`: e.g. visible_at, posted_at",
81
+ "",
82
+ "Example user prompts:",
83
+ ' - "Show me current Toptal job opportunities."',
84
+ ' - "List remote part-time Toptal jobs with React skills."',
85
+ ].join("\n"),
86
+ inputSchema: {
87
+ skills: z.array(z.string()).optional().describe("Required skill names (AND across)"),
88
+ keywords: z.array(z.string()).optional().describe("Free-text keywords (AND across)"),
89
+ excludeSkills: z.array(z.string()).optional().describe("Skills to exclude"),
90
+ excludeKeywords: z.array(z.string()).optional().describe("Keywords to exclude"),
91
+ commitments: z.array(z.string()).optional().describe("JobCommitmentFilterEnum values"),
92
+ workTypes: z.array(z.string()).optional().describe("JobWorkTypeSlug values"),
93
+ estimatedLengths: z.array(z.string()).optional().describe("EstimatedLengthFilterEnum values"),
94
+ sortTarget: z.string().optional().describe("Sort target (e.g. visible_at, posted_at)"),
95
+ dryRun: DRY_RUN_FIELD,
96
+ },
97
+ }, async (args) => {
98
+ const auth = await ctx.resolveToolAuth();
99
+ if (!auth.ok)
100
+ return auth.response;
101
+ const opts = {};
102
+ if (args.skills !== undefined)
103
+ opts.skills = args.skills;
104
+ if (args.keywords !== undefined)
105
+ opts.keywords = args.keywords;
106
+ if (args.excludeSkills !== undefined)
107
+ opts.excludeSkills = args.excludeSkills;
108
+ if (args.excludeKeywords !== undefined)
109
+ opts.excludeKeywords = args.excludeKeywords;
110
+ if (args.commitments !== undefined)
111
+ opts.commitments = args.commitments;
112
+ if (args.workTypes !== undefined)
113
+ opts.workTypes = args.workTypes;
114
+ if (args.estimatedLengths !== undefined)
115
+ opts.estimatedLengths = args.estimatedLengths;
116
+ if (args.sortTarget !== undefined)
117
+ opts.sortTarget = args.sortTarget;
118
+ if (args.dryRun === true) {
119
+ return dryRunResponse(buildMcpDryRunPreview("JobsList", "mobile-gateway", buildJobsListVariables(opts, {}), auth.token));
120
+ }
121
+ try {
122
+ // MCP unwraps the JobListPage to items only (issue #138 wires
123
+ // pagination on the CLI surface; MCP pagination is a separate
124
+ // follow-up). The wire still returns totalCount + page/perPage
125
+ // — those are discarded here to preserve the MCP output
126
+ // contract (`JobListItem[]`).
127
+ const page = await jobs.list(auth.token, opts);
128
+ return successResponse(page.items);
129
+ }
130
+ catch (err) {
131
+ return mapJobsError(err);
132
+ }
133
+ });
134
+ // -------- show ---------------------------------------------------------
135
+ server.registerTool("ttctl_jobs_show", {
136
+ title: "Show one job by id",
137
+ description: [
138
+ "Fetch a single job's detail view by id.",
139
+ "Returns title, description, skills, client metadata, time-zone, rates, and interest-state flags.",
140
+ "",
141
+ "Example user prompts:",
142
+ ' - "Show me Toptal job job_abc123."',
143
+ ' - "What\'s the description for that job I just listed?"',
144
+ ].join("\n"),
145
+ inputSchema: {
146
+ id: z.string().describe("Job id (from `ttctl_jobs_list`)"),
147
+ dryRun: DRY_RUN_FIELD,
148
+ },
149
+ }, async (args) => {
150
+ const auth = await ctx.resolveToolAuth();
151
+ if (!auth.ok)
152
+ return auth.response;
153
+ if (args.dryRun === true) {
154
+ return dryRunResponse(buildMcpDryRunPreview("JobShow", "mobile-gateway", { id: args.id }, auth.token));
155
+ }
156
+ try {
157
+ const item = await jobs.show(auth.token, args.id);
158
+ return successResponse(item);
159
+ }
160
+ catch (err) {
161
+ return mapJobsError(err);
162
+ }
163
+ });
164
+ // -------- save ---------------------------------------------------------
165
+ server.registerTool("ttctl_jobs_save", {
166
+ title: "Save a job (bookmark)",
167
+ description: [
168
+ "Mark a Toptal job as saved (bookmark). The job appears in `ttctl_jobs_saved` afterwards.",
169
+ "",
170
+ "If the job was previously marked not-interested, this mutation clears that flag (the wire's interest-status model is one-of-three: saved / not-interested / cleared).",
171
+ ].join("\n"),
172
+ inputSchema: { id: z.string().describe("Job id"), dryRun: DRY_RUN_FIELD },
173
+ }, async (args) => {
174
+ const auth = await ctx.resolveToolAuth();
175
+ if (!auth.ok)
176
+ return auth.response;
177
+ try {
178
+ const outcome = await jobs.save(auth.token, args.id, { dryRun: args.dryRun ?? false });
179
+ if (outcome.kind === "preview")
180
+ return dryRunResponse(outcome.preview);
181
+ return successResponse(outcome.result);
182
+ }
183
+ catch (err) {
184
+ return mapJobsError(err);
185
+ }
186
+ });
187
+ // -------- unsave -------------------------------------------------------
188
+ server.registerTool("ttctl_jobs_unsave", {
189
+ title: "Remove a job from saved",
190
+ description: [
191
+ "Clear interest flags on a Toptal job — the wire's only 'remove saved' path.",
192
+ "Note that this ALSO clears `not-interested` (single wire mutation covers both signals).",
193
+ ].join("\n"),
194
+ inputSchema: { id: z.string().describe("Job id"), dryRun: DRY_RUN_FIELD },
195
+ }, async (args) => {
196
+ const auth = await ctx.resolveToolAuth();
197
+ if (!auth.ok)
198
+ return auth.response;
199
+ try {
200
+ const outcome = await jobs.unsave(auth.token, args.id, { dryRun: args.dryRun ?? false });
201
+ if (outcome.kind === "preview")
202
+ return dryRunResponse(outcome.preview);
203
+ return successResponse(outcome.result);
204
+ }
205
+ catch (err) {
206
+ return mapJobsError(err);
207
+ }
208
+ });
209
+ // -------- saved --------------------------------------------------------
210
+ server.registerTool("ttctl_jobs_saved", {
211
+ title: "List saved jobs",
212
+ description: "List the user's saved (bookmarked) Toptal jobs.",
213
+ inputSchema: { dryRun: DRY_RUN_FIELD },
214
+ }, async (args) => {
215
+ const auth = await ctx.resolveToolAuth();
216
+ if (!auth.ok)
217
+ return auth.response;
218
+ if (args.dryRun === true) {
219
+ return dryRunResponse(buildMcpDryRunPreview("JobsList", "mobile-gateway", buildJobsListVariables({}, { saved: true }), auth.token));
220
+ }
221
+ try {
222
+ // MCP unwraps the JobListPage to items only (issue #138; see
223
+ // jobs_list for rationale).
224
+ const page = await jobs.saved(auth.token);
225
+ return successResponse(page.items);
226
+ }
227
+ catch (err) {
228
+ return mapJobsError(err);
229
+ }
230
+ });
231
+ // -------- viewed -------------------------------------------------------
232
+ server.registerTool("ttctl_jobs_viewed", {
233
+ title: "List viewed jobs (best-effort, first page only)",
234
+ description: [
235
+ "List Toptal jobs the user has marked as viewed.",
236
+ "",
237
+ "**Limitation (R1)**: the wire has no `viewed` filter on eligibleJobs.",
238
+ "This tool fetches the first page of eligible jobs (≤20) and filters",
239
+ "client-side on the `viewed` boolean. Jobs viewed but on subsequent",
240
+ "pages will not appear.",
241
+ "",
242
+ "Dry-run note: the apply path issues `JobsList` (the same query used by `ttctl_jobs_list`) and filters client-side on `viewed` — the preview reflects the wire call accordingly.",
243
+ ].join("\n"),
244
+ inputSchema: { dryRun: DRY_RUN_FIELD },
245
+ }, async (args) => {
246
+ const auth = await ctx.resolveToolAuth();
247
+ if (!auth.ok)
248
+ return auth.response;
249
+ if (args.dryRun === true) {
250
+ return dryRunResponse(buildMcpDryRunPreview("JobsList", "mobile-gateway", buildJobsListVariables({}, {}), auth.token));
251
+ }
252
+ try {
253
+ // MCP unwraps the JobListPage to items only (issue #138; see
254
+ // jobs_list for rationale). totalCount here reflects the
255
+ // underlying eligibleJobs fetch (pre-`viewed` filter), not the
256
+ // returned items.length.
257
+ const page = await jobs.viewedList(auth.token);
258
+ return successResponse(page.items);
259
+ }
260
+ catch (err) {
261
+ return mapJobsError(err);
262
+ }
263
+ });
264
+ // -------- mark_viewed --------------------------------------------------
265
+ server.registerTool("ttctl_jobs_mark_viewed", {
266
+ title: "Explicitly mark a job as viewed",
267
+ description: [
268
+ "Mark a Toptal job as viewed.",
269
+ "The web UI normally auto-marks on detail-page open — this tool exposes the mutation for completeness.",
270
+ ].join("\n"),
271
+ inputSchema: { id: z.string().describe("Job id"), dryRun: DRY_RUN_FIELD },
272
+ }, async (args) => {
273
+ const auth = await ctx.resolveToolAuth();
274
+ if (!auth.ok)
275
+ return auth.response;
276
+ try {
277
+ const outcome = await jobs.markViewed(auth.token, args.id, { dryRun: args.dryRun ?? false });
278
+ if (outcome.kind === "preview")
279
+ return dryRunResponse(outcome.preview);
280
+ return successResponse(outcome.result);
281
+ }
282
+ catch (err) {
283
+ return mapJobsError(err);
284
+ }
285
+ });
286
+ // -------- not_interested -----------------------------------------------
287
+ server.registerTool("ttctl_jobs_not_interested", {
288
+ title: "Mark a job as not-interested",
289
+ description: [
290
+ "Mark a Toptal job as not-interested with a reason.",
291
+ "`reason` is required (server rejects empty strings).",
292
+ "",
293
+ "If the job was previously saved, this mutation clears the saved flag.",
294
+ ].join("\n"),
295
+ inputSchema: {
296
+ id: z.string().describe("Job id"),
297
+ reason: z.string().min(1).describe("Reason for dismissing (free-text)"),
298
+ dryRun: DRY_RUN_FIELD,
299
+ },
300
+ }, async (args) => {
301
+ const auth = await ctx.resolveToolAuth();
302
+ if (!auth.ok)
303
+ return auth.response;
304
+ try {
305
+ const outcome = await jobs.notInterested(auth.token, args.id, { reason: args.reason }, { dryRun: args.dryRun ?? false });
306
+ if (outcome.kind === "preview")
307
+ return dryRunResponse(outcome.preview);
308
+ return successResponse(outcome.result);
309
+ }
310
+ catch (err) {
311
+ return mapJobsError(err);
312
+ }
313
+ });
314
+ // -------- not_interested_list ------------------------------------------
315
+ server.registerTool("ttctl_jobs_not_interested_list", {
316
+ title: "List jobs marked as not-interested",
317
+ description: "List Toptal jobs the user marked as not-interested.",
318
+ inputSchema: { dryRun: DRY_RUN_FIELD },
319
+ }, async (args) => {
320
+ const auth = await ctx.resolveToolAuth();
321
+ if (!auth.ok)
322
+ return auth.response;
323
+ if (args.dryRun === true) {
324
+ return dryRunResponse(buildMcpDryRunPreview("JobsList", "mobile-gateway", buildJobsListVariables({}, { notInterested: true }), auth.token));
325
+ }
326
+ try {
327
+ // MCP unwraps the JobListPage to items only (issue #138; see
328
+ // jobs_list for rationale).
329
+ const page = await jobs.notInterestedList(auth.token);
330
+ return successResponse(page.items);
331
+ }
332
+ catch (err) {
333
+ return mapJobsError(err);
334
+ }
335
+ });
336
+ // -------- clear_interest -----------------------------------------------
337
+ server.registerTool("ttctl_jobs_clear_interest", {
338
+ title: "Clear interest flags on a job",
339
+ description: [
340
+ "Clear interest flags (both `saved` and `not-interested`) on a job.",
341
+ "Use this to undo a previous `not-interested` mark, or to remove a job from saved.",
342
+ ].join("\n"),
343
+ inputSchema: { id: z.string().describe("Job id"), dryRun: DRY_RUN_FIELD },
344
+ }, async (args) => {
345
+ const auth = await ctx.resolveToolAuth();
346
+ if (!auth.ok)
347
+ return auth.response;
348
+ try {
349
+ const outcome = await jobs.clearInterest(auth.token, args.id, { dryRun: args.dryRun ?? false });
350
+ if (outcome.kind === "preview")
351
+ return dryRunResponse(outcome.preview);
352
+ return successResponse(outcome.result);
353
+ }
354
+ catch (err) {
355
+ return mapJobsError(err);
356
+ }
357
+ });
358
+ // -------- search_list --------------------------------------------------
359
+ server.registerTool("ttctl_jobs_search_list", {
360
+ title: "Show the active job-search subscription",
361
+ description: [
362
+ "Show the user's current job-search subscription state.",
363
+ "",
364
+ "**Cardinality note (R2)**: the platform supports a SINGLE subscription per user — there is no list of named subscriptions.",
365
+ "Returns `{ active: false, filters: null }` when no subscription is active, or the active subscription filters when one is.",
366
+ ].join("\n"),
367
+ inputSchema: { dryRun: DRY_RUN_FIELD },
368
+ }, async (args) => {
369
+ const auth = await ctx.resolveToolAuth();
370
+ if (!auth.ok)
371
+ return auth.response;
372
+ if (args.dryRun === true) {
373
+ return dryRunResponse(buildMcpDryRunPreview("JobSearchSubscriptionShow", "mobile-gateway", {}, auth.token));
374
+ }
375
+ try {
376
+ const state = await jobs.searchSubscriptionShow(auth.token);
377
+ return successResponse(state);
378
+ }
379
+ catch (err) {
380
+ return mapJobsError(err);
381
+ }
382
+ });
383
+ // -------- search_save --------------------------------------------------
384
+ server.registerTool("ttctl_jobs_search_save", {
385
+ title: "Start (or replace) the job-search subscription",
386
+ description: [
387
+ "Start a new job-search subscription with the supplied filters.",
388
+ "If a subscription is already active, it is replaced.",
389
+ "",
390
+ "Returns the post-mutation subscription state.",
391
+ ].join("\n"),
392
+ inputSchema: {
393
+ skills: z.array(z.string()).optional(),
394
+ keywords: z.array(z.string()).optional(),
395
+ excludeSkills: z.array(z.string()).optional(),
396
+ excludeKeywords: z.array(z.string()).optional(),
397
+ commitments: z.array(z.string()).optional(),
398
+ workTypes: z.array(z.string()).optional(),
399
+ estimatedLengths: z.array(z.string()).optional(),
400
+ excludeUnspecifiedBudget: z.boolean().optional(),
401
+ dryRun: DRY_RUN_FIELD,
402
+ },
403
+ }, async (args) => {
404
+ const auth = await ctx.resolveToolAuth();
405
+ if (!auth.ok)
406
+ return auth.response;
407
+ try {
408
+ const filters = {};
409
+ if (args.skills !== undefined)
410
+ filters.skills = args.skills;
411
+ if (args.keywords !== undefined)
412
+ filters.keywords = args.keywords;
413
+ if (args.excludeSkills !== undefined)
414
+ filters.excludeSkills = args.excludeSkills;
415
+ if (args.excludeKeywords !== undefined)
416
+ filters.excludeKeywords = args.excludeKeywords;
417
+ if (args.commitments !== undefined)
418
+ filters.commitments = args.commitments;
419
+ if (args.workTypes !== undefined)
420
+ filters.workTypes = args.workTypes;
421
+ if (args.estimatedLengths !== undefined)
422
+ filters.estimatedLengths = args.estimatedLengths;
423
+ if (args.excludeUnspecifiedBudget !== undefined) {
424
+ filters.excludeUnspecifiedBudget = args.excludeUnspecifiedBudget;
425
+ }
426
+ const outcome = await jobs.searchSubscriptionSave(auth.token, filters, { dryRun: args.dryRun ?? false });
427
+ if (outcome.kind === "preview")
428
+ return dryRunResponse(outcome.preview);
429
+ return successResponse(outcome.result);
430
+ }
431
+ catch (err) {
432
+ return mapJobsError(err);
433
+ }
434
+ });
435
+ // -------- search_remove ------------------------------------------------
436
+ server.registerTool("ttctl_jobs_search_remove", {
437
+ title: "Terminate the active job-search subscription",
438
+ description: [
439
+ "Terminate the user's active job-search subscription.",
440
+ "Idempotent — terminating a non-active subscription returns success.",
441
+ ].join("\n"),
442
+ inputSchema: { dryRun: DRY_RUN_FIELD },
443
+ }, async (args) => {
444
+ const auth = await ctx.resolveToolAuth();
445
+ if (!auth.ok)
446
+ return auth.response;
447
+ try {
448
+ const outcome = await jobs.searchSubscriptionRemove(auth.token, { dryRun: args.dryRun ?? false });
449
+ if (outcome.kind === "preview")
450
+ return dryRunResponse(outcome.preview);
451
+ return successResponse(outcome.result);
452
+ }
453
+ catch (err) {
454
+ return mapJobsError(err);
455
+ }
456
+ });
457
+ }
458
+ function successResponse(data) {
459
+ return {
460
+ content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
461
+ };
462
+ }
463
+ function mapJobsError(err) {
464
+ const typed = ttctlErrorToToolResponseOrNull(err);
465
+ if (typed !== null)
466
+ return typed;
467
+ if (err instanceof jobs.JobsError) {
468
+ return {
469
+ isError: true,
470
+ content: [
471
+ {
472
+ type: "text",
473
+ text: [
474
+ `Error: ${err.message}`,
475
+ "",
476
+ err.code === "NOT_FOUND"
477
+ ? "Recovery: Verify the job id (use ttctl_jobs_list to discover it)."
478
+ : err.code === "MUTATION_ERROR"
479
+ ? "Recovery: Check the mutation input — the server reported a per-field validation failure."
480
+ : "Recovery: Adjust the tool input or retry; see the code below.",
481
+ "",
482
+ `(Code: ${err.code})`,
483
+ ].join("\n"),
484
+ },
485
+ ],
486
+ };
487
+ }
488
+ const message = err instanceof Error ? err.message : String(err);
489
+ return {
490
+ isError: true,
491
+ content: [
492
+ {
493
+ type: "text",
494
+ text: [
495
+ `Error: jobs request failed: ${message}`,
496
+ "",
497
+ "Recovery: Retry; if the failure persists, file an issue.",
498
+ "",
499
+ "(Code: UNKNOWN)",
500
+ ].join("\n"),
501
+ },
502
+ ],
503
+ };
504
+ }
505
+ //# sourceMappingURL=jobs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../src/tools/jobs.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAE9D,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAgC,MAAM,cAAc,CAAC;AAEnG,MAAM,aAAa,GAAG,CAAC;KACpB,OAAO,EAAE;KACT,QAAQ,EAAE;KACV,QAAQ,CACP,+JAA+J,CAChK,CAAC;AAEJ;;;;;;GAMG;AACH,SAAS,sBAAsB,CAC7B,IAAsB,EACtB,MAAoD;IAEpD,MAAM,SAAS,GAA4B;QACzC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;QAClE,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;QAC1E,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI;QAC9F,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI;QACtG,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;QACtF,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;QAC9E,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI;QAC1G,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI;QACnC,KAAK,EAAE,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI;QAC/D,aAAa,EAAE,MAAM,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI;KACxF,CAAC;IACF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,GAA4B;IAC/E,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,KAAK,EAAE,kCAAkC;QACzC,WAAW,EAAE;YACX,+DAA+D;YAC/D,gDAAgD;YAChD,EAAE;YACF,mBAAmB;YACnB,6EAA6E;YAC7E,4DAA4D;YAC5D,8CAA8C;YAC9C,sCAAsC;YACtC,oDAAoD;YACpD,8CAA8C;YAC9C,EAAE;YACF,uBAAuB;YACvB,iDAAiD;YACjD,4DAA4D;SAC7D,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YACpF,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;YACpF,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YAC3E,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;YAC/E,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;YACtF,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YAC5E,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;YAC7F,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;YACtF,MAAM,EAAE,aAAa;SACtB;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACnC,MAAM,IAAI,GAAqB,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QACzD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;YAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/D,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS;YAAE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QAC9E,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS;YAAE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;QACpF,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;YAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACxE,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;YAAE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAClE,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS;YAAE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC;QACvF,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS;YAAE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACrE,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,cAAc,CACnB,qBAAqB,CAAC,UAAU,EAAE,gBAAgB,EAAE,sBAAsB,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAClG,CAAC;QACJ,CAAC;QACD,IAAI,CAAC;YACH,8DAA8D;YAC9D,8DAA8D;YAC9D,+DAA+D;YAC/D,wDAAwD;YACxD,8BAA8B;YAC9B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC/C,OAAO,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EAAE;YACX,yCAAyC;YACzC,kGAAkG;YAClG,EAAE;YACF,uBAAuB;YACvB,sCAAsC;YACtC,2DAA2D;SAC5D,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;YAC1D,MAAM,EAAE,aAAa;SACtB;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,cAAc,CAAC,qBAAqB,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACzG,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YAClD,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EAAE;YACX,0FAA0F;YAC1F,EAAE;YACF,uKAAuK;SACxK,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE;KAC1E,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC;YACvF,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACvE,OAAO,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE;YACX,6EAA6E;YAC7E,yFAAyF;SAC1F,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE;KAC1E,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC;YACzF,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACvE,OAAO,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,iDAAiD;QAC9D,WAAW,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE;KACvC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,cAAc,CACnB,qBAAqB,CAAC,UAAU,EAAE,gBAAgB,EAAE,sBAAsB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAC7G,CAAC;QACJ,CAAC;QACD,IAAI,CAAC;YACH,6DAA6D;YAC7D,4BAA4B;YAC5B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1C,OAAO,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,iDAAiD;QACxD,WAAW,EAAE;YACX,iDAAiD;YACjD,EAAE;YACF,uEAAuE;YACvE,qEAAqE;YACrE,oEAAoE;YACpE,wBAAwB;YACxB,EAAE;YACF,iLAAiL;SAClL,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE;KACvC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,cAAc,CACnB,qBAAqB,CAAC,UAAU,EAAE,gBAAgB,EAAE,sBAAsB,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAChG,CAAC;QACJ,CAAC;QACD,IAAI,CAAC;YACH,6DAA6D;YAC7D,yDAAyD;YACzD,+DAA+D;YAC/D,yBAAyB;YACzB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/C,OAAO,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;QACE,KAAK,EAAE,iCAAiC;QACxC,WAAW,EAAE;YACX,8BAA8B;YAC9B,uGAAuG;SACxG,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE;KAC1E,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC;YAC7F,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACvE,OAAO,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,2BAA2B,EAC3B;QACE,KAAK,EAAE,8BAA8B;QACrC,WAAW,EAAE;YACX,oDAAoD;YACpD,sDAAsD;YACtD,EAAE;YACF,uEAAuE;SACxE,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACjC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YACvE,MAAM,EAAE,aAAa;SACtB;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CACtC,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,EAAE,EACP,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EACvB,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,CACjC,CAAC;YACF,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACvE,OAAO,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,gCAAgC,EAChC;QACE,KAAK,EAAE,oCAAoC;QAC3C,WAAW,EAAE,qDAAqD;QAClE,WAAW,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE;KACvC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,cAAc,CACnB,qBAAqB,CACnB,UAAU,EACV,gBAAgB,EAChB,sBAAsB,CAAC,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EACnD,IAAI,CAAC,KAAK,CACX,CACF,CAAC;QACJ,CAAC;QACD,IAAI,CAAC;YACH,6DAA6D;YAC7D,4BAA4B;YAC5B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtD,OAAO,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,2BAA2B,EAC3B;QACE,KAAK,EAAE,+BAA+B;QACtC,WAAW,EAAE;YACX,oEAAoE;YACpE,mFAAmF;SACpF,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE;KAC1E,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC;YAChG,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACvE,OAAO,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;QACE,KAAK,EAAE,yCAAyC;QAChD,WAAW,EAAE;YACX,wDAAwD;YACxD,EAAE;YACF,4HAA4H;YAC5H,4HAA4H;SAC7H,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE;KACvC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,cAAc,CAAC,qBAAqB,CAAC,2BAA2B,EAAE,gBAAgB,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9G,CAAC;QACD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5D,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;QACE,KAAK,EAAE,gDAAgD;QACvD,WAAW,EAAE;YACX,gEAAgE;YAChE,sDAAsD;YACtD,EAAE;YACF,+CAA+C;SAChD,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YACtC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YACxC,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YAC7C,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YAC/C,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YAC3C,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YACzC,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YAChD,wBAAwB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;YAChD,MAAM,EAAE,aAAa;SACtB;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAmC,EAAE,CAAC;YACnD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YAC5D,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAAE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YAClE,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS;gBAAE,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;YACjF,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS;gBAAE,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;YACvF,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;gBAAE,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;YAC3E,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;gBAAE,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;YACrE,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS;gBAAE,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC;YAC1F,IAAI,IAAI,CAAC,wBAAwB,KAAK,SAAS,EAAE,CAAC;gBAChD,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,wBAAwB,CAAC;YACnE,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC;YACzG,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACvE,OAAO,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,CAAC,YAAY,CACjB,0BAA0B,EAC1B;QACE,KAAK,EAAE,8CAA8C;QACrD,WAAW,EAAE;YACX,sDAAsD;YACtD,qEAAqE;SACtE,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE;KACvC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC;YAClG,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACvE,OAAO,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC;AAOD,SAAS,eAAe,CAAC,IAAa;IACpC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;KACjE,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,GAAY;IAChC,MAAM,KAAK,GAAG,8BAA8B,CAAC,GAAG,CAAC,CAAC;IAClD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACjC,IAAI,GAAG,YAAY,IAAI,CAAC,SAAS,EAAE,CAAC;QAClC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;wBACJ,UAAU,GAAG,CAAC,OAAO,EAAE;wBACvB,EAAE;wBACF,GAAG,CAAC,IAAI,KAAK,WAAW;4BACtB,CAAC,CAAC,mEAAmE;4BACrE,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,gBAAgB;gCAC7B,CAAC,CAAC,0FAA0F;gCAC5F,CAAC,CAAC,+DAA+D;wBACrE,EAAE;wBACF,UAAU,GAAG,CAAC,IAAI,GAAG;qBACtB,CAAC,IAAI,CAAC,IAAI,CAAC;iBACb;aACF;SACF,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE;oBACJ,+BAA+B,OAAO,EAAE;oBACxC,EAAE;oBACF,0DAA0D;oBAC1D,EAAE;oBACF,iBAAiB;iBAClB,CAAC,IAAI,CAAC,IAAI,CAAC;aACb;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,129 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * MCP `outputSchema` definitions for the top-10 write-capable tools
4
+ * (#226). Each schema mirrors the TypeScript return type from
5
+ * `@ttctl/core` so LLM clients reading the tool registry can validate
6
+ * the structured payload they receive.
7
+ *
8
+ * Each schema describes the SUCCESS-path payload only. Dry-run responses
9
+ * use the uniform `{ ok, dryRun, preview }` envelope advertised via the
10
+ * tool description (see `_shared.ts` § `dryRunResponse`) and intentionally
11
+ * carry NO `structuredContent` — the SDK skips `outputSchema` validation
12
+ * when `structuredContent` is absent (per `@modelcontextprotocol/sdk`
13
+ * `_validateOutput`), so dry-run paths bypass success-shape validation
14
+ * cleanly.
15
+ *
16
+ * The MCP SDK's `normalizeObjectSchema` accepts only ZodObject shapes for
17
+ * `outputSchema`; unions and discriminated unions are silently dropped.
18
+ * Therefore each schema below is a single `z.object()` describing the
19
+ * apply-path payload — sufficient for the AC ("LLM clients can validate
20
+ * tool output against the schema").
21
+ */
22
+ /**
23
+ * Shape returned by `profile.basic.set()` on the apply path —
24
+ * mirrors `UpdateProfileResult` from `@ttctl/core`.
25
+ */
26
+ export declare const profileBasicUpdateOutputSchema: z.ZodObject<{
27
+ profile: z.ZodObject<{
28
+ id: z.ZodString;
29
+ about: z.ZodNullable<z.ZodString>;
30
+ quote: z.ZodNullable<z.ZodString>;
31
+ }, z.core.$strip>;
32
+ notice: z.ZodNullable<z.ZodString>;
33
+ }, z.core.$strip>;
34
+ /**
35
+ * Shape returned by `profile.basic.photoUpload()` — mirrors `PhotoUrl`
36
+ * from `@ttctl/core`.
37
+ */
38
+ export declare const profileBasicPhotoUploadOutputSchema: z.ZodObject<{
39
+ default: z.ZodNullable<z.ZodString>;
40
+ original: z.ZodNullable<z.ZodString>;
41
+ small: z.ZodNullable<z.ZodString>;
42
+ cropped: z.ZodNullable<z.ZodObject<{
43
+ x: z.ZodNumber;
44
+ y: z.ZodNumber;
45
+ width: z.ZodNumber;
46
+ height: z.ZodNumber;
47
+ }, z.core.$strip>>;
48
+ isResolutionSatisfied: z.ZodBoolean;
49
+ }, z.core.$strip>;
50
+ /**
51
+ * Shape returned by `profile.resume.upload()` — mirrors
52
+ * `UploadResumeResult` from `@ttctl/core`.
53
+ */
54
+ export declare const profileResumeUploadOutputSchema: z.ZodObject<{
55
+ success: z.ZodBoolean;
56
+ }, z.core.$strip>;
57
+ /**
58
+ * Shape returned by `profile.education.add()` / `update()` — mirrors
59
+ * `Education` from `@ttctl/core`.
60
+ */
61
+ export declare const profileEducationRowOutputSchema: z.ZodObject<{
62
+ id: z.ZodString;
63
+ institution: z.ZodString;
64
+ degree: z.ZodString;
65
+ fieldOfStudy: z.ZodNullable<z.ZodString>;
66
+ location: z.ZodNullable<z.ZodString>;
67
+ title: z.ZodNullable<z.ZodString>;
68
+ yearFrom: z.ZodNullable<z.ZodNumber>;
69
+ yearTo: z.ZodNullable<z.ZodNumber>;
70
+ highlight: z.ZodBoolean;
71
+ }, z.core.$strip>;
72
+ /**
73
+ * Shape returned by the `*_remove` tools' structured-content slot —
74
+ * `{ id, removed: true }`. The `text` content slot retains the
75
+ * human-readable confirmation; `structuredContent` exposes a typed
76
+ * acknowledgment.
77
+ */
78
+ export declare const profileRowRemoveOutputSchema: z.ZodObject<{
79
+ id: z.ZodString;
80
+ removed: z.ZodLiteral<true>;
81
+ }, z.core.$strip>;
82
+ /**
83
+ * Shape returned by `profile.employment.add()` / `update()` — mirrors
84
+ * `Employment` from `@ttctl/core`. The last four fields were added in
85
+ * #344 to close the write/read asymmetry; they MUST stay in sync with
86
+ * the `Employment` interface or the `add`/`update` tools' declared
87
+ * output schema would under-report the rows they actually return.
88
+ */
89
+ export declare const profileEmploymentRowOutputSchema: z.ZodObject<{
90
+ id: z.ZodString;
91
+ company: z.ZodString;
92
+ position: z.ZodString;
93
+ companyWebsite: z.ZodNullable<z.ZodString>;
94
+ noWebsite: z.ZodBoolean;
95
+ startDate: z.ZodNullable<z.ZodNumber>;
96
+ endDate: z.ZodNullable<z.ZodNumber>;
97
+ experienceItems: z.ZodNullable<z.ZodArray<z.ZodString>>;
98
+ highlight: z.ZodBoolean;
99
+ showViaToptal: z.ZodBoolean;
100
+ toptalRelated: z.ZodBoolean;
101
+ publicationPermit: z.ZodNullable<z.ZodBoolean>;
102
+ reportingTo: z.ZodNullable<z.ZodString>;
103
+ industries: z.ZodArray<z.ZodObject<{
104
+ id: z.ZodString;
105
+ name: z.ZodString;
106
+ }, z.core.$strip>>;
107
+ primaryGeography: z.ZodNullable<z.ZodObject<{
108
+ id: z.ZodString;
109
+ code: z.ZodNullable<z.ZodString>;
110
+ name: z.ZodNullable<z.ZodString>;
111
+ }, z.core.$strip>>;
112
+ }, z.core.$strip>;
113
+ /**
114
+ * Shape returned by `profile.industries.update()` / `show()` — mirrors
115
+ * `IndustryProfile` from `@ttctl/core`.
116
+ */
117
+ export declare const profileIndustriesRowOutputSchema: z.ZodObject<{
118
+ id: z.ZodString;
119
+ title: z.ZodString;
120
+ about: z.ZodNullable<z.ZodString>;
121
+ domainArea: z.ZodNullable<z.ZodString>;
122
+ }, z.core.$strip>;
123
+ /**
124
+ * Tool names (frozen) that the test suite asserts must carry a populated
125
+ * `outputSchema`. Adding a new write-capable tool: append its name here
126
+ * and define the schema above.
127
+ */
128
+ export declare const TOOLS_WITH_OUTPUT_SCHEMA: readonly ["ttctl_profile_basic_update", "ttctl_profile_basic_photo_upload", "ttctl_profile_resume_upload", "ttctl_profile_education_add", "ttctl_profile_education_update", "ttctl_profile_education_remove", "ttctl_profile_employment_add", "ttctl_profile_employment_update", "ttctl_profile_employment_remove", "ttctl_profile_industries_update", "ttctl_profile_industries_show"];
129
+ //# sourceMappingURL=output-schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-schemas.d.ts","sourceRoot":"","sources":["../../src/tools/output-schemas.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;GAGG;AACH,eAAO,MAAM,8BAA8B;;;;;;;iBAOzC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,mCAAmC;;;;;;;;;;;iBAa9C,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,+BAA+B;;iBAE1C,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;;iBAU1C,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B;;;iBAGvC,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;iBAgB3C,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,gCAAgC;;;;;iBAK3C,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,yXAY3B,CAAC"}