@ttctl/mcp 0.0.0 → 0.1.0-rc.1
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 +131 -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 +115 -0
- package/dist/tools/output-schemas.d.ts.map +1 -0
- package/dist/tools/output-schemas.js +130 -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 +193 -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 +196 -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 +228 -0
- package/dist/tools/profile/employment.js.map +1 -0
- package/dist/tools/profile/industries.d.ts +22 -0
- package/dist/tools/profile/industries.d.ts.map +1 -0
- package/dist/tools/profile/industries.js +168 -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 +19 -0
- package/dist/tools/profile_basic_show.d.ts.map +1 -0
- package/dist/tools/profile_basic_show.js +64 -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_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,79 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { profile } from "@ttctl/core";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { ttctlErrorToToolResponseOrNull } from "../errors.js";
|
|
6
|
+
import { buildMcpDryRunPreview, domainErrorResponse, dryRunResponse, genericErrorResponse, isToolErrorResponse, jsonResponse, } from "./_shared.js";
|
|
7
|
+
const TOOL_NAME = "ttctl_profile_external_update";
|
|
8
|
+
const DRY_RUN_FIELD = z
|
|
9
|
+
.boolean()
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("Preview the request without executing. Returns `{ ok: true, dryRun: true, preview }` with operationName + variables + redacted bearer header. Default: false.");
|
|
12
|
+
/**
|
|
13
|
+
* Register the `ttctl_profile_external_update` MCP tool. Mirrors the
|
|
14
|
+
* `ttctl profile external update` CLI leaf — sets one or more external
|
|
15
|
+
* profile URLs (LinkedIn, GitHub, website, Twitter, Behance, Dribbble) on
|
|
16
|
+
* the signed-in talent's profile.
|
|
17
|
+
*
|
|
18
|
+
* Each URL field is independently optional; at least one must be supplied.
|
|
19
|
+
* The schema's `--portfolio-url` from issue #76 is intentionally absent —
|
|
20
|
+
* see the service module top-comment for the spec/API reconciliation.
|
|
21
|
+
*/
|
|
22
|
+
export function registerProfileExternalUpdateTool(server, ctx) {
|
|
23
|
+
server.registerTool(TOOL_NAME, {
|
|
24
|
+
title: "Update external profile URLs",
|
|
25
|
+
description: [
|
|
26
|
+
"Set one or more external profile URLs (LinkedIn, GitHub, website, Twitter, Behance, Dribbble) on the signed-in talent's profile. At least one field must be provided.",
|
|
27
|
+
"",
|
|
28
|
+
"Example user prompts that should map to this tool:",
|
|
29
|
+
' - "Update my LinkedIn URL to https://linkedin.com/in/janedoe."',
|
|
30
|
+
' - "Set my GitHub and personal website."',
|
|
31
|
+
' - "Add my Behance and Dribbble profiles to my Toptal page."',
|
|
32
|
+
].join("\n"),
|
|
33
|
+
inputSchema: {
|
|
34
|
+
linkedin: z.url().optional().describe("LinkedIn profile URL"),
|
|
35
|
+
github: z.url().optional().describe("GitHub profile URL"),
|
|
36
|
+
website: z.url().optional().describe("Personal website URL"),
|
|
37
|
+
twitter: z.url().optional().describe("Twitter / X profile URL"),
|
|
38
|
+
behance: z.url().optional().describe("Behance profile URL"),
|
|
39
|
+
dribbble: z.url().optional().describe("Dribbble profile URL"),
|
|
40
|
+
dryRun: DRY_RUN_FIELD,
|
|
41
|
+
},
|
|
42
|
+
}, async (input) => {
|
|
43
|
+
const auth = await ctx.loadTokenForTool(TOOL_NAME);
|
|
44
|
+
if (isToolErrorResponse(auth))
|
|
45
|
+
return auth;
|
|
46
|
+
const changes = {};
|
|
47
|
+
if (input.linkedin !== undefined)
|
|
48
|
+
changes.linkedin = input.linkedin;
|
|
49
|
+
if (input.github !== undefined)
|
|
50
|
+
changes.github = input.github;
|
|
51
|
+
if (input.website !== undefined)
|
|
52
|
+
changes.website = input.website;
|
|
53
|
+
if (input.twitter !== undefined)
|
|
54
|
+
changes.twitter = input.twitter;
|
|
55
|
+
if (input.behance !== undefined)
|
|
56
|
+
changes.behance = input.behance;
|
|
57
|
+
if (input.dribbble !== undefined)
|
|
58
|
+
changes.dribbble = input.dribbble;
|
|
59
|
+
if (input.dryRun === true) {
|
|
60
|
+
return dryRunResponse(buildMcpDryRunPreview("UpdateExternalProfiles", "talent-profile", {
|
|
61
|
+
input: { profileId: profile.basic.DRY_RUN_PROFILE_ID_PLACEHOLDER, externalProfiles: changes },
|
|
62
|
+
}, auth.token));
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const result = await profile.external.update(auth.token, changes);
|
|
66
|
+
return jsonResponse(result);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
const typed = ttctlErrorToToolResponseOrNull(err);
|
|
70
|
+
if (typed !== null)
|
|
71
|
+
return typed;
|
|
72
|
+
if (err instanceof profile.external.ProfileError) {
|
|
73
|
+
return domainErrorResponse(TOOL_NAME, err);
|
|
74
|
+
}
|
|
75
|
+
return genericErrorResponse(TOOL_NAME, err);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=profile_external_update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_external_update.js","sourceRoot":"","sources":["../../src/tools/profile_external_update.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type ToolRegistrationContext } from "./_shared.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register the `ttctl_profile_reviews_approve_item` MCP tool. Mirrors the
|
|
5
|
+
* `ttctl profile reviews approve-item` CLI leaf — approves a single
|
|
6
|
+
* pending item within a section review.
|
|
7
|
+
*
|
|
8
|
+
* The issue's single-positional `<id>` shorthand is replaced by named
|
|
9
|
+
* inputs because the underlying API requires three fields (`reviewId`,
|
|
10
|
+
* `itemId`, `itemKind`) to identify an item. Run
|
|
11
|
+
* `ttctl_profile_reviews_list` first to obtain the three required values.
|
|
12
|
+
*
|
|
13
|
+
* **Destructive**: approval is final per platform semantics. No `--dry-run`
|
|
14
|
+
* gate at v0; that lands separately (see issue #52).
|
|
15
|
+
*/
|
|
16
|
+
export declare function registerProfileReviewsApproveItemTool(server: McpServer, ctx: ToolRegistrationContext): void;
|
|
17
|
+
//# sourceMappingURL=profile_reviews_approve_item.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_reviews_approve_item.d.ts","sourceRoot":"","sources":["../../src/tools/profile_reviews_approve_item.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,OAAO,EAOL,KAAK,uBAAuB,EAC7B,MAAM,cAAc,CAAC;AAWtB;;;;;;;;;;;;GAYG;AACH,wBAAgB,qCAAqC,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,uBAAuB,GAAG,IAAI,CA6D3G"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { profile } from "@ttctl/core";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { ttctlErrorToToolResponseOrNull } from "../errors.js";
|
|
6
|
+
import { buildMcpDryRunPreview, domainErrorResponse, dryRunResponse, genericErrorResponse, isToolErrorResponse, jsonResponse, } from "./_shared.js";
|
|
7
|
+
const TOOL_NAME = "ttctl_profile_reviews_approve_item";
|
|
8
|
+
const DRY_RUN_FIELD = z
|
|
9
|
+
.boolean()
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("Preview the request without executing. Returns `{ ok: true, dryRun: true, preview }` with operationName + variables + redacted bearer header. Useful for inspecting destructive approval shape before firing. Default: false.");
|
|
12
|
+
/**
|
|
13
|
+
* Register the `ttctl_profile_reviews_approve_item` MCP tool. Mirrors the
|
|
14
|
+
* `ttctl profile reviews approve-item` CLI leaf — approves a single
|
|
15
|
+
* pending item within a section review.
|
|
16
|
+
*
|
|
17
|
+
* The issue's single-positional `<id>` shorthand is replaced by named
|
|
18
|
+
* inputs because the underlying API requires three fields (`reviewId`,
|
|
19
|
+
* `itemId`, `itemKind`) to identify an item. Run
|
|
20
|
+
* `ttctl_profile_reviews_list` first to obtain the three required values.
|
|
21
|
+
*
|
|
22
|
+
* **Destructive**: approval is final per platform semantics. No `--dry-run`
|
|
23
|
+
* gate at v0; that lands separately (see issue #52).
|
|
24
|
+
*/
|
|
25
|
+
export function registerProfileReviewsApproveItemTool(server, ctx) {
|
|
26
|
+
server.registerTool(TOOL_NAME, {
|
|
27
|
+
title: "Approve a pending review item",
|
|
28
|
+
description: [
|
|
29
|
+
"Approve a single pending item within a section review. DESTRUCTIVE: approval is final per platform semantics. Run `ttctl_profile_reviews_list` first to obtain the three required IDs.",
|
|
30
|
+
"",
|
|
31
|
+
"Example user prompts that should map to this tool:",
|
|
32
|
+
' - "Approve the suggested change to my education section item."',
|
|
33
|
+
' - "Accept the pending edit on my employment item."',
|
|
34
|
+
' - "Approve item ID xyz in review abc."',
|
|
35
|
+
].join("\n"),
|
|
36
|
+
inputSchema: {
|
|
37
|
+
reviewId: z
|
|
38
|
+
.string()
|
|
39
|
+
.min(1)
|
|
40
|
+
.describe("Section-review ID. Source: `ttctl_profile_reviews_list` row's `id` field."),
|
|
41
|
+
itemId: z
|
|
42
|
+
.string()
|
|
43
|
+
.min(1)
|
|
44
|
+
.describe("Section-review-item ID. Source: `ttctl_profile_reviews_list` row's `items[].id` field."),
|
|
45
|
+
kind: z
|
|
46
|
+
.string()
|
|
47
|
+
.min(1)
|
|
48
|
+
.describe("ItemReviewKind enum value as a string (e.g. EDUCATION, EMPLOYMENT, CERTIFICATION)."),
|
|
49
|
+
dryRun: DRY_RUN_FIELD,
|
|
50
|
+
},
|
|
51
|
+
}, async (input) => {
|
|
52
|
+
const auth = await ctx.loadTokenForTool(TOOL_NAME);
|
|
53
|
+
if (isToolErrorResponse(auth))
|
|
54
|
+
return auth;
|
|
55
|
+
if (input.dryRun === true) {
|
|
56
|
+
return dryRunResponse(buildMcpDryRunPreview("ApproveItemReview", "talent-profile", { input: { reviewId: input.reviewId, itemId: input.itemId, itemKind: input.kind } }, auth.token));
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
const result = await profile.reviews.approveItem(auth.token, {
|
|
60
|
+
reviewId: input.reviewId,
|
|
61
|
+
itemId: input.itemId,
|
|
62
|
+
itemKind: input.kind,
|
|
63
|
+
});
|
|
64
|
+
return jsonResponse(result);
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
const typed = ttctlErrorToToolResponseOrNull(err);
|
|
68
|
+
if (typed !== null)
|
|
69
|
+
return typed;
|
|
70
|
+
if (err instanceof profile.reviews.ProfileError) {
|
|
71
|
+
return domainErrorResponse(TOOL_NAME, err);
|
|
72
|
+
}
|
|
73
|
+
return genericErrorResponse(TOOL_NAME, err);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=profile_reviews_approve_item.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_reviews_approve_item.js","sourceRoot":"","sources":["../../src/tools/profile_reviews_approve_item.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,GAEb,MAAM,cAAc,CAAC;AAEtB,MAAM,SAAS,GAAG,oCAAoC,CAAC;AAEvD,MAAM,aAAa,GAAG,CAAC;KACpB,OAAO,EAAE;KACT,QAAQ,EAAE;KACV,QAAQ,CACP,+NAA+N,CAChO,CAAC;AAEJ;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qCAAqC,CAAC,MAAiB,EAAE,GAA4B;IACnG,MAAM,CAAC,YAAY,CACjB,SAAS,EACT;QACE,KAAK,EAAE,+BAA+B;QACtC,WAAW,EAAE;YACX,wLAAwL;YACxL,EAAE;YACF,oDAAoD;YACpD,kEAAkE;YAClE,sDAAsD;YACtD,0CAA0C;SAC3C,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE;YACX,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,2EAA2E,CAAC;YACxF,MAAM,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,wFAAwF,CAAC;YACrG,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,oFAAoF,CAAC;YACjG,MAAM,EAAE,aAAa;SACtB;KACF,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,mBAAmB,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAE3C,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,cAAc,CACnB,qBAAqB,CACnB,mBAAmB,EACnB,gBAAgB,EAChB,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,EACnF,IAAI,CAAC,KAAK,CACX,CACF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE;gBAC3D,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,QAAQ,EAAE,KAAK,CAAC,IAAI;aACrB,CAAC,CAAC;YACH,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,8BAA8B,CAAC,GAAG,CAAC,CAAC;YAClD,IAAI,KAAK,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YACjC,IAAI,GAAG,YAAY,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;gBAChD,OAAO,mBAAmB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YAC7C,CAAC;YACD,OAAO,oBAAoB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type ToolRegistrationContext } from "./_shared.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register the `ttctl_profile_reviews_approve_section` MCP tool. Mirrors
|
|
5
|
+
* the `ttctl profile reviews approve-section` CLI leaf — approves all
|
|
6
|
+
* pending items within a section review.
|
|
7
|
+
*
|
|
8
|
+
* The issue's single-positional `<id>` shorthand is replaced by named
|
|
9
|
+
* inputs because the API requires both `reviewId` and `section`. Run
|
|
10
|
+
* `ttctl_profile_reviews_list` first to obtain the IDs.
|
|
11
|
+
*
|
|
12
|
+
* **Destructive**: approval is final per platform semantics.
|
|
13
|
+
*/
|
|
14
|
+
export declare function registerProfileReviewsApproveSectionTool(server: McpServer, ctx: ToolRegistrationContext): void;
|
|
15
|
+
//# sourceMappingURL=profile_reviews_approve_section.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_reviews_approve_section.d.ts","sourceRoot":"","sources":["../../src/tools/profile_reviews_approve_section.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,OAAO,EAOL,KAAK,uBAAuB,EAC7B,MAAM,cAAc,CAAC;AAWtB;;;;;;;;;;GAUG;AACH,wBAAgB,wCAAwC,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,uBAAuB,GAAG,IAAI,CAwD9G"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { profile } from "@ttctl/core";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { ttctlErrorToToolResponseOrNull } from "../errors.js";
|
|
6
|
+
import { buildMcpDryRunPreview, domainErrorResponse, dryRunResponse, genericErrorResponse, isToolErrorResponse, jsonResponse, } from "./_shared.js";
|
|
7
|
+
const TOOL_NAME = "ttctl_profile_reviews_approve_section";
|
|
8
|
+
const DRY_RUN_FIELD = z
|
|
9
|
+
.boolean()
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("Preview the request without executing. Returns `{ ok: true, dryRun: true, preview }` with operationName + variables + redacted bearer header. Useful for inspecting destructive approval shape before firing. Default: false.");
|
|
12
|
+
/**
|
|
13
|
+
* Register the `ttctl_profile_reviews_approve_section` MCP tool. Mirrors
|
|
14
|
+
* the `ttctl profile reviews approve-section` CLI leaf — approves all
|
|
15
|
+
* pending items within a section review.
|
|
16
|
+
*
|
|
17
|
+
* The issue's single-positional `<id>` shorthand is replaced by named
|
|
18
|
+
* inputs because the API requires both `reviewId` and `section`. Run
|
|
19
|
+
* `ttctl_profile_reviews_list` first to obtain the IDs.
|
|
20
|
+
*
|
|
21
|
+
* **Destructive**: approval is final per platform semantics.
|
|
22
|
+
*/
|
|
23
|
+
export function registerProfileReviewsApproveSectionTool(server, ctx) {
|
|
24
|
+
server.registerTool(TOOL_NAME, {
|
|
25
|
+
title: "Approve all pending items in a section",
|
|
26
|
+
description: [
|
|
27
|
+
"Approve all pending items within a section review. DESTRUCTIVE: approval is final per platform semantics. Run `ttctl_profile_reviews_list` first to obtain the section ID.",
|
|
28
|
+
"",
|
|
29
|
+
"Example user prompts that should map to this tool:",
|
|
30
|
+
' - "Approve all the suggested changes to my skills section."',
|
|
31
|
+
' - "Accept all pending edits in my employment section."',
|
|
32
|
+
' - "Approve everything in section EDUCATION."',
|
|
33
|
+
].join("\n"),
|
|
34
|
+
inputSchema: {
|
|
35
|
+
reviewId: z
|
|
36
|
+
.string()
|
|
37
|
+
.min(1)
|
|
38
|
+
.describe("Section-review ID. Source: `ttctl_profile_reviews_list` row's `id` field."),
|
|
39
|
+
section: z
|
|
40
|
+
.string()
|
|
41
|
+
.min(1)
|
|
42
|
+
.describe("ReviewSection enum value as a string (e.g. EDUCATION, EMPLOYMENT, SKILLS)."),
|
|
43
|
+
dryRun: DRY_RUN_FIELD,
|
|
44
|
+
},
|
|
45
|
+
}, async (input) => {
|
|
46
|
+
const auth = await ctx.loadTokenForTool(TOOL_NAME);
|
|
47
|
+
if (isToolErrorResponse(auth))
|
|
48
|
+
return auth;
|
|
49
|
+
if (input.dryRun === true) {
|
|
50
|
+
return dryRunResponse(buildMcpDryRunPreview("ApproveSectionReview", "talent-profile", { input: { reviewId: input.reviewId, section: input.section } }, auth.token));
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const result = await profile.reviews.approveSection(auth.token, {
|
|
54
|
+
reviewId: input.reviewId,
|
|
55
|
+
section: input.section,
|
|
56
|
+
});
|
|
57
|
+
return jsonResponse(result);
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
const typed = ttctlErrorToToolResponseOrNull(err);
|
|
61
|
+
if (typed !== null)
|
|
62
|
+
return typed;
|
|
63
|
+
if (err instanceof profile.reviews.ProfileError) {
|
|
64
|
+
return domainErrorResponse(TOOL_NAME, err);
|
|
65
|
+
}
|
|
66
|
+
return genericErrorResponse(TOOL_NAME, err);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=profile_reviews_approve_section.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_reviews_approve_section.js","sourceRoot":"","sources":["../../src/tools/profile_reviews_approve_section.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,GAEb,MAAM,cAAc,CAAC;AAEtB,MAAM,SAAS,GAAG,uCAAuC,CAAC;AAE1D,MAAM,aAAa,GAAG,CAAC;KACpB,OAAO,EAAE;KACT,QAAQ,EAAE;KACV,QAAQ,CACP,+NAA+N,CAChO,CAAC;AAEJ;;;;;;;;;;GAUG;AACH,MAAM,UAAU,wCAAwC,CAAC,MAAiB,EAAE,GAA4B;IACtG,MAAM,CAAC,YAAY,CACjB,SAAS,EACT;QACE,KAAK,EAAE,wCAAwC;QAC/C,WAAW,EAAE;YACX,4KAA4K;YAC5K,EAAE;YACF,oDAAoD;YACpD,+DAA+D;YAC/D,0DAA0D;YAC1D,gDAAgD;SACjD,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE;YACX,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,2EAA2E,CAAC;YACxF,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,4EAA4E,CAAC;YACzF,MAAM,EAAE,aAAa;SACtB;KACF,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,mBAAmB,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAE3C,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,cAAc,CACnB,qBAAqB,CACnB,sBAAsB,EACtB,gBAAgB,EAChB,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,EAC/D,IAAI,CAAC,KAAK,CACX,CACF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE;gBAC9D,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,OAAO,EAAE,KAAK,CAAC,OAAO;aACvB,CAAC,CAAC;YACH,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,8BAA8B,CAAC,GAAG,CAAC,CAAC;YAClD,IAAI,KAAK,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YACjC,IAAI,GAAG,YAAY,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;gBAChD,OAAO,mBAAmB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YAC7C,CAAC;YACD,OAAO,oBAAoB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type ToolRegistrationContext } from "./_shared.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register the `ttctl_profile_reviews_list` MCP tool. Mirrors the
|
|
5
|
+
* `ttctl profile reviews list` CLI leaf — lists pending section reviews
|
|
6
|
+
* for the signed-in talent.
|
|
7
|
+
*
|
|
8
|
+
* Each row carries the section-review ID (passed to
|
|
9
|
+
* `ttctl_profile_reviews_approve_section`) plus an `items` array; each
|
|
10
|
+
* item carries its own ID (passed to
|
|
11
|
+
* `ttctl_profile_reviews_approve_item`) and the underlying entity ID.
|
|
12
|
+
* Use this tool first before invoking the approval tools to obtain the
|
|
13
|
+
* required IDs.
|
|
14
|
+
*/
|
|
15
|
+
export declare function registerProfileReviewsListTool(server: McpServer, ctx: ToolRegistrationContext): void;
|
|
16
|
+
//# sourceMappingURL=profile_reviews_list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_reviews_list.d.ts","sourceRoot":"","sources":["../../src/tools/profile_reviews_list.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,OAAO,EAOL,KAAK,uBAAuB,EAC7B,MAAM,cAAc,CAAC;AAWtB;;;;;;;;;;;GAWG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,uBAAuB,GAAG,IAAI,CA2CpG"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { profile } from "@ttctl/core";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { ttctlErrorToToolResponseOrNull } from "../errors.js";
|
|
6
|
+
import { buildMcpDryRunPreview, domainErrorResponse, dryRunResponse, genericErrorResponse, isToolErrorResponse, jsonResponse, } from "./_shared.js";
|
|
7
|
+
const TOOL_NAME = "ttctl_profile_reviews_list";
|
|
8
|
+
const DRY_RUN_FIELD = z
|
|
9
|
+
.boolean()
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("Preview the request without executing. Returns `{ ok: true, dryRun: true, preview }` with operationName + variables + redacted bearer header. Default: false.");
|
|
12
|
+
/**
|
|
13
|
+
* Register the `ttctl_profile_reviews_list` MCP tool. Mirrors the
|
|
14
|
+
* `ttctl profile reviews list` CLI leaf — lists pending section reviews
|
|
15
|
+
* for the signed-in talent.
|
|
16
|
+
*
|
|
17
|
+
* Each row carries the section-review ID (passed to
|
|
18
|
+
* `ttctl_profile_reviews_approve_section`) plus an `items` array; each
|
|
19
|
+
* item carries its own ID (passed to
|
|
20
|
+
* `ttctl_profile_reviews_approve_item`) and the underlying entity ID.
|
|
21
|
+
* Use this tool first before invoking the approval tools to obtain the
|
|
22
|
+
* required IDs.
|
|
23
|
+
*/
|
|
24
|
+
export function registerProfileReviewsListTool(server, ctx) {
|
|
25
|
+
server.registerTool(TOOL_NAME, {
|
|
26
|
+
title: "List pending section reviews",
|
|
27
|
+
description: [
|
|
28
|
+
"List pending section reviews for the signed-in talent. Each row carries the section-review ID, section name, requestedAt timestamp, and an `items` array (each with its own id, itemId, requestedAt). Returns an empty array when no reviews are pending.",
|
|
29
|
+
"",
|
|
30
|
+
"Example user prompts that should map to this tool:",
|
|
31
|
+
' - "What\'s pending review on my profile?"',
|
|
32
|
+
' - "Show me my section reviews."',
|
|
33
|
+
' - "Are there any unapproved changes on my profile?"',
|
|
34
|
+
].join("\n"),
|
|
35
|
+
inputSchema: { dryRun: DRY_RUN_FIELD },
|
|
36
|
+
}, async (input) => {
|
|
37
|
+
const auth = await ctx.loadTokenForTool(TOOL_NAME);
|
|
38
|
+
if (isToolErrorResponse(auth))
|
|
39
|
+
return auth;
|
|
40
|
+
if (input.dryRun === true) {
|
|
41
|
+
return dryRunResponse(buildMcpDryRunPreview("sectionReviews", "talent-profile", { profileId: profile.basic.DRY_RUN_PROFILE_ID_PLACEHOLDER }, auth.token));
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const result = await profile.reviews.list(auth.token);
|
|
45
|
+
return jsonResponse(result);
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
const typed = ttctlErrorToToolResponseOrNull(err);
|
|
49
|
+
if (typed !== null)
|
|
50
|
+
return typed;
|
|
51
|
+
if (err instanceof profile.reviews.ProfileError) {
|
|
52
|
+
return domainErrorResponse(TOOL_NAME, err);
|
|
53
|
+
}
|
|
54
|
+
return genericErrorResponse(TOOL_NAME, err);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=profile_reviews_list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_reviews_list.js","sourceRoot":"","sources":["../../src/tools/profile_reviews_list.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,GAEb,MAAM,cAAc,CAAC;AAEtB,MAAM,SAAS,GAAG,4BAA4B,CAAC;AAE/C,MAAM,aAAa,GAAG,CAAC;KACpB,OAAO,EAAE;KACT,QAAQ,EAAE;KACV,QAAQ,CACP,+JAA+J,CAChK,CAAC;AAEJ;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,8BAA8B,CAAC,MAAiB,EAAE,GAA4B;IAC5F,MAAM,CAAC,YAAY,CACjB,SAAS,EACT;QACE,KAAK,EAAE,8BAA8B;QACrC,WAAW,EAAE;YACX,2PAA2P;YAC3P,EAAE;YACF,oDAAoD;YACpD,6CAA6C;YAC7C,mCAAmC;YACnC,uDAAuD;SACxD,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE;KACvC,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,mBAAmB,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAE3C,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,cAAc,CACnB,qBAAqB,CACnB,gBAAgB,EAChB,gBAAgB,EAChB,EAAE,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,EAC3D,IAAI,CAAC,KAAK,CACX,CACF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtD,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,8BAA8B,CAAC,GAAG,CAAC,CAAC;YAClD,IAAI,KAAK,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YACjC,IAAI,GAAG,YAAY,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;gBAChD,OAAO,mBAAmB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YAC7C,CAAC;YACD,OAAO,oBAAoB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type ToolRegistrationContext } from "./_shared.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register the `ttctl_profile_reviews_submit_for_review` MCP tool.
|
|
5
|
+
* Mirrors the `ttctl profile reviews submit-for-review` CLI leaf — re-
|
|
6
|
+
* submits the talent's profile for platform-side re-review.
|
|
7
|
+
*
|
|
8
|
+
* The platform may reject if the profile is not yet ready (cross-check
|
|
9
|
+
* via `ttctl_profile_external_readiness`). The mutation's input shape is
|
|
10
|
+
* **INFERRED — UNVERIFIED** (`{ profileId: ID! }`); deviations would
|
|
11
|
+
* surface as `USER_ERROR` at runtime.
|
|
12
|
+
*/
|
|
13
|
+
export declare function registerProfileReviewsSubmitForReviewTool(server: McpServer, ctx: ToolRegistrationContext): void;
|
|
14
|
+
//# sourceMappingURL=profile_reviews_submit_for_review.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_reviews_submit_for_review.d.ts","sourceRoot":"","sources":["../../src/tools/profile_reviews_submit_for_review.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,OAAO,EAOL,KAAK,uBAAuB,EAC7B,MAAM,cAAc,CAAC;AAWtB;;;;;;;;;GASG;AACH,wBAAgB,yCAAyC,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,uBAAuB,GAAG,IAAI,CA2C/G"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { profile } from "@ttctl/core";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { ttctlErrorToToolResponseOrNull } from "../errors.js";
|
|
6
|
+
import { buildMcpDryRunPreview, domainErrorResponse, dryRunResponse, genericErrorResponse, isToolErrorResponse, jsonResponse, } from "./_shared.js";
|
|
7
|
+
const TOOL_NAME = "ttctl_profile_reviews_submit_for_review";
|
|
8
|
+
const DRY_RUN_FIELD = z
|
|
9
|
+
.boolean()
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("Preview the request without executing. Returns `{ ok: true, dryRun: true, preview }` with operationName + variables + redacted bearer header. Default: false.");
|
|
12
|
+
/**
|
|
13
|
+
* Register the `ttctl_profile_reviews_submit_for_review` MCP tool.
|
|
14
|
+
* Mirrors the `ttctl profile reviews submit-for-review` CLI leaf — re-
|
|
15
|
+
* submits the talent's profile for platform-side re-review.
|
|
16
|
+
*
|
|
17
|
+
* The platform may reject if the profile is not yet ready (cross-check
|
|
18
|
+
* via `ttctl_profile_external_readiness`). The mutation's input shape is
|
|
19
|
+
* **INFERRED — UNVERIFIED** (`{ profileId: ID! }`); deviations would
|
|
20
|
+
* surface as `USER_ERROR` at runtime.
|
|
21
|
+
*/
|
|
22
|
+
export function registerProfileReviewsSubmitForReviewTool(server, ctx) {
|
|
23
|
+
server.registerTool(TOOL_NAME, {
|
|
24
|
+
title: "Submit profile for platform re-review",
|
|
25
|
+
description: [
|
|
26
|
+
"Submit the talent's profile for platform-side re-review. Used after profile edits that need re-verification (skills, employments, etc.). The platform may reject if the profile is not yet ready (use `ttctl_profile_external_readiness` to check first).",
|
|
27
|
+
"",
|
|
28
|
+
"Example user prompts that should map to this tool:",
|
|
29
|
+
' - "Submit my profile for review."',
|
|
30
|
+
' - "Re-submit my Toptal profile after my edits."',
|
|
31
|
+
' - "I\'m done editing — submit for re-review."',
|
|
32
|
+
].join("\n"),
|
|
33
|
+
inputSchema: { dryRun: DRY_RUN_FIELD },
|
|
34
|
+
}, async (input) => {
|
|
35
|
+
const auth = await ctx.loadTokenForTool(TOOL_NAME);
|
|
36
|
+
if (isToolErrorResponse(auth))
|
|
37
|
+
return auth;
|
|
38
|
+
if (input.dryRun === true) {
|
|
39
|
+
return dryRunResponse(buildMcpDryRunPreview("submitForReview", "talent-profile", { input: { profileId: profile.basic.DRY_RUN_PROFILE_ID_PLACEHOLDER } }, auth.token));
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const result = await profile.reviews.submitForReview(auth.token);
|
|
43
|
+
return jsonResponse(result);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
const typed = ttctlErrorToToolResponseOrNull(err);
|
|
47
|
+
if (typed !== null)
|
|
48
|
+
return typed;
|
|
49
|
+
if (err instanceof profile.reviews.ProfileError) {
|
|
50
|
+
return domainErrorResponse(TOOL_NAME, err);
|
|
51
|
+
}
|
|
52
|
+
return genericErrorResponse(TOOL_NAME, err);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=profile_reviews_submit_for_review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_reviews_submit_for_review.js","sourceRoot":"","sources":["../../src/tools/profile_reviews_submit_for_review.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,GAEb,MAAM,cAAc,CAAC;AAEtB,MAAM,SAAS,GAAG,yCAAyC,CAAC;AAE5D,MAAM,aAAa,GAAG,CAAC;KACpB,OAAO,EAAE;KACT,QAAQ,EAAE;KACV,QAAQ,CACP,+JAA+J,CAChK,CAAC;AAEJ;;;;;;;;;GASG;AACH,MAAM,UAAU,yCAAyC,CAAC,MAAiB,EAAE,GAA4B;IACvG,MAAM,CAAC,YAAY,CACjB,SAAS,EACT;QACE,KAAK,EAAE,uCAAuC;QAC9C,WAAW,EAAE;YACX,2PAA2P;YAC3P,EAAE;YACF,oDAAoD;YACpD,qCAAqC;YACrC,mDAAmD;YACnD,iDAAiD;SAClD,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE;KACvC,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,mBAAmB,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAE3C,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,cAAc,CACnB,qBAAqB,CACnB,iBAAiB,EACjB,gBAAgB,EAChB,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,EAAE,EACtE,IAAI,CAAC,KAAK,CACX,CACF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACjE,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,8BAA8B,CAAC,GAAG,CAAC,CAAC;YAClD,IAAI,KAAK,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YACjC,IAAI,GAAG,YAAY,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;gBAChD,OAAO,mBAAmB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YAC7C,CAAC;YACD,OAAO,oBAAoB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type ToolRegistrationContext } from "./_shared.js";
|
|
3
|
+
export declare function registerProfileSkillsAddTool(server: McpServer, ctx: ToolRegistrationContext): void;
|
|
4
|
+
//# sourceMappingURL=profile_skills_add.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_skills_add.d.ts","sourceRoot":"","sources":["../../src/tools/profile_skills_add.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,OAAO,EAOL,KAAK,uBAAuB,EAC7B,MAAM,cAAc,CAAC;AAWtB,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,uBAAuB,GAAG,IAAI,CAmDlG"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { profile } from "@ttctl/core";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { ttctlErrorToToolResponseOrNull } from "../errors.js";
|
|
6
|
+
import { buildMcpDryRunPreview, domainErrorResponse, dryRunResponse, genericErrorResponse, isToolErrorResponse, jsonResponse, } from "./_shared.js";
|
|
7
|
+
const TOOL_NAME = "ttctl_profile_skills_add";
|
|
8
|
+
const DRY_RUN_FIELD = z
|
|
9
|
+
.boolean()
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("Preview the request without executing. Returns `{ ok: true, dryRun: true, preview }` with operationName + variables + redacted bearer header. Default: false.");
|
|
12
|
+
export function registerProfileSkillsAddTool(server, ctx) {
|
|
13
|
+
server.registerTool(TOOL_NAME, {
|
|
14
|
+
title: "Add a skill to profile",
|
|
15
|
+
description: [
|
|
16
|
+
"Add a skill to the signed-in user's profile by its catalog name (e.g., `TypeScript`, `PostgreSQL`).",
|
|
17
|
+
"Returns the new ProfileSkillSet with default rating/experience/visibility — configure those via `ttctl_profile_skills_update`.",
|
|
18
|
+
"",
|
|
19
|
+
"Example user prompts that should map to this tool:",
|
|
20
|
+
' - "Add TypeScript to my Toptal skills."',
|
|
21
|
+
' - "Add PostgreSQL as a skill on my profile."',
|
|
22
|
+
].join("\n"),
|
|
23
|
+
inputSchema: {
|
|
24
|
+
name: z
|
|
25
|
+
.string()
|
|
26
|
+
.min(1)
|
|
27
|
+
.describe('Skill catalog name to add. The server resolves the name to a Skill id; if the name is ambiguous (e.g., "Postgres" vs "PostgreSQL"), use `ttctl_profile_skills_autocomplete` first to disambiguate.'),
|
|
28
|
+
dryRun: DRY_RUN_FIELD,
|
|
29
|
+
},
|
|
30
|
+
}, async (input) => {
|
|
31
|
+
const auth = await ctx.loadTokenForTool(TOOL_NAME);
|
|
32
|
+
if (isToolErrorResponse(auth))
|
|
33
|
+
return auth;
|
|
34
|
+
if (input.dryRun === true) {
|
|
35
|
+
return dryRunResponse(buildMcpDryRunPreview("ADD_PROFILE_SKILL_SET", "talent-profile", { input: { name: input.name.trim() } }, auth.token));
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const result = await profile.skills.add(auth.token, input.name);
|
|
39
|
+
return jsonResponse(result);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
const typed = ttctlErrorToToolResponseOrNull(err);
|
|
43
|
+
if (typed !== null)
|
|
44
|
+
return typed;
|
|
45
|
+
if (err instanceof profile.skills.SkillsError) {
|
|
46
|
+
return domainErrorResponse(TOOL_NAME, err);
|
|
47
|
+
}
|
|
48
|
+
return genericErrorResponse(TOOL_NAME, err);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=profile_skills_add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_skills_add.js","sourceRoot":"","sources":["../../src/tools/profile_skills_add.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,GAEb,MAAM,cAAc,CAAC;AAEtB,MAAM,SAAS,GAAG,0BAA0B,CAAC;AAE7C,MAAM,aAAa,GAAG,CAAC;KACpB,OAAO,EAAE;KACT,QAAQ,EAAE;KACV,QAAQ,CACP,+JAA+J,CAChK,CAAC;AAEJ,MAAM,UAAU,4BAA4B,CAAC,MAAiB,EAAE,GAA4B;IAC1F,MAAM,CAAC,YAAY,CACjB,SAAS,EACT;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EAAE;YACX,qGAAqG;YACrG,gIAAgI;YAChI,EAAE;YACF,oDAAoD;YACpD,2CAA2C;YAC3C,gDAAgD;SACjD,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE;YACX,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CACP,oMAAoM,CACrM;YACH,MAAM,EAAE,aAAa;SACtB;KACF,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,mBAAmB,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAE3C,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,cAAc,CACnB,qBAAqB,CACnB,uBAAuB,EACvB,gBAAgB,EAChB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,EACtC,IAAI,CAAC,KAAK,CACX,CACF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAChE,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,8BAA8B,CAAC,GAAG,CAAC,CAAC;YAClD,IAAI,KAAK,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YACjC,IAAI,GAAG,YAAY,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;gBAC9C,OAAO,mBAAmB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YAC7C,CAAC;YACD,OAAO,oBAAoB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type ToolRegistrationContext } from "./_shared.js";
|
|
3
|
+
export declare function registerProfileSkillsAutocompleteTool(server: McpServer, ctx: ToolRegistrationContext): void;
|
|
4
|
+
//# sourceMappingURL=profile_skills_autocomplete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_skills_autocomplete.d.ts","sourceRoot":"","sources":["../../src/tools/profile_skills_autocomplete.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,OAAO,EAOL,KAAK,uBAAuB,EAC7B,MAAM,cAAc,CAAC;AAWtB,wBAAgB,qCAAqC,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,uBAAuB,GAAG,IAAI,CA2E3G"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { profile } from "@ttctl/core";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { ttctlErrorToToolResponseOrNull } from "../errors.js";
|
|
6
|
+
import { buildMcpDryRunPreview, domainErrorResponse, dryRunResponse, genericErrorResponse, isToolErrorResponse, jsonResponse, } from "./_shared.js";
|
|
7
|
+
const TOOL_NAME = "ttctl_profile_skills_autocomplete";
|
|
8
|
+
const DRY_RUN_FIELD = z
|
|
9
|
+
.boolean()
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("Preview the request without executing. Returns `{ ok: true, dryRun: true, preview }` with operationName + variables + redacted bearer header. Default: false.");
|
|
12
|
+
export function registerProfileSkillsAutocompleteTool(server, ctx) {
|
|
13
|
+
server.registerTool(TOOL_NAME, {
|
|
14
|
+
title: "Search global skill catalog",
|
|
15
|
+
description: [
|
|
16
|
+
"Search the global Toptal skill catalog for entries matching `query` (suitable for disambiguating before calling `ttctl_profile_skills_add`).",
|
|
17
|
+
"Results are scoped to skills the talent's vertical permits and exclude any ids passed in `withoutIds` (e.g., the talent's existing skills).",
|
|
18
|
+
"",
|
|
19
|
+
"Example user prompts that should map to this tool:",
|
|
20
|
+
" - \"Search Toptal's catalog for 'postgres' before I add it.\"",
|
|
21
|
+
" - \"Find skill names matching 'java'.\"",
|
|
22
|
+
].join("\n"),
|
|
23
|
+
inputSchema: {
|
|
24
|
+
query: z.string().min(1).describe("Substring to search for in skill names. Case-insensitive."),
|
|
25
|
+
limit: z
|
|
26
|
+
.number()
|
|
27
|
+
.int()
|
|
28
|
+
.min(1)
|
|
29
|
+
.max(50)
|
|
30
|
+
.optional()
|
|
31
|
+
.describe("Max number of suggestions to return. Defaults to 10. Range: 1-50."),
|
|
32
|
+
withoutIds: z
|
|
33
|
+
.array(z.string().min(1))
|
|
34
|
+
.optional()
|
|
35
|
+
.describe("Skill catalog ids to exclude from the results — typically the talent's existing skill catalog ids so the dropdown doesn't suggest skills already on the profile."),
|
|
36
|
+
dryRun: DRY_RUN_FIELD,
|
|
37
|
+
},
|
|
38
|
+
}, async (input) => {
|
|
39
|
+
const auth = await ctx.loadTokenForTool(TOOL_NAME);
|
|
40
|
+
if (isToolErrorResponse(auth))
|
|
41
|
+
return auth;
|
|
42
|
+
if (input.dryRun === true) {
|
|
43
|
+
return dryRunResponse(buildMcpDryRunPreview("GET_SKILLS_FOR_AUTOCOMPLETE", "talent-profile", {
|
|
44
|
+
profileId: profile.basic.DRY_RUN_PROFILE_ID_PLACEHOLDER,
|
|
45
|
+
search: input.query.trim(),
|
|
46
|
+
limit: input.limit ?? 10,
|
|
47
|
+
withoutIds: input.withoutIds ?? [],
|
|
48
|
+
}, auth.token));
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const profilePayload = await profile.basic.show(auth.token);
|
|
52
|
+
const profileId = profilePayload.viewer?.viewerRole.profileId;
|
|
53
|
+
if (profileId === undefined) {
|
|
54
|
+
return domainErrorResponse(TOOL_NAME, {
|
|
55
|
+
code: "NO_VIEWER",
|
|
56
|
+
message: "No profile id bound to this session.",
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
const options = {};
|
|
60
|
+
if (input.limit !== undefined)
|
|
61
|
+
options.limit = input.limit;
|
|
62
|
+
if (input.withoutIds !== undefined)
|
|
63
|
+
options.withoutIds = input.withoutIds;
|
|
64
|
+
const suggestions = await profile.skills.autocomplete(auth.token, profileId, input.query, options);
|
|
65
|
+
return jsonResponse(suggestions);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
const typed = ttctlErrorToToolResponseOrNull(err);
|
|
69
|
+
if (typed !== null)
|
|
70
|
+
return typed;
|
|
71
|
+
if (err instanceof profile.skills.SkillsError || err instanceof profile.basic.ProfileError) {
|
|
72
|
+
return domainErrorResponse(TOOL_NAME, err);
|
|
73
|
+
}
|
|
74
|
+
return genericErrorResponse(TOOL_NAME, err);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=profile_skills_autocomplete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_skills_autocomplete.js","sourceRoot":"","sources":["../../src/tools/profile_skills_autocomplete.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,GAEb,MAAM,cAAc,CAAC;AAEtB,MAAM,SAAS,GAAG,mCAAmC,CAAC;AAEtD,MAAM,aAAa,GAAG,CAAC;KACpB,OAAO,EAAE;KACT,QAAQ,EAAE;KACV,QAAQ,CACP,+JAA+J,CAChK,CAAC;AAEJ,MAAM,UAAU,qCAAqC,CAAC,MAAiB,EAAE,GAA4B;IACnG,MAAM,CAAC,YAAY,CACjB,SAAS,EACT;QACE,KAAK,EAAE,6BAA6B;QACpC,WAAW,EAAE;YACX,8IAA8I;YAC9I,6IAA6I;YAC7I,EAAE;YACF,oDAAoD;YACpD,iEAAiE;YACjE,2CAA2C;SAC5C,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,2DAA2D,CAAC;YAC9F,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,EAAE,CAAC;iBACP,QAAQ,EAAE;iBACV,QAAQ,CAAC,mEAAmE,CAAC;YAChF,UAAU,EAAE,CAAC;iBACV,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;iBACxB,QAAQ,EAAE;iBACV,QAAQ,CACP,kKAAkK,CACnK;YACH,MAAM,EAAE,aAAa;SACtB;KACF,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,mBAAmB,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAE3C,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,cAAc,CACnB,qBAAqB,CACnB,6BAA6B,EAC7B,gBAAgB,EAChB;gBACE,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,8BAA8B;gBACvD,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC1B,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;gBACxB,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,EAAE;aACnC,EACD,IAAI,CAAC,KAAK,CACX,CACF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5D,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,EAAE,UAAU,CAAC,SAAS,CAAC;YAC9D,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,OAAO,mBAAmB,CAAC,SAAS,EAAE;oBACpC,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,sCAAsC;iBAChD,CAAC,CAAC;YACL,CAAC;YACD,MAAM,OAAO,GAA8C,EAAE,CAAC;YAC9D,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;gBAAE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;YAC3D,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;gBAAE,OAAO,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;YAC1E,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACnG,OAAO,YAAY,CAAC,WAAW,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,8BAA8B,CAAC,GAAG,CAAC,CAAC;YAClD,IAAI,KAAK,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YACjC,IAAI,GAAG,YAAY,OAAO,CAAC,MAAM,CAAC,WAAW,IAAI,GAAG,YAAY,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;gBAC3F,OAAO,mBAAmB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YAC7C,CAAC;YACD,OAAO,oBAAoB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|