@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.
- package/README.md +72 -9
- package/dist/auth.d.ts +40 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +69 -0
- package/dist/auth.js.map +1 -0
- package/dist/data-handling.d.ts +91 -0
- package/dist/data-handling.d.ts.map +1 -0
- package/dist/data-handling.js +129 -0
- package/dist/data-handling.js.map +1 -0
- package/dist/diagnostic.d.ts +262 -0
- package/dist/diagnostic.d.ts.map +1 -0
- package/dist/diagnostic.js +362 -0
- package/dist/diagnostic.js.map +1 -0
- package/dist/errors.d.ts +54 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +48 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/kill-switch-hook.d.ts +67 -0
- package/dist/kill-switch-hook.d.ts.map +1 -0
- package/dist/kill-switch-hook.js +61 -0
- package/dist/kill-switch-hook.js.map +1 -0
- package/dist/server.d.ts +100 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +157 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/_shared.d.ts +227 -0
- package/dist/tools/_shared.d.ts.map +1 -0
- package/dist/tools/_shared.js +238 -0
- package/dist/tools/_shared.js.map +1 -0
- package/dist/tools/applications.d.ts +27 -0
- package/dist/tools/applications.d.ts.map +1 -0
- package/dist/tools/applications.js +192 -0
- package/dist/tools/applications.js.map +1 -0
- package/dist/tools/availability.d.ts +33 -0
- package/dist/tools/availability.d.ts.map +1 -0
- package/dist/tools/availability.js +272 -0
- package/dist/tools/availability.js.map +1 -0
- package/dist/tools/contracts.d.ts +29 -0
- package/dist/tools/contracts.d.ts.map +1 -0
- package/dist/tools/contracts.js +157 -0
- package/dist/tools/contracts.js.map +1 -0
- package/dist/tools/engagements.d.ts +36 -0
- package/dist/tools/engagements.d.ts.map +1 -0
- package/dist/tools/engagements.js +408 -0
- package/dist/tools/engagements.js.map +1 -0
- package/dist/tools/file-upload.d.ts +133 -0
- package/dist/tools/file-upload.d.ts.map +1 -0
- package/dist/tools/file-upload.js +247 -0
- package/dist/tools/file-upload.js.map +1 -0
- package/dist/tools/index.d.ts +28 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +133 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/jobs.d.ts +37 -0
- package/dist/tools/jobs.d.ts.map +1 -0
- package/dist/tools/jobs.js +505 -0
- package/dist/tools/jobs.js.map +1 -0
- package/dist/tools/output-schemas.d.ts +129 -0
- package/dist/tools/output-schemas.d.ts.map +1 -0
- package/dist/tools/output-schemas.js +138 -0
- package/dist/tools/output-schemas.js.map +1 -0
- package/dist/tools/payments.d.ts +36 -0
- package/dist/tools/payments.d.ts.map +1 -0
- package/dist/tools/payments.js +373 -0
- package/dist/tools/payments.js.map +1 -0
- package/dist/tools/profile/certifications.d.ts +18 -0
- package/dist/tools/profile/certifications.d.ts.map +1 -0
- package/dist/tools/profile/certifications.js +219 -0
- package/dist/tools/profile/certifications.js.map +1 -0
- package/dist/tools/profile/education.d.ts +23 -0
- package/dist/tools/profile/education.d.ts.map +1 -0
- package/dist/tools/profile/education.js +222 -0
- package/dist/tools/profile/education.js.map +1 -0
- package/dist/tools/profile/employment.d.ts +23 -0
- package/dist/tools/profile/employment.d.ts.map +1 -0
- package/dist/tools/profile/employment.js +254 -0
- package/dist/tools/profile/employment.js.map +1 -0
- package/dist/tools/profile/industries.d.ts +30 -0
- package/dist/tools/profile/industries.d.ts.map +1 -0
- package/dist/tools/profile/industries.js +196 -0
- package/dist/tools/profile/industries.js.map +1 -0
- package/dist/tools/profile/portfolio.d.ts +22 -0
- package/dist/tools/profile/portfolio.d.ts.map +1 -0
- package/dist/tools/profile/portfolio.js +341 -0
- package/dist/tools/profile/portfolio.js.map +1 -0
- package/dist/tools/profile/resume.d.ts +16 -0
- package/dist/tools/profile/resume.d.ts.map +1 -0
- package/dist/tools/profile/resume.js +107 -0
- package/dist/tools/profile/resume.js.map +1 -0
- package/dist/tools/profile/shared.d.ts +85 -0
- package/dist/tools/profile/shared.d.ts.map +1 -0
- package/dist/tools/profile/shared.js +128 -0
- package/dist/tools/profile/shared.js.map +1 -0
- package/dist/tools/profile/visas.d.ts +15 -0
- package/dist/tools/profile/visas.d.ts.map +1 -0
- package/dist/tools/profile/visas.js +170 -0
- package/dist/tools/profile/visas.js.map +1 -0
- package/dist/tools/profile_basic_photo_show.d.ts +14 -0
- package/dist/tools/profile_basic_photo_show.d.ts.map +1 -0
- package/dist/tools/profile_basic_photo_show.js +59 -0
- package/dist/tools/profile_basic_photo_show.js.map +1 -0
- package/dist/tools/profile_basic_photo_upload.d.ts +24 -0
- package/dist/tools/profile_basic_photo_upload.d.ts.map +1 -0
- package/dist/tools/profile_basic_photo_upload.js +90 -0
- package/dist/tools/profile_basic_photo_upload.js.map +1 -0
- package/dist/tools/profile_basic_show.d.ts +64 -0
- package/dist/tools/profile_basic_show.d.ts.map +1 -0
- package/dist/tools/profile_basic_show.js +108 -0
- package/dist/tools/profile_basic_show.js.map +1 -0
- package/dist/tools/profile_basic_update.d.ts +37 -0
- package/dist/tools/profile_basic_update.d.ts.map +1 -0
- package/dist/tools/profile_basic_update.js +97 -0
- package/dist/tools/profile_basic_update.js.map +1 -0
- package/dist/tools/profile_external_advanced_wizard_show.d.ts +14 -0
- package/dist/tools/profile_external_advanced_wizard_show.d.ts.map +1 -0
- package/dist/tools/profile_external_advanced_wizard_show.js +56 -0
- package/dist/tools/profile_external_advanced_wizard_show.js.map +1 -0
- package/dist/tools/profile_external_custom_requirements_set.d.ts +13 -0
- package/dist/tools/profile_external_custom_requirements_set.d.ts.map +1 -0
- package/dist/tools/profile_external_custom_requirements_set.js +75 -0
- package/dist/tools/profile_external_custom_requirements_set.js.map +1 -0
- package/dist/tools/profile_external_custom_requirements_show.d.ts +14 -0
- package/dist/tools/profile_external_custom_requirements_show.d.ts.map +1 -0
- package/dist/tools/profile_external_custom_requirements_show.js +56 -0
- package/dist/tools/profile_external_custom_requirements_show.js.map +1 -0
- package/dist/tools/profile_external_readiness.d.ts +12 -0
- package/dist/tools/profile_external_readiness.d.ts.map +1 -0
- package/dist/tools/profile_external_readiness.js +54 -0
- package/dist/tools/profile_external_readiness.js.map +1 -0
- package/dist/tools/profile_external_recommendations.d.ts +15 -0
- package/dist/tools/profile_external_recommendations.d.ts.map +1 -0
- package/dist/tools/profile_external_recommendations.js +57 -0
- package/dist/tools/profile_external_recommendations.js.map +1 -0
- package/dist/tools/profile_external_show.d.ts +15 -0
- package/dist/tools/profile_external_show.d.ts.map +1 -0
- package/dist/tools/profile_external_show.js +59 -0
- package/dist/tools/profile_external_show.js.map +1 -0
- package/dist/tools/profile_external_update.d.ts +14 -0
- package/dist/tools/profile_external_update.d.ts.map +1 -0
- package/dist/tools/profile_external_update.js +79 -0
- package/dist/tools/profile_external_update.js.map +1 -0
- package/dist/tools/profile_reviews_approve_item.d.ts +17 -0
- package/dist/tools/profile_reviews_approve_item.d.ts.map +1 -0
- package/dist/tools/profile_reviews_approve_item.js +77 -0
- package/dist/tools/profile_reviews_approve_item.js.map +1 -0
- package/dist/tools/profile_reviews_approve_section.d.ts +15 -0
- package/dist/tools/profile_reviews_approve_section.d.ts.map +1 -0
- package/dist/tools/profile_reviews_approve_section.js +70 -0
- package/dist/tools/profile_reviews_approve_section.js.map +1 -0
- package/dist/tools/profile_reviews_list.d.ts +16 -0
- package/dist/tools/profile_reviews_list.d.ts.map +1 -0
- package/dist/tools/profile_reviews_list.js +58 -0
- package/dist/tools/profile_reviews_list.js.map +1 -0
- package/dist/tools/profile_reviews_submit_for_review.d.ts +14 -0
- package/dist/tools/profile_reviews_submit_for_review.d.ts.map +1 -0
- package/dist/tools/profile_reviews_submit_for_review.js +56 -0
- package/dist/tools/profile_reviews_submit_for_review.js.map +1 -0
- package/dist/tools/profile_skills_add.d.ts +4 -0
- package/dist/tools/profile_skills_add.d.ts.map +1 -0
- package/dist/tools/profile_skills_add.js +52 -0
- package/dist/tools/profile_skills_add.js.map +1 -0
- package/dist/tools/profile_skills_autocomplete.d.ts +4 -0
- package/dist/tools/profile_skills_autocomplete.d.ts.map +1 -0
- package/dist/tools/profile_skills_autocomplete.js +78 -0
- package/dist/tools/profile_skills_autocomplete.js.map +1 -0
- package/dist/tools/profile_skills_list.d.ts +16 -0
- package/dist/tools/profile_skills_list.d.ts.map +1 -0
- package/dist/tools/profile_skills_list.js +65 -0
- package/dist/tools/profile_skills_list.js.map +1 -0
- package/dist/tools/profile_skills_readiness.d.ts +4 -0
- package/dist/tools/profile_skills_readiness.d.ts.map +1 -0
- package/dist/tools/profile_skills_readiness.js +53 -0
- package/dist/tools/profile_skills_readiness.js.map +1 -0
- package/dist/tools/profile_skills_remove.d.ts +4 -0
- package/dist/tools/profile_skills_remove.d.ts.map +1 -0
- package/dist/tools/profile_skills_remove.js +53 -0
- package/dist/tools/profile_skills_remove.js.map +1 -0
- package/dist/tools/profile_skills_show.d.ts +4 -0
- package/dist/tools/profile_skills_show.d.ts.map +1 -0
- package/dist/tools/profile_skills_show.js +51 -0
- package/dist/tools/profile_skills_show.js.map +1 -0
- package/dist/tools/profile_skills_update.d.ts +11 -0
- package/dist/tools/profile_skills_update.d.ts.map +1 -0
- package/dist/tools/profile_skills_update.js +97 -0
- package/dist/tools/profile_skills_update.js.map +1 -0
- package/dist/tools/timesheet.d.ts +29 -0
- package/dist/tools/timesheet.d.ts.map +1 -0
- package/dist/tools/timesheet.js +257 -0
- package/dist/tools/timesheet.js.map +1 -0
- package/package.json +33 -13
- package/index.js +0 -7
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { contracts } 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
|
+
* Register the `ttctl_contracts_*` MCP tools (#195). Two read-only tools:
|
|
13
|
+
*
|
|
14
|
+
* - `ttctl_contracts_list` — list talent-level contracts
|
|
15
|
+
* - `ttctl_contracts_show` — show one contract by id
|
|
16
|
+
*
|
|
17
|
+
* The `<id>` argument is the `Contract.id` from `ttctl_contracts_list`.
|
|
18
|
+
*
|
|
19
|
+
* **Domain distinction**: this group surfaces talent-level legal
|
|
20
|
+
* documents (Toptal Direct, Master Service Agreement) via
|
|
21
|
+
* `viewer.contracts` on the portal surface. Engagement-attached
|
|
22
|
+
* commercial agreements (rates, hours, period for one project) live
|
|
23
|
+
* on a different surface — use `ttctl_engagements_show <engagement-id>`.
|
|
24
|
+
*
|
|
25
|
+
* **Dry-run path** (issue #165): both tools accept `dryRun?: boolean`.
|
|
26
|
+
* Read-only tools build the preview at the MCP layer via
|
|
27
|
+
* `buildMcpDryRunPreview` — `show` previews the same `GetContracts`
|
|
28
|
+
* operation as `list` (the apply path fetches the list and filters
|
|
29
|
+
* client-side; the dry-run reflects that wire call accurately).
|
|
30
|
+
*
|
|
31
|
+
* **Per CLAUDE.md schema/contract validation rule**: `GetContracts`
|
|
32
|
+
* is hand-authored against the portal surface; every projected field
|
|
33
|
+
* is `Unknown`-typed in the SDL → INFERRED. Live E2E coverage
|
|
34
|
+
* (`packages/e2e/src/35-contracts.e2e.test.ts`) is mandatory pre-merge.
|
|
35
|
+
*/
|
|
36
|
+
export function registerContractsTools(server, ctx) {
|
|
37
|
+
server.registerTool("ttctl_contracts_list", {
|
|
38
|
+
title: "List talent-level contracts",
|
|
39
|
+
description: [
|
|
40
|
+
"List the signed-in user's talent-level legal contracts.",
|
|
41
|
+
"These are top-level documents like Toptal Direct, Master Service Agreement, etc.",
|
|
42
|
+
"(reachable via `viewer.contracts` on the portal surface).",
|
|
43
|
+
"",
|
|
44
|
+
"For engagement-attached commercial agreements (rates, hours, period for a",
|
|
45
|
+
"specific project), use `ttctl_engagements_show <engagement-id>` instead —",
|
|
46
|
+
"those are a different domain on a different transport.",
|
|
47
|
+
"",
|
|
48
|
+
"Returns a list of contracts; each contract carries id, kind, provider,",
|
|
49
|
+
"status, billingType, signedAt, sentAt, isActive, verificationDeadline, title.",
|
|
50
|
+
"",
|
|
51
|
+
"Example user prompts:",
|
|
52
|
+
' - "What Toptal contracts do I have?"',
|
|
53
|
+
' - "Show me my Toptal legal documents."',
|
|
54
|
+
' - "Is my Toptal Direct contract active?"',
|
|
55
|
+
].join("\n"),
|
|
56
|
+
inputSchema: {
|
|
57
|
+
dryRun: DRY_RUN_FIELD,
|
|
58
|
+
},
|
|
59
|
+
}, async (args) => {
|
|
60
|
+
const auth = await ctx.resolveToolAuth();
|
|
61
|
+
if (!auth.ok)
|
|
62
|
+
return auth.response;
|
|
63
|
+
if (args.dryRun === true) {
|
|
64
|
+
return dryRunResponse(buildMcpDryRunPreview("GetContracts", "talent-profile", {}, auth.token));
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const items = await contracts.list(auth.token);
|
|
68
|
+
return successResponse(items);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
return mapContractsError(err);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
server.registerTool("ttctl_contracts_show", {
|
|
75
|
+
title: "Show one talent-level contract by id",
|
|
76
|
+
description: [
|
|
77
|
+
"Fetch one talent-level contract by id (the row id from `ttctl_contracts_list`).",
|
|
78
|
+
"Returns the full projection: id, kind, provider, status, billingType,",
|
|
79
|
+
"signedAt, sentAt, isActive, verificationDeadline, title.",
|
|
80
|
+
"",
|
|
81
|
+
"The portal API does not expose a per-id contract lookup; this tool fetches",
|
|
82
|
+
"the full contracts list and filters client-side. Latency-conscious callers",
|
|
83
|
+
"querying multiple contracts should use `ttctl_contracts_list` once.",
|
|
84
|
+
"",
|
|
85
|
+
"Example user prompts:",
|
|
86
|
+
' - "Show me contract ct_abc123."',
|
|
87
|
+
' - "What is the status of my MSA with Toptal?"',
|
|
88
|
+
].join("\n"),
|
|
89
|
+
inputSchema: {
|
|
90
|
+
id: z.string().describe("Contract id (the row id from `ttctl_contracts_list`)"),
|
|
91
|
+
dryRun: DRY_RUN_FIELD,
|
|
92
|
+
},
|
|
93
|
+
}, async (args) => {
|
|
94
|
+
const auth = await ctx.resolveToolAuth();
|
|
95
|
+
if (!auth.ok)
|
|
96
|
+
return auth.response;
|
|
97
|
+
if (args.dryRun === true) {
|
|
98
|
+
// The apply path fetches the same `GetContracts` operation as the
|
|
99
|
+
// list tool, then filters client-side. The preview accurately
|
|
100
|
+
// reflects the wire call (no per-id variable on the operation).
|
|
101
|
+
return dryRunResponse(buildMcpDryRunPreview("GetContracts", "talent-profile", {}, auth.token));
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
const item = await contracts.show(auth.token, args.id);
|
|
105
|
+
return successResponse(item);
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
return mapContractsError(err);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function successResponse(data) {
|
|
113
|
+
return {
|
|
114
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function mapContractsError(err) {
|
|
118
|
+
const typed = ttctlErrorToToolResponseOrNull(err);
|
|
119
|
+
if (typed !== null)
|
|
120
|
+
return typed;
|
|
121
|
+
if (err instanceof contracts.ContractsError) {
|
|
122
|
+
return {
|
|
123
|
+
isError: true,
|
|
124
|
+
content: [
|
|
125
|
+
{
|
|
126
|
+
type: "text",
|
|
127
|
+
text: [`Error: ${err.message}`, "", recoveryForCode(err.code), "", `(Code: ${err.code})`].join("\n"),
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
133
|
+
return {
|
|
134
|
+
isError: true,
|
|
135
|
+
content: [
|
|
136
|
+
{
|
|
137
|
+
type: "text",
|
|
138
|
+
text: [
|
|
139
|
+
`Error: contracts request failed: ${message}`,
|
|
140
|
+
"",
|
|
141
|
+
"Recovery: Retry; if the failure persists, file an issue.",
|
|
142
|
+
"",
|
|
143
|
+
"(Code: UNKNOWN)",
|
|
144
|
+
].join("\n"),
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function recoveryForCode(code) {
|
|
150
|
+
switch (code) {
|
|
151
|
+
case "NOT_FOUND":
|
|
152
|
+
return "Recovery: Verify the contract id (use `ttctl_contracts_list` to discover ids).";
|
|
153
|
+
default:
|
|
154
|
+
return "Recovery: Adjust the tool input or retry; see the code below.";
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../src/tools/contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type ToolRegistrationContext } from "./_shared.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register the `ttctl_engagements_*` MCP tools (initial #147 spec
|
|
5
|
+
* extended by #155 with `breaks_reschedule`). Tool names use the
|
|
6
|
+
* `ttctl_` prefix and the canonical CLI path joined with `_`:
|
|
7
|
+
*
|
|
8
|
+
* - `ttctl_engagements_list`
|
|
9
|
+
* - `ttctl_engagements_show`
|
|
10
|
+
* - `ttctl_engagements_stats`
|
|
11
|
+
* - `ttctl_engagements_breaks_list`
|
|
12
|
+
* - `ttctl_engagements_breaks_add`
|
|
13
|
+
* - `ttctl_engagements_breaks_remove`
|
|
14
|
+
* - `ttctl_engagements_breaks_reschedule` (#155)
|
|
15
|
+
*
|
|
16
|
+
* Each tool maps 1:1 to a CLI leaf — the schemas describe the same set
|
|
17
|
+
* of fields. The `<id>` argument is the `jobActivityItem.id` (the row
|
|
18
|
+
* id from `engagements_list`); `<break-id>` is the
|
|
19
|
+
* `engagementBreak.id` (the id returned by `engagements_breaks_list`).
|
|
20
|
+
*
|
|
21
|
+
* Per #147 scope amendment (2026-05-10), `allocated-hours` is NOT
|
|
22
|
+
* surfaced here — that scope moved to `availability` (#146) since the
|
|
23
|
+
* underlying mutation (`UpdateAllocatedHours`) operates on
|
|
24
|
+
* `viewerRole`, not per-engagement.
|
|
25
|
+
*
|
|
26
|
+
* Dry-run path (issue #165): every tool accepts `dryRun?: boolean`. The
|
|
27
|
+
* three read-only tools and `breaks_list` use MCP-layer preview building;
|
|
28
|
+
* the two break mutations are passthrough — `core.engagements.breaks.{add,remove}`
|
|
29
|
+
* already support `{ dryRun: true }` (#163), so the MCP layer forwards
|
|
30
|
+
* the flag and reformats the resulting `{ kind: "preview", preview }`
|
|
31
|
+
* outcome as the uniform `{ ok, dryRun, preview }` envelope. `stats`
|
|
32
|
+
* uses the plural `{ previews: [...] }` envelope (2 parallel
|
|
33
|
+
* `JobActivityItems` calls — one per status group).
|
|
34
|
+
*/
|
|
35
|
+
export declare function registerEngagementsTools(server: McpServer, ctx: ToolRegistrationContext): void;
|
|
36
|
+
//# sourceMappingURL=engagements.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engagements.d.ts","sourceRoot":"","sources":["../../src/tools/engagements.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,OAAO,EAA8D,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC;AASxH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,uBAAuB,GAAG,IAAI,CA6V9F"}
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { engagements } from "@ttctl/core";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { ttctlErrorToToolResponseOrNull } from "../errors.js";
|
|
6
|
+
import { buildMcpDryRunPreview, dryRunMultiResponse, 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
|
+
* Register the `ttctl_engagements_*` MCP tools (initial #147 spec
|
|
13
|
+
* extended by #155 with `breaks_reschedule`). Tool names use the
|
|
14
|
+
* `ttctl_` prefix and the canonical CLI path joined with `_`:
|
|
15
|
+
*
|
|
16
|
+
* - `ttctl_engagements_list`
|
|
17
|
+
* - `ttctl_engagements_show`
|
|
18
|
+
* - `ttctl_engagements_stats`
|
|
19
|
+
* - `ttctl_engagements_breaks_list`
|
|
20
|
+
* - `ttctl_engagements_breaks_add`
|
|
21
|
+
* - `ttctl_engagements_breaks_remove`
|
|
22
|
+
* - `ttctl_engagements_breaks_reschedule` (#155)
|
|
23
|
+
*
|
|
24
|
+
* Each tool maps 1:1 to a CLI leaf — the schemas describe the same set
|
|
25
|
+
* of fields. The `<id>` argument is the `jobActivityItem.id` (the row
|
|
26
|
+
* id from `engagements_list`); `<break-id>` is the
|
|
27
|
+
* `engagementBreak.id` (the id returned by `engagements_breaks_list`).
|
|
28
|
+
*
|
|
29
|
+
* Per #147 scope amendment (2026-05-10), `allocated-hours` is NOT
|
|
30
|
+
* surfaced here — that scope moved to `availability` (#146) since the
|
|
31
|
+
* underlying mutation (`UpdateAllocatedHours`) operates on
|
|
32
|
+
* `viewerRole`, not per-engagement.
|
|
33
|
+
*
|
|
34
|
+
* Dry-run path (issue #165): every tool accepts `dryRun?: boolean`. The
|
|
35
|
+
* three read-only tools and `breaks_list` use MCP-layer preview building;
|
|
36
|
+
* the two break mutations are passthrough — `core.engagements.breaks.{add,remove}`
|
|
37
|
+
* already support `{ dryRun: true }` (#163), so the MCP layer forwards
|
|
38
|
+
* the flag and reformats the resulting `{ kind: "preview", preview }`
|
|
39
|
+
* outcome as the uniform `{ ok, dryRun, preview }` envelope. `stats`
|
|
40
|
+
* uses the plural `{ previews: [...] }` envelope (2 parallel
|
|
41
|
+
* `JobActivityItems` calls — one per status group).
|
|
42
|
+
*/
|
|
43
|
+
export function registerEngagementsTools(server, ctx) {
|
|
44
|
+
server.registerTool("ttctl_engagements_list", {
|
|
45
|
+
title: "List engagements",
|
|
46
|
+
description: [
|
|
47
|
+
"List the signed-in user's Toptal Talent engagements (active by default).",
|
|
48
|
+
"An engagement is an active assignment between the user and a client",
|
|
49
|
+
"(= what users colloquially call 'current job' or 'current contract').",
|
|
50
|
+
"",
|
|
51
|
+
"Filter via `status`:",
|
|
52
|
+
" - `active` (default): currently active engagements",
|
|
53
|
+
" - `past`: closed engagements",
|
|
54
|
+
" - `all`: both",
|
|
55
|
+
"",
|
|
56
|
+
"Optional `keywords` is a free-text filter (AND across multiple).",
|
|
57
|
+
"",
|
|
58
|
+
"Example user prompts:",
|
|
59
|
+
' - "What are my active Toptal engagements?"',
|
|
60
|
+
' - "Show me my past Toptal contracts."',
|
|
61
|
+
' - "List all my Toptal jobs, current and past."',
|
|
62
|
+
].join("\n"),
|
|
63
|
+
inputSchema: {
|
|
64
|
+
status: z
|
|
65
|
+
.enum([...engagements.ENGAGEMENT_LIST_STATUSES])
|
|
66
|
+
.optional()
|
|
67
|
+
.describe("Filter by engagement status: active (default), past, or all"),
|
|
68
|
+
keywords: z.array(z.string()).optional().describe("Free-text keyword filter (AND across multiple)"),
|
|
69
|
+
dryRun: DRY_RUN_FIELD,
|
|
70
|
+
},
|
|
71
|
+
}, async (args) => {
|
|
72
|
+
const auth = await ctx.resolveToolAuth();
|
|
73
|
+
if (!auth.ok)
|
|
74
|
+
return auth.response;
|
|
75
|
+
const opts = {};
|
|
76
|
+
if (args.status !== undefined)
|
|
77
|
+
opts.status = args.status;
|
|
78
|
+
if (args.keywords !== undefined)
|
|
79
|
+
opts.keywords = args.keywords;
|
|
80
|
+
if (args.dryRun === true) {
|
|
81
|
+
// Mirror the apply-path mapping from `--status` to
|
|
82
|
+
// JobActivityItemStatusGroupEnum so the preview's
|
|
83
|
+
// `onlyStatusGroupFilter` matches what the wire call would send.
|
|
84
|
+
// Apply path: core/services/engagements/index.ts `listStatusToGroups`.
|
|
85
|
+
const status = opts.status ?? "active";
|
|
86
|
+
const statusGroups = status === "active"
|
|
87
|
+
? ["ACTIVE_ENGAGEMENT"]
|
|
88
|
+
: status === "past"
|
|
89
|
+
? ["CLOSED_ENGAGEMENT"]
|
|
90
|
+
: ["ACTIVE_ENGAGEMENT", "CLOSED_ENGAGEMENT"];
|
|
91
|
+
const variables = {
|
|
92
|
+
keywords: opts.keywords !== undefined && opts.keywords.length > 0 ? opts.keywords : null,
|
|
93
|
+
onlyStatusGroupFilter: statusGroups,
|
|
94
|
+
};
|
|
95
|
+
return dryRunResponse(buildMcpDryRunPreview("JobActivityItems", "mobile-gateway", variables, auth.token));
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const items = await engagements.list(auth.token, opts);
|
|
99
|
+
return successResponse(items);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
return mapEngagementsError(err);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
server.registerTool("ttctl_engagements_show", {
|
|
106
|
+
title: "Show one engagement",
|
|
107
|
+
description: [
|
|
108
|
+
"Fetch a single engagement's full detail by id (the row id from",
|
|
109
|
+
"`ttctl_engagements_list`, which is the underlying TalentJobActivityItem id).",
|
|
110
|
+
"Returns the engagement metadata (status, start/end dates, expected hours,",
|
|
111
|
+
"commitment), the underlying job (title, client, description, work type),",
|
|
112
|
+
"the current agreement (rates, commitment), earnings summary, and any",
|
|
113
|
+
"scheduled breaks.",
|
|
114
|
+
"",
|
|
115
|
+
"Example user prompts:",
|
|
116
|
+
' - "Show me the details of engagement act_xyz."',
|
|
117
|
+
' - "What is my hourly rate on engagement act_abc?"',
|
|
118
|
+
' - "Are there any scheduled breaks on my current Toptal engagement?"',
|
|
119
|
+
].join("\n"),
|
|
120
|
+
inputSchema: {
|
|
121
|
+
id: z.string().describe("Engagement id (the TalentJobActivityItem id from `engagements_list`)"),
|
|
122
|
+
dryRun: DRY_RUN_FIELD,
|
|
123
|
+
},
|
|
124
|
+
}, async (args) => {
|
|
125
|
+
const auth = await ctx.resolveToolAuth();
|
|
126
|
+
if (!auth.ok)
|
|
127
|
+
return auth.response;
|
|
128
|
+
if (args.dryRun === true) {
|
|
129
|
+
return dryRunResponse(buildMcpDryRunPreview("JobActivityItem", "mobile-gateway", { id: args.id }, auth.token));
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
const item = await engagements.show(auth.token, args.id);
|
|
133
|
+
return successResponse(item);
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
return mapEngagementsError(err);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
server.registerTool("ttctl_engagements_stats", {
|
|
140
|
+
title: "Per-status engagement counts",
|
|
141
|
+
description: [
|
|
142
|
+
"Aggregate engagement counts: returns per-status totals (active, past) plus",
|
|
143
|
+
"the overall sum.",
|
|
144
|
+
"",
|
|
145
|
+
"Issues 2 server calls in parallel (one per engagement-bearing status group).",
|
|
146
|
+
"Each count is server-provided (totalCount on JobActivityList) — no",
|
|
147
|
+
"client-side aggregation.",
|
|
148
|
+
"",
|
|
149
|
+
"Example user prompts:",
|
|
150
|
+
' - "How many Toptal engagements have I had in total?"',
|
|
151
|
+
' - "Show me a breakdown of my Toptal engagements by status."',
|
|
152
|
+
"",
|
|
153
|
+
"Dry-run note: returns `{ ok: true, dryRun: true, previews: [...] }` (plural `previews`) — one `JobActivityItems` preview per engagement status group (2 total: ACTIVE_ENGAGEMENT, CLOSED_ENGAGEMENT), matching the 2 parallel calls the apply path fires.",
|
|
154
|
+
].join("\n"),
|
|
155
|
+
inputSchema: { dryRun: DRY_RUN_FIELD },
|
|
156
|
+
}, async (args) => {
|
|
157
|
+
const auth = await ctx.resolveToolAuth();
|
|
158
|
+
if (!auth.ok)
|
|
159
|
+
return auth.response;
|
|
160
|
+
if (args.dryRun === true) {
|
|
161
|
+
const previews = engagements.ENGAGEMENT_STATUS_GROUPS.map((group) => buildMcpDryRunPreview("JobActivityItems", "mobile-gateway", { keywords: null, onlyStatusGroupFilter: [group] }, auth.token));
|
|
162
|
+
return dryRunMultiResponse(previews);
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
const stats = await engagements.stats(auth.token);
|
|
166
|
+
return successResponse(stats);
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
return mapEngagementsError(err);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
server.registerTool("ttctl_engagements_breaks_list", {
|
|
173
|
+
title: "List breaks on an engagement",
|
|
174
|
+
description: [
|
|
175
|
+
"List the scheduled break windows for a specific engagement.",
|
|
176
|
+
"A break is a planned period when the talent will not be working on the",
|
|
177
|
+
"engagement (vacation, time off, etc.).",
|
|
178
|
+
"",
|
|
179
|
+
"The id parameter is the engagement id (TalentJobActivityItem id), the",
|
|
180
|
+
"same id used by `ttctl_engagements_show`.",
|
|
181
|
+
"",
|
|
182
|
+
"Example user prompts:",
|
|
183
|
+
' - "Show me the scheduled breaks on engagement act_xyz."',
|
|
184
|
+
' - "Do I have any vacations planned on my current Toptal engagement?"',
|
|
185
|
+
].join("\n"),
|
|
186
|
+
inputSchema: {
|
|
187
|
+
id: z.string().describe("Engagement id (the TalentJobActivityItem id from `engagements_list`)"),
|
|
188
|
+
dryRun: DRY_RUN_FIELD,
|
|
189
|
+
},
|
|
190
|
+
}, async (args) => {
|
|
191
|
+
const auth = await ctx.resolveToolAuth();
|
|
192
|
+
if (!auth.ok)
|
|
193
|
+
return auth.response;
|
|
194
|
+
if (args.dryRun === true) {
|
|
195
|
+
return dryRunResponse(buildMcpDryRunPreview("EngagementBreaks", "mobile-gateway", { jobActivityItemId: args.id }, auth.token));
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
const items = await engagements.breaks.list(auth.token, args.id);
|
|
199
|
+
return successResponse(items);
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
return mapEngagementsError(err);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
server.registerTool("ttctl_engagements_breaks_reasons_list", {
|
|
206
|
+
title: "List valid break reasons (catalog)",
|
|
207
|
+
description: [
|
|
208
|
+
"List the server-side catalog of valid break-reason identifiers for",
|
|
209
|
+
"`ttctl_engagements_breaks_add` (the `reasonIdentifier` argument).",
|
|
210
|
+
"",
|
|
211
|
+
"Reads `platformConfiguration.engagementBreakReasons` from the mobile",
|
|
212
|
+
"gateway. Returns an array of `{identifier, nameForRole}` sorted by",
|
|
213
|
+
"`identifier`. `identifier` is what the user supplies to",
|
|
214
|
+
"`ttctl_engagements_breaks_add`; `nameForRole` is the human-readable",
|
|
215
|
+
"label.",
|
|
216
|
+
"",
|
|
217
|
+
"Use this tool to discover valid `reasonIdentifier` values before",
|
|
218
|
+
"scheduling a break — the catalog can change over time.",
|
|
219
|
+
"",
|
|
220
|
+
"Example user prompts:",
|
|
221
|
+
' - "What break reasons can I use when scheduling a Toptal engagement break?"',
|
|
222
|
+
' - "List the valid --reason-id values for `ttctl engagements breaks add`."',
|
|
223
|
+
].join("\n"),
|
|
224
|
+
inputSchema: { dryRun: DRY_RUN_FIELD },
|
|
225
|
+
}, async (args) => {
|
|
226
|
+
const auth = await ctx.resolveToolAuth();
|
|
227
|
+
if (!auth.ok)
|
|
228
|
+
return auth.response;
|
|
229
|
+
if (args.dryRun === true) {
|
|
230
|
+
return dryRunResponse(buildMcpDryRunPreview("PlatformConfiguration", "mobile-gateway", {}, auth.token));
|
|
231
|
+
}
|
|
232
|
+
try {
|
|
233
|
+
const items = await engagements.breaks.reasonsList(auth.token);
|
|
234
|
+
return successResponse(items);
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
return mapEngagementsError(err);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
server.registerTool("ttctl_engagements_breaks_add", {
|
|
241
|
+
title: "Schedule a break on an engagement",
|
|
242
|
+
description: [
|
|
243
|
+
"Schedule a new break window on an engagement.",
|
|
244
|
+
"",
|
|
245
|
+
"Required: `id` (engagement id), `startDate` (YYYY-MM-DD), `endDate`",
|
|
246
|
+
"(YYYY-MM-DD), `reasonIdentifier` (server-side reason key — known",
|
|
247
|
+
"values: `talent_on_vacation`, `client_needs_preparation`,",
|
|
248
|
+
"`client_on_vacation`, `other`).",
|
|
249
|
+
"Optional: `comment` (free-text note).",
|
|
250
|
+
"",
|
|
251
|
+
"**This is a write operation**: it modifies the user's scheduled time-off",
|
|
252
|
+
"on the live Toptal Talent platform. Confirm with the user before invoking.",
|
|
253
|
+
"",
|
|
254
|
+
"Example user prompts:",
|
|
255
|
+
' - "Schedule a break on engagement act_xyz from June 1 to June 8."',
|
|
256
|
+
' - "Add a vacation window to my current Toptal engagement next week."',
|
|
257
|
+
].join("\n"),
|
|
258
|
+
inputSchema: {
|
|
259
|
+
id: z.string().describe("Engagement id (the TalentJobActivityItem id from `engagements_list`)"),
|
|
260
|
+
startDate: z.string().describe("Break start date (YYYY-MM-DD)"),
|
|
261
|
+
endDate: z.string().describe("Break end date (YYYY-MM-DD)"),
|
|
262
|
+
reasonIdentifier: z
|
|
263
|
+
.string()
|
|
264
|
+
.describe("Server-side reason key (known: talent_on_vacation, client_needs_preparation, client_on_vacation, other)"),
|
|
265
|
+
comment: z.string().optional().describe("Optional free-text comment"),
|
|
266
|
+
dryRun: DRY_RUN_FIELD,
|
|
267
|
+
},
|
|
268
|
+
}, async (args) => {
|
|
269
|
+
const auth = await ctx.resolveToolAuth();
|
|
270
|
+
if (!auth.ok)
|
|
271
|
+
return auth.response;
|
|
272
|
+
try {
|
|
273
|
+
const opts = {
|
|
274
|
+
startDate: args.startDate,
|
|
275
|
+
endDate: args.endDate,
|
|
276
|
+
reasonIdentifier: args.reasonIdentifier,
|
|
277
|
+
};
|
|
278
|
+
if (args.comment !== undefined)
|
|
279
|
+
opts.comment = args.comment;
|
|
280
|
+
const outcome = await engagements.breaks.add(auth.token, args.id, opts, { dryRun: args.dryRun ?? false });
|
|
281
|
+
if (outcome.kind === "preview")
|
|
282
|
+
return dryRunResponse(outcome.preview);
|
|
283
|
+
return successResponse(outcome.result);
|
|
284
|
+
}
|
|
285
|
+
catch (err) {
|
|
286
|
+
return mapEngagementsError(err);
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
server.registerTool("ttctl_engagements_breaks_remove", {
|
|
290
|
+
title: "Cancel a scheduled break",
|
|
291
|
+
description: [
|
|
292
|
+
"Cancel a previously-scheduled break by its id (the id returned by",
|
|
293
|
+
"`ttctl_engagements_breaks_list`).",
|
|
294
|
+
"",
|
|
295
|
+
"**This is a write operation**: it cancels a scheduled break on the live",
|
|
296
|
+
"Toptal Talent platform. Confirm with the user before invoking.",
|
|
297
|
+
"",
|
|
298
|
+
"Example user prompts:",
|
|
299
|
+
' - "Cancel break br_abc on engagement act_xyz."',
|
|
300
|
+
' - "Remove the scheduled break starting June 1 on my Toptal engagement."',
|
|
301
|
+
].join("\n"),
|
|
302
|
+
inputSchema: {
|
|
303
|
+
breakId: z.string().describe("Engagement break id (the engagementBreak id from `engagements_breaks_list`)"),
|
|
304
|
+
dryRun: DRY_RUN_FIELD,
|
|
305
|
+
},
|
|
306
|
+
}, async (args) => {
|
|
307
|
+
const auth = await ctx.resolveToolAuth();
|
|
308
|
+
if (!auth.ok)
|
|
309
|
+
return auth.response;
|
|
310
|
+
try {
|
|
311
|
+
const outcome = await engagements.breaks.remove(auth.token, args.breakId, { dryRun: args.dryRun ?? false });
|
|
312
|
+
if (outcome.kind === "preview")
|
|
313
|
+
return dryRunResponse(outcome.preview);
|
|
314
|
+
return successResponse(outcome.result);
|
|
315
|
+
}
|
|
316
|
+
catch (err) {
|
|
317
|
+
return mapEngagementsError(err);
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
server.registerTool("ttctl_engagements_breaks_reschedule", {
|
|
321
|
+
title: "Reschedule a scheduled break to a new date window",
|
|
322
|
+
description: [
|
|
323
|
+
"Move an existing scheduled break to a new date window in-place, without",
|
|
324
|
+
"removing and re-adding it. Preserves the existing break's reason and",
|
|
325
|
+
"comment (the wire mutation only carries the new startDate + endDate).",
|
|
326
|
+
"",
|
|
327
|
+
"Required: `breakId` (the engagementBreak id, from `engagements_breaks_list`),",
|
|
328
|
+
"`startDate` (YYYY-MM-DD), `endDate` (YYYY-MM-DD).",
|
|
329
|
+
"",
|
|
330
|
+
"**This is a write operation**: it changes a scheduled break's dates on the",
|
|
331
|
+
"live Toptal Talent platform. Confirm with the user before invoking.",
|
|
332
|
+
"",
|
|
333
|
+
"Example user prompts:",
|
|
334
|
+
' - "Reschedule break br_abc to July 1 through July 8."',
|
|
335
|
+
' - "Move my scheduled vacation from June 1-8 to June 15-22."',
|
|
336
|
+
' - "Push back the start of my upcoming break by a week."',
|
|
337
|
+
].join("\n"),
|
|
338
|
+
inputSchema: {
|
|
339
|
+
breakId: z.string().describe("Engagement break id (the engagementBreak id from `engagements_breaks_list`)"),
|
|
340
|
+
startDate: z.string().describe("New break start date (YYYY-MM-DD)"),
|
|
341
|
+
endDate: z.string().describe("New break end date (YYYY-MM-DD)"),
|
|
342
|
+
dryRun: DRY_RUN_FIELD,
|
|
343
|
+
},
|
|
344
|
+
}, async (args) => {
|
|
345
|
+
const auth = await ctx.resolveToolAuth();
|
|
346
|
+
if (!auth.ok)
|
|
347
|
+
return auth.response;
|
|
348
|
+
try {
|
|
349
|
+
const outcome = await engagements.breaks.reschedule(auth.token, args.breakId, { startDate: args.startDate, endDate: args.endDate }, { 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 mapEngagementsError(err);
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
function successResponse(data) {
|
|
360
|
+
return {
|
|
361
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
function mapEngagementsError(err) {
|
|
365
|
+
const typed = ttctlErrorToToolResponseOrNull(err);
|
|
366
|
+
if (typed !== null)
|
|
367
|
+
return typed;
|
|
368
|
+
if (err instanceof engagements.EngagementsError) {
|
|
369
|
+
return {
|
|
370
|
+
isError: true,
|
|
371
|
+
content: [
|
|
372
|
+
{
|
|
373
|
+
type: "text",
|
|
374
|
+
text: [`Error: ${err.message}`, "", recoveryForCode(err.code), "", `(Code: ${err.code})`].join("\n"),
|
|
375
|
+
},
|
|
376
|
+
],
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
380
|
+
return {
|
|
381
|
+
isError: true,
|
|
382
|
+
content: [
|
|
383
|
+
{
|
|
384
|
+
type: "text",
|
|
385
|
+
text: [
|
|
386
|
+
`Error: engagements request failed: ${message}`,
|
|
387
|
+
"",
|
|
388
|
+
"Recovery: Retry; if the failure persists, file an issue.",
|
|
389
|
+
"",
|
|
390
|
+
"(Code: UNKNOWN)",
|
|
391
|
+
].join("\n"),
|
|
392
|
+
},
|
|
393
|
+
],
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
function recoveryForCode(code) {
|
|
397
|
+
switch (code) {
|
|
398
|
+
case "NOT_FOUND":
|
|
399
|
+
return "Recovery: Verify the engagement id (use `ttctl_engagements_list` to discover it).";
|
|
400
|
+
case "NO_ENGAGEMENT":
|
|
401
|
+
return "Recovery: This activity item is not an engagement (likely an application or interview). Use `ttctl_applications_show` instead.";
|
|
402
|
+
case "MUTATION_ERROR":
|
|
403
|
+
return "Recovery: The mutation was rejected by the server (often: overlapping break dates or validation). Check the message above and adjust the input.";
|
|
404
|
+
default:
|
|
405
|
+
return "Recovery: Adjust the tool input or retry; see the code below.";
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
//# sourceMappingURL=engagements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engagements.js","sourceRoot":"","sources":["../../src/tools/engagements.ts"],"names":[],"mappings":"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"}
|