@topolo/mcp 0.6.0 → 0.7.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 +70 -26
- package/dist/dispatch.js +144 -106
- package/dist/http.js +152 -114
- package/dist/index.js +417 -167
- package/package.json +9 -2
package/dist/http.js
CHANGED
|
@@ -3098,9 +3098,9 @@ var require_data = __commonJS({
|
|
|
3098
3098
|
}
|
|
3099
3099
|
});
|
|
3100
3100
|
|
|
3101
|
-
// ../../node_modules/.pnpm/fast-uri@3.1.
|
|
3101
|
+
// ../../node_modules/.pnpm/fast-uri@3.1.3/node_modules/fast-uri/lib/utils.js
|
|
3102
3102
|
var require_utils = __commonJS({
|
|
3103
|
-
"../../node_modules/.pnpm/fast-uri@3.1.
|
|
3103
|
+
"../../node_modules/.pnpm/fast-uri@3.1.3/node_modules/fast-uri/lib/utils.js"(exports, module) {
|
|
3104
3104
|
"use strict";
|
|
3105
3105
|
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
3106
3106
|
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
@@ -3411,9 +3411,9 @@ var require_utils = __commonJS({
|
|
|
3411
3411
|
}
|
|
3412
3412
|
});
|
|
3413
3413
|
|
|
3414
|
-
// ../../node_modules/.pnpm/fast-uri@3.1.
|
|
3414
|
+
// ../../node_modules/.pnpm/fast-uri@3.1.3/node_modules/fast-uri/lib/schemes.js
|
|
3415
3415
|
var require_schemes = __commonJS({
|
|
3416
|
-
"../../node_modules/.pnpm/fast-uri@3.1.
|
|
3416
|
+
"../../node_modules/.pnpm/fast-uri@3.1.3/node_modules/fast-uri/lib/schemes.js"(exports, module) {
|
|
3417
3417
|
"use strict";
|
|
3418
3418
|
var { isUUID } = require_utils();
|
|
3419
3419
|
var URN_REG = /([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-.:;=@]|%[\da-f]{2})+)/iu;
|
|
@@ -3621,9 +3621,9 @@ var require_schemes = __commonJS({
|
|
|
3621
3621
|
}
|
|
3622
3622
|
});
|
|
3623
3623
|
|
|
3624
|
-
// ../../node_modules/.pnpm/fast-uri@3.1.
|
|
3624
|
+
// ../../node_modules/.pnpm/fast-uri@3.1.3/node_modules/fast-uri/index.js
|
|
3625
3625
|
var require_fast_uri = __commonJS({
|
|
3626
|
-
"../../node_modules/.pnpm/fast-uri@3.1.
|
|
3626
|
+
"../../node_modules/.pnpm/fast-uri@3.1.3/node_modules/fast-uri/index.js"(exports, module) {
|
|
3627
3627
|
"use strict";
|
|
3628
3628
|
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
3629
3629
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
@@ -3836,7 +3836,7 @@ var require_fast_uri = __commonJS({
|
|
|
3836
3836
|
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
|
|
3837
3837
|
if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
|
|
3838
3838
|
try {
|
|
3839
|
-
parsed.host = URL
|
|
3839
|
+
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
3840
3840
|
} catch (e) {
|
|
3841
3841
|
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
3842
3842
|
}
|
|
@@ -15861,6 +15861,15 @@ function splitService(servicePart) {
|
|
|
15861
15861
|
// src/tools.ts
|
|
15862
15862
|
var APPLICATION_IDS = Object.keys(APPLICATIONS).sort();
|
|
15863
15863
|
var HTTP_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
|
|
15864
|
+
function optionalResourceContext(args) {
|
|
15865
|
+
const resourceType = typeof args["resourceType"] === "string" ? args["resourceType"].trim() : "";
|
|
15866
|
+
const resourceId = typeof args["resourceId"] === "string" ? args["resourceId"].trim() : "";
|
|
15867
|
+
if (!resourceType && !resourceId) return void 0;
|
|
15868
|
+
if (!resourceType || !resourceId) {
|
|
15869
|
+
throw new Error("resourceType and resourceId must be provided together.");
|
|
15870
|
+
}
|
|
15871
|
+
return { resourceType, resourceId };
|
|
15872
|
+
}
|
|
15864
15873
|
var TOOLS = [
|
|
15865
15874
|
{
|
|
15866
15875
|
name: "topolo_whoami",
|
|
@@ -15876,22 +15885,32 @@ var TOOLS = [
|
|
|
15876
15885
|
handler: async (topolo) => topolo.identity.whoami()
|
|
15877
15886
|
},
|
|
15878
15887
|
{
|
|
15879
|
-
name: "
|
|
15880
|
-
title: "
|
|
15881
|
-
description: "
|
|
15888
|
+
name: "topolo_search_applications",
|
|
15889
|
+
title: "Search Topolo applications the agent can reach",
|
|
15890
|
+
description: "Searches the credential-scoped application registry with a bounded page and continuation cursor. Returns actionService as the canonical selector for topolo_search_actions, plus granted permissions, API URL, and launch URL without loading the global platform catalog.",
|
|
15882
15891
|
requiredScopes: [],
|
|
15883
15892
|
destructive: false,
|
|
15884
15893
|
inputSchema: {
|
|
15885
15894
|
type: "object",
|
|
15886
|
-
properties: {
|
|
15895
|
+
properties: {
|
|
15896
|
+
query: { type: "string" },
|
|
15897
|
+
cursor: { type: "string" },
|
|
15898
|
+
limit: { type: "integer", minimum: 1, maximum: 100, default: 25 }
|
|
15899
|
+
},
|
|
15887
15900
|
additionalProperties: false
|
|
15888
15901
|
},
|
|
15889
|
-
handler: async (topolo) => {
|
|
15890
|
-
const
|
|
15902
|
+
handler: async (topolo, args) => {
|
|
15903
|
+
const result = await topolo.client.searchServices({
|
|
15904
|
+
query: typeof args["query"] === "string" ? args["query"] : void 0,
|
|
15905
|
+
cursor: typeof args["cursor"] === "string" ? args["cursor"] : void 0,
|
|
15906
|
+
limit: typeof args["limit"] === "number" ? args["limit"] : void 0
|
|
15907
|
+
});
|
|
15908
|
+
const applications = result.services.map((entry) => {
|
|
15891
15909
|
const id = displayAppId(entry);
|
|
15892
15910
|
return {
|
|
15893
15911
|
id,
|
|
15894
15912
|
appId: entry.appId,
|
|
15913
|
+
actionService: entry.appId,
|
|
15895
15914
|
slug: entry.slug,
|
|
15896
15915
|
name: entry.name,
|
|
15897
15916
|
apiBaseUrl: entry.apiBaseUrl,
|
|
@@ -15904,13 +15923,13 @@ var TOOLS = [
|
|
|
15904
15923
|
permissions: [...entry.permissions]
|
|
15905
15924
|
};
|
|
15906
15925
|
}).sort((left, right) => left.id.localeCompare(right.id));
|
|
15907
|
-
return {
|
|
15926
|
+
return { applications, page: result.page };
|
|
15908
15927
|
}
|
|
15909
15928
|
},
|
|
15910
15929
|
{
|
|
15911
|
-
name: "
|
|
15912
|
-
title: "
|
|
15913
|
-
description: "
|
|
15930
|
+
name: "topolo_search_actions",
|
|
15931
|
+
title: "Search Topolo actions the agent can call",
|
|
15932
|
+
description: "Searches one application's credential-scoped actions with a bounded page and continuation cursor.",
|
|
15914
15933
|
requiredScopes: [],
|
|
15915
15934
|
destructive: false,
|
|
15916
15935
|
inputSchema: {
|
|
@@ -15918,31 +15937,25 @@ var TOOLS = [
|
|
|
15918
15937
|
properties: {
|
|
15919
15938
|
service: {
|
|
15920
15939
|
type: "string",
|
|
15921
|
-
description: "
|
|
15922
|
-
}
|
|
15940
|
+
description: "Required application selector. Prefer actionService from topolo_search_applications; canonical app id, slug, and name are also accepted."
|
|
15941
|
+
},
|
|
15942
|
+
query: { type: "string" },
|
|
15943
|
+
cursor: { type: "string" },
|
|
15944
|
+
limit: { type: "integer", minimum: 1, maximum: 100, default: 25 }
|
|
15923
15945
|
},
|
|
15946
|
+
required: ["service"],
|
|
15924
15947
|
additionalProperties: false
|
|
15925
15948
|
},
|
|
15926
|
-
handler: async (topolo, args) =>
|
|
15927
|
-
|
|
15928
|
-
|
|
15929
|
-
|
|
15930
|
-
|
|
15931
|
-
|
|
15932
|
-
|
|
15933
|
-
|
|
15934
|
-
|
|
15935
|
-
|
|
15936
|
-
requiredScopes: [],
|
|
15937
|
-
destructive: false,
|
|
15938
|
-
inputSchema: {
|
|
15939
|
-
type: "object",
|
|
15940
|
-
properties: {},
|
|
15941
|
-
additionalProperties: false
|
|
15942
|
-
},
|
|
15943
|
-
handler: async (topolo) => ({
|
|
15944
|
-
applications: await topolo.client.listServices()
|
|
15945
|
-
})
|
|
15949
|
+
handler: async (topolo, args) => {
|
|
15950
|
+
const service = typeof args["service"] === "string" ? args["service"].trim() : "";
|
|
15951
|
+
if (!service) throw new Error("service is required for bounded action discovery.");
|
|
15952
|
+
return topolo.client.searchActions({
|
|
15953
|
+
service,
|
|
15954
|
+
query: typeof args["query"] === "string" ? args["query"] : void 0,
|
|
15955
|
+
cursor: typeof args["cursor"] === "string" ? args["cursor"] : void 0,
|
|
15956
|
+
limit: typeof args["limit"] === "number" ? args["limit"] : void 0
|
|
15957
|
+
});
|
|
15958
|
+
}
|
|
15946
15959
|
},
|
|
15947
15960
|
{
|
|
15948
15961
|
name: "topolo_get_application",
|
|
@@ -15955,7 +15968,7 @@ var TOOLS = [
|
|
|
15955
15968
|
properties: {
|
|
15956
15969
|
application: {
|
|
15957
15970
|
type: "string",
|
|
15958
|
-
description: "Application identifier: app id, slug, or name from
|
|
15971
|
+
description: "Application identifier: app id, slug, or name from topolo_search_applications."
|
|
15959
15972
|
}
|
|
15960
15973
|
},
|
|
15961
15974
|
required: ["application"],
|
|
@@ -15966,18 +15979,98 @@ var TOOLS = [
|
|
|
15966
15979
|
if (typeof application !== "string" || !application.trim()) {
|
|
15967
15980
|
throw new Error("`application` must be a non-empty string.");
|
|
15968
15981
|
}
|
|
15969
|
-
|
|
15970
|
-
|
|
15971
|
-
|
|
15972
|
-
|
|
15982
|
+
return { application: await topolo.client.getService(application) };
|
|
15983
|
+
}
|
|
15984
|
+
},
|
|
15985
|
+
{
|
|
15986
|
+
name: "topolo_get_action",
|
|
15987
|
+
title: "Describe one Topolo action",
|
|
15988
|
+
description: "Returns one credential-scoped action by exact action id.",
|
|
15989
|
+
requiredScopes: [],
|
|
15990
|
+
destructive: false,
|
|
15991
|
+
inputSchema: {
|
|
15992
|
+
type: "object",
|
|
15993
|
+
properties: { actionId: { type: "string", minLength: 1 } },
|
|
15994
|
+
required: ["actionId"],
|
|
15995
|
+
additionalProperties: false
|
|
15996
|
+
},
|
|
15997
|
+
handler: async (topolo, args) => {
|
|
15998
|
+
const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
|
|
15999
|
+
if (!actionId) throw new Error("actionId is required.");
|
|
16000
|
+
return { action: await topolo.client.getAction(actionId) };
|
|
16001
|
+
}
|
|
16002
|
+
},
|
|
16003
|
+
{
|
|
16004
|
+
name: "topolo_read_action",
|
|
16005
|
+
title: "Call one read-only Topolo action",
|
|
16006
|
+
description: "Calls one exact action id only when its published contract is read-only and needs no confirmation.",
|
|
16007
|
+
requiredScopes: [],
|
|
16008
|
+
destructive: false,
|
|
16009
|
+
inputSchema: {
|
|
16010
|
+
type: "object",
|
|
16011
|
+
properties: {
|
|
16012
|
+
actionId: { type: "string", minLength: 1 },
|
|
16013
|
+
input: { type: "object", additionalProperties: true },
|
|
16014
|
+
resourceType: { type: "string", description: "Optional app-local resource alias, such as workspace." },
|
|
16015
|
+
resourceId: { type: "string", description: "Resource id. Required when resourceType is provided." }
|
|
16016
|
+
},
|
|
16017
|
+
required: ["actionId"],
|
|
16018
|
+
additionalProperties: false
|
|
16019
|
+
},
|
|
16020
|
+
handler: async (topolo, args) => {
|
|
16021
|
+
const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
|
|
16022
|
+
if (!actionId) throw new Error("actionId is required.");
|
|
16023
|
+
const input = args["input"];
|
|
16024
|
+
if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
|
|
16025
|
+
throw new Error("input must be an object.");
|
|
16026
|
+
}
|
|
16027
|
+
const action = await topolo.client.getAction(actionId);
|
|
16028
|
+
const agentAccess = action.agentAccess ?? (action.destructive ? "off" : action.readOnly && !action.requiresConfirmation ? "auto" : "confirm");
|
|
16029
|
+
if (action.method !== "GET" || !action.readOnly || action.destructive || action.requiresConfirmation || agentAccess !== "auto") {
|
|
16030
|
+
throw new Error(`Action "${actionId}" is not an automatic read-only action. Use topolo_call_action with confirmation.`);
|
|
16031
|
+
}
|
|
16032
|
+
const resource = optionalResourceContext(args);
|
|
16033
|
+
return topolo.client.callAction(
|
|
16034
|
+
actionId,
|
|
16035
|
+
input ?? {},
|
|
16036
|
+
resource ? { resource } : {}
|
|
16037
|
+
);
|
|
16038
|
+
}
|
|
16039
|
+
},
|
|
16040
|
+
{
|
|
16041
|
+
name: "topolo_call_action",
|
|
16042
|
+
title: "Call one Topolo action",
|
|
16043
|
+
description: "Calls one exact action id. Mutating actions require confirm:true.",
|
|
16044
|
+
requiredScopes: [],
|
|
16045
|
+
destructive: true,
|
|
16046
|
+
inputSchema: {
|
|
16047
|
+
type: "object",
|
|
16048
|
+
properties: {
|
|
16049
|
+
actionId: { type: "string", minLength: 1 },
|
|
16050
|
+
input: { type: "object", additionalProperties: true },
|
|
16051
|
+
resourceType: { type: "string", description: "Optional app-local resource alias, such as workspace." },
|
|
16052
|
+
resourceId: { type: "string", description: "Resource id. Required when resourceType is provided." },
|
|
16053
|
+
confirm: { type: "boolean" }
|
|
16054
|
+
},
|
|
16055
|
+
required: ["actionId"],
|
|
16056
|
+
additionalProperties: false
|
|
16057
|
+
},
|
|
16058
|
+
handler: async (topolo, args) => {
|
|
16059
|
+
const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
|
|
16060
|
+
if (!actionId) throw new Error("actionId is required.");
|
|
16061
|
+
const input = args["input"];
|
|
16062
|
+
if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
|
|
16063
|
+
throw new Error("input must be an object.");
|
|
16064
|
+
}
|
|
16065
|
+
const resource = optionalResourceContext(args);
|
|
16066
|
+
return topolo.client.callAction(
|
|
16067
|
+
actionId,
|
|
16068
|
+
input ?? {},
|
|
16069
|
+
{
|
|
16070
|
+
confirm: args["confirm"] === true,
|
|
16071
|
+
...resource ? { resource } : {}
|
|
16072
|
+
}
|
|
15973
16073
|
);
|
|
15974
|
-
if (!match) {
|
|
15975
|
-
const known = catalog.map((e) => e.slug || e.appId).sort().filter((value) => typeof value === "string" && value.length > 0);
|
|
15976
|
-
throw new Error(
|
|
15977
|
-
`Unknown application "${application}". ${formatKnownValues(known, "applications")}`
|
|
15978
|
-
);
|
|
15979
|
-
}
|
|
15980
|
-
return { application: match };
|
|
15981
16074
|
}
|
|
15982
16075
|
},
|
|
15983
16076
|
{
|
|
@@ -15991,7 +16084,7 @@ var TOOLS = [
|
|
|
15991
16084
|
properties: {
|
|
15992
16085
|
application: {
|
|
15993
16086
|
type: "string",
|
|
15994
|
-
description: "Optional application ID from
|
|
16087
|
+
description: "Optional application ID from topolo_search_applications."
|
|
15995
16088
|
}
|
|
15996
16089
|
},
|
|
15997
16090
|
additionalProperties: false
|
|
@@ -16031,7 +16124,7 @@ var TOOLS = [
|
|
|
16031
16124
|
properties: {
|
|
16032
16125
|
application: {
|
|
16033
16126
|
type: "string",
|
|
16034
|
-
description: "Optional application ID from
|
|
16127
|
+
description: "Optional application ID from topolo_search_applications."
|
|
16035
16128
|
},
|
|
16036
16129
|
failOn: {
|
|
16037
16130
|
type: "string",
|
|
@@ -16065,7 +16158,7 @@ var TOOLS = [
|
|
|
16065
16158
|
{
|
|
16066
16159
|
name: "topolo_api_call",
|
|
16067
16160
|
title: "Call any Topolo platform service",
|
|
16068
|
-
description: "Low-level passthrough to any Topolo service. Use when no domain-specific tool exists for the operation you need. The request is signed with the current credential and scoped to the caller's organization \u2014 the target service will return 403 if your scopes do not permit the operation, even though this tool is advertised. Mutating calls (non-GET methods) require confirm:true. Call
|
|
16161
|
+
description: "Low-level passthrough to any Topolo service. Use when no domain-specific tool exists for the operation you need. The request is signed with the current credential and scoped to the caller's organization \u2014 the target service will return 403 if your scopes do not permit the operation, even though this tool is advertised. Mutating calls (non-GET methods) require confirm:true. Call topolo_search_applications first to discover callable app IDs; the SDK can also resolve live Auth-catalog app ids/slugs for newly registered API surfaces.",
|
|
16069
16162
|
requiredScopes: [],
|
|
16070
16163
|
destructive: true,
|
|
16071
16164
|
inputSchema: {
|
|
@@ -16096,7 +16189,7 @@ var TOOLS = [
|
|
|
16096
16189
|
},
|
|
16097
16190
|
resourceType: {
|
|
16098
16191
|
type: "string",
|
|
16099
|
-
description: "Optional workspace resource alias from
|
|
16192
|
+
description: "Optional workspace resource alias from topolo_search_applications apiKeyResources. Aliases are app-defined, e.g. brand, mailbox, venue, merchant, or any other cataloged alias."
|
|
16100
16193
|
},
|
|
16101
16194
|
resourceId: {
|
|
16102
16195
|
type: "string",
|
|
@@ -16114,7 +16207,7 @@ var TOOLS = [
|
|
|
16114
16207
|
const service = args["service"];
|
|
16115
16208
|
const path = args["path"];
|
|
16116
16209
|
if (typeof service !== "string" || !service.trim()) {
|
|
16117
|
-
throw new Error("service is required. Call
|
|
16210
|
+
throw new Error("service is required. Call topolo_search_applications first to discover callable services.");
|
|
16118
16211
|
}
|
|
16119
16212
|
if (typeof path !== "string" || !path) {
|
|
16120
16213
|
throw new Error("path is required");
|
|
@@ -16128,12 +16221,7 @@ var TOOLS = [
|
|
|
16128
16221
|
const normalisedQuery = query && typeof query === "object" && !Array.isArray(query) ? Object.fromEntries(
|
|
16129
16222
|
Object.entries(query).map(([k, v]) => [k, String(v)])
|
|
16130
16223
|
) : void 0;
|
|
16131
|
-
const
|
|
16132
|
-
const resourceId = typeof args["resourceId"] === "string" ? args["resourceId"].trim() : "";
|
|
16133
|
-
if (resourceType && !resourceId || !resourceType && resourceId) {
|
|
16134
|
-
throw new Error("resourceType and resourceId must be provided together.");
|
|
16135
|
-
}
|
|
16136
|
-
const resource = resourceType && resourceId ? { resourceType, resourceId } : void 0;
|
|
16224
|
+
const resource = optionalResourceContext(args);
|
|
16137
16225
|
return topolo.client.request({
|
|
16138
16226
|
service: service.trim(),
|
|
16139
16227
|
method,
|
|
@@ -16150,58 +16238,8 @@ function filterToolsByScopes(tools, scopes) {
|
|
|
16150
16238
|
return tools.filter((t) => hasAnyScope(scopes, t.requiredScopes));
|
|
16151
16239
|
}
|
|
16152
16240
|
async function buildTopoloTools(topolo, scopes, tools = TOOLS) {
|
|
16153
|
-
|
|
16154
|
-
|
|
16155
|
-
const actionTools = actionsToToolDefs(actions);
|
|
16156
|
-
return filterToolsByScopes([...baseTools, ...actionTools], scopes);
|
|
16157
|
-
}
|
|
16158
|
-
function effectiveAgentAccess(a) {
|
|
16159
|
-
if (a.agentAccess) return a.agentAccess;
|
|
16160
|
-
if (a.destructive) return "off";
|
|
16161
|
-
if (a.readOnly && !a.requiresConfirmation) return "auto";
|
|
16162
|
-
return "confirm";
|
|
16163
|
-
}
|
|
16164
|
-
function actionsToToolDefs(actions) {
|
|
16165
|
-
return actions.map((action) => ({ action, access: effectiveAgentAccess(action) })).filter(({ access }) => access !== "off").map(({ action, access }) => ({
|
|
16166
|
-
name: action.toolName || toolNameForAction(action),
|
|
16167
|
-
title: action.title,
|
|
16168
|
-
description: action.description,
|
|
16169
|
-
requiredScopes: action.requiredPermission ? [action.requiredPermission] : [],
|
|
16170
|
-
destructive: access === "confirm",
|
|
16171
|
-
inputSchema: actionInputSchema(action, access),
|
|
16172
|
-
handler: async (topolo, args) => {
|
|
16173
|
-
const confirm = Boolean(args["confirm"]);
|
|
16174
|
-
const input = { ...args };
|
|
16175
|
-
delete input["confirm"];
|
|
16176
|
-
return topolo.client.callAction(action.actionId, input, { confirm });
|
|
16177
|
-
}
|
|
16178
|
-
}));
|
|
16179
|
-
}
|
|
16180
|
-
function toolNameForAction(action) {
|
|
16181
|
-
const service = (action.appSlug || action.appId || "service").replace(/^topolo-/, "").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
16182
|
-
const name = action.name.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
16183
|
-
return ["topolo", service, name].filter(Boolean).join("_").slice(0, 96);
|
|
16184
|
-
}
|
|
16185
|
-
function actionInputSchema(action, access = "auto") {
|
|
16186
|
-
const schema = {
|
|
16187
|
-
type: "object",
|
|
16188
|
-
properties: {},
|
|
16189
|
-
additionalProperties: false,
|
|
16190
|
-
...action.inputSchema
|
|
16191
|
-
};
|
|
16192
|
-
const properties = schema.properties && typeof schema.properties === "object" && !Array.isArray(schema.properties) ? { ...schema.properties } : {};
|
|
16193
|
-
if (access === "confirm") {
|
|
16194
|
-
properties.confirm = {
|
|
16195
|
-
type: "boolean",
|
|
16196
|
-
description: "Required for mutating actions. Explicit human-in-the-loop acknowledgement."
|
|
16197
|
-
};
|
|
16198
|
-
}
|
|
16199
|
-
return {
|
|
16200
|
-
...schema,
|
|
16201
|
-
type: "object",
|
|
16202
|
-
properties,
|
|
16203
|
-
additionalProperties: schema.additionalProperties ?? false
|
|
16204
|
-
};
|
|
16241
|
+
void topolo;
|
|
16242
|
+
return filterToolsByScopes(tools, scopes);
|
|
16205
16243
|
}
|
|
16206
16244
|
function evaluateApplicationAuditGate(report, threshold) {
|
|
16207
16245
|
const counts = {
|