@topolo/cli 0.13.26 → 0.13.27
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/dist/index.js +321 -233
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -326,74 +326,6 @@ function validTopoloActionAccessPolicy(value) {
|
|
|
326
326
|
}
|
|
327
327
|
return true;
|
|
328
328
|
}
|
|
329
|
-
function record2(value) {
|
|
330
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
331
|
-
}
|
|
332
|
-
function text(value, limit = 512) {
|
|
333
|
-
return typeof value === "string" && value.trim() ? value.trim().slice(0, limit) : null;
|
|
334
|
-
}
|
|
335
|
-
function strings2(value) {
|
|
336
|
-
return Array.isArray(value) ? value.slice(0, 8).flatMap((item) => {
|
|
337
|
-
const result = text(item);
|
|
338
|
-
return result ? [result] : [];
|
|
339
|
-
}) : [];
|
|
340
|
-
}
|
|
341
|
-
function pairs(value, first, second) {
|
|
342
|
-
return Array.isArray(value) ? value.slice(0, 8).flatMap((item) => {
|
|
343
|
-
if (!record2(item)) return [];
|
|
344
|
-
const a = text(item[first], 160);
|
|
345
|
-
const b = text(item[second]);
|
|
346
|
-
return a && b ? [{ [first]: a, [second]: b }] : [];
|
|
347
|
-
}) : [];
|
|
348
|
-
}
|
|
349
|
-
function docs(value) {
|
|
350
|
-
const result = text(value, 2048);
|
|
351
|
-
if (!result) return null;
|
|
352
|
-
try {
|
|
353
|
-
const url = new URL(result);
|
|
354
|
-
return url.protocol === "https:" && !url.username && !url.password ? url.href : null;
|
|
355
|
-
} catch {
|
|
356
|
-
return null;
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
function normalizeApplicationGuide(value) {
|
|
360
|
-
if (!record2(value) || value.schemaVersion !== 1 || value.source !== "published_application_manifest") return null;
|
|
361
|
-
const purpose = text(value.purpose, 2048);
|
|
362
|
-
const gettingStarted = strings2(value.gettingStarted);
|
|
363
|
-
const docsUrl = docs(value.docsUrl);
|
|
364
|
-
return {
|
|
365
|
-
schemaVersion: 1,
|
|
366
|
-
source: "published_application_manifest",
|
|
367
|
-
publishedAt: text(value.publishedAt, 160),
|
|
368
|
-
purpose,
|
|
369
|
-
problemStatement: text(value.problemStatement, 2048),
|
|
370
|
-
solutionStatement: text(value.solutionStatement, 2048),
|
|
371
|
-
benefits: strings2(value.benefits),
|
|
372
|
-
features: pairs(value.features, "title", "description"),
|
|
373
|
-
gettingStarted,
|
|
374
|
-
worksWellWith: pairs(value.worksWellWith, "appId", "reason"),
|
|
375
|
-
docsUrl,
|
|
376
|
-
missingFields: [...!purpose ? ["purpose"] : [], ...!docsUrl ? ["docsUrl"] : [], ...!gettingStarted.length ? ["gettingStarted"] : []]
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
function applyAuthHeaders(headers, credential) {
|
|
380
|
-
if (credential.kind === "api_key") {
|
|
381
|
-
headers.set("X-Api-Key", credential.apiKey);
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
headers.set("Authorization", `${credential.kind === "dpop_access_token" ? "DPoP" : "Bearer"} ${credential.accessToken}`);
|
|
385
|
-
}
|
|
386
|
-
function applyAuditHeaders(headers, agent, requestId) {
|
|
387
|
-
headers.set("X-Topolo-Client", `${agent.clientName}/${agent.clientVersion}`);
|
|
388
|
-
if (agent.agentName) headers.set("X-Topolo-Agent", agent.agentName);
|
|
389
|
-
headers.set("X-Topolo-Request-Id", requestId);
|
|
390
|
-
}
|
|
391
|
-
function generateRequestId() {
|
|
392
|
-
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
393
|
-
return crypto.randomUUID();
|
|
394
|
-
}
|
|
395
|
-
return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
396
|
-
}
|
|
397
329
|
var TopoloSdkError = class extends Error {
|
|
398
330
|
code;
|
|
399
331
|
constructor(code, message3) {
|
|
@@ -823,152 +755,6 @@ var TopoloReauthRequiredError = class extends TopoloAuthError {
|
|
|
823
755
|
this.reauthorization = Object.freeze({ ...reauthorization });
|
|
824
756
|
}
|
|
825
757
|
};
|
|
826
|
-
var ACTION_SECRET_PREFIX = "topolo-secret:";
|
|
827
|
-
function isActionSecretReference(value) {
|
|
828
|
-
return typeof value === "string" && value.startsWith(ACTION_SECRET_PREFIX);
|
|
829
|
-
}
|
|
830
|
-
function isRecord(value) {
|
|
831
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
832
|
-
}
|
|
833
|
-
function sensitive(key, value) {
|
|
834
|
-
const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
835
|
-
if (normalized === "capability") {
|
|
836
|
-
if (typeof value !== "string") return value !== null && value !== void 0 && typeof value !== "boolean" && typeof value !== "number";
|
|
837
|
-
const text4 = value.trim();
|
|
838
|
-
return Boolean(text4) && !/^[a-z][a-z0-9_-]{0,31}$/.test(text4);
|
|
839
|
-
}
|
|
840
|
-
return ["authorization", "cookie", "setcookie", "proxyauthorization"].includes(normalized) || /(token|secret|password|privatekey|apikey|backupcodes?|recoverycodes?)$/.test(normalized);
|
|
841
|
-
}
|
|
842
|
-
function maskActionSecrets(value, secrets) {
|
|
843
|
-
let masked = value;
|
|
844
|
-
for (const [secret, reference] of secrets) {
|
|
845
|
-
const encoded = encodeURIComponent(secret);
|
|
846
|
-
const variants = [.../* @__PURE__ */ new Set([secret, encoded])].map((item) => item.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
847
|
-
masked = masked.replace(new RegExp(variants.join("|"), "g"), (match) => match === secret ? reference : encodeURIComponent(reference));
|
|
848
|
-
}
|
|
849
|
-
return masked;
|
|
850
|
-
}
|
|
851
|
-
async function resolveActionSecrets(value, store, secrets) {
|
|
852
|
-
if (isActionSecretReference(value)) {
|
|
853
|
-
if (!store) throw new TopoloSdkError("action_secret_store_required", "Protected action references require a secret store.");
|
|
854
|
-
const resolved = await store.load(value);
|
|
855
|
-
if (typeof resolved !== "string" || !resolved) throw new TopoloSdkError("action_secret_unsupported_type", "Protected action handoff requires a nonempty string credential.");
|
|
856
|
-
secrets.set(resolved, value);
|
|
857
|
-
return resolved;
|
|
858
|
-
}
|
|
859
|
-
if (Array.isArray(value)) return Promise.all(value.map((item) => resolveActionSecrets(item, store, secrets)));
|
|
860
|
-
if (!isRecord(value)) return value;
|
|
861
|
-
return Object.fromEntries(await Promise.all(Object.entries(value).map(async ([key, item]) => [key, await resolveActionSecrets(item, store, secrets)])));
|
|
862
|
-
}
|
|
863
|
-
async function protectActionResult(value, store, options = {}) {
|
|
864
|
-
const secrets = /* @__PURE__ */ new Map();
|
|
865
|
-
function documentation(item, key) {
|
|
866
|
-
if (options.preserveActionSchemas === true && ["inputSchema", "outputSchema", "input_schema", "output_schema"].includes(key) && isRecord(item)) return true;
|
|
867
|
-
if (options.preserveActionContracts === true && ["agentContract", "agent_contract"].includes(key) && isRecord(item)) return true;
|
|
868
|
-
return options.preserveAgentGuidance === true && key === "agentGuidance" && isRecord(item) && item.schemaVersion === 1 && typeof item.kind === "string" && ["action-guide", "product-guide", "concept"].includes(item.kind);
|
|
869
|
-
}
|
|
870
|
-
function localizationMap(path) {
|
|
871
|
-
const location = path.join("/");
|
|
872
|
-
if (options.localizationAction === "sources.verify") return location === "data/hashes";
|
|
873
|
-
if (options.localizationAction === "values.bulk_upsert") return location === "data/sourceHashes";
|
|
874
|
-
return ["translation.release.prepare", "translation.release.import", "translation.release.get"].includes(options.localizationAction ?? "") && /^data\/bundle\/catalogs\/\*\/(sources|(?:packs|provenance)\/[^/]+)$/.test(location);
|
|
875
|
-
}
|
|
876
|
-
async function protect(item, key = "", path = []) {
|
|
877
|
-
if (documentation(item, key)) return item;
|
|
878
|
-
if (isActionSecretReference(item)) return item;
|
|
879
|
-
if (Array.isArray(item) && /(?:backup|recovery)codes$/.test(key.toLowerCase().replace(/[^a-z0-9]/g, ""))) {
|
|
880
|
-
return Promise.all(item.map((child) => protect(child, key, [...path, "*"])));
|
|
881
|
-
}
|
|
882
|
-
if (sensitive(key, item)) {
|
|
883
|
-
const reference = store ? await store.save(item) : "[REDACTED]";
|
|
884
|
-
if (typeof item === "string" && item) secrets.set(item, reference);
|
|
885
|
-
return reference;
|
|
886
|
-
}
|
|
887
|
-
if (Array.isArray(item)) return Promise.all(item.map((child) => protect(child, "", [...path, "*"])));
|
|
888
|
-
if (!isRecord(item)) return item;
|
|
889
|
-
return Object.fromEntries(await Promise.all(Object.entries(item).map(async ([name, child]) => [name, await protect(child, localizationMap(path) ? "" : name, [...path, name])])));
|
|
890
|
-
}
|
|
891
|
-
const protectedValue = await protect(value);
|
|
892
|
-
async function protectEmbedded(item, key = "") {
|
|
893
|
-
if (documentation(item, key)) return item;
|
|
894
|
-
if (typeof item === "string" && !isActionSecretReference(item) && maskActionSecrets(item, secrets) !== item) {
|
|
895
|
-
return store ? store.save(item) : maskActionSecrets(item, secrets);
|
|
896
|
-
}
|
|
897
|
-
if (Array.isArray(item)) return Promise.all(item.map((child) => protectEmbedded(child)));
|
|
898
|
-
if (!isRecord(item)) return item;
|
|
899
|
-
return Object.fromEntries(await Promise.all(Object.entries(item).map(async ([key2, child]) => [key2, await protectEmbedded(child, key2)])));
|
|
900
|
-
}
|
|
901
|
-
return protectEmbedded(protectedValue);
|
|
902
|
-
}
|
|
903
|
-
function maskActionSecretValue(value, secrets) {
|
|
904
|
-
if (value instanceof Error) return maskActionSecretError(value, secrets);
|
|
905
|
-
if (typeof value === "string") return maskActionSecrets(value, secrets);
|
|
906
|
-
if (Array.isArray(value)) return value.map((item) => maskActionSecretValue(item, secrets));
|
|
907
|
-
if (!isRecord(value)) return value;
|
|
908
|
-
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, maskActionSecretValue(item, secrets)]));
|
|
909
|
-
}
|
|
910
|
-
function maskActionSecretError(error, secrets) {
|
|
911
|
-
if (!(error instanceof Error)) return maskActionSecretValue(error, secrets);
|
|
912
|
-
const masked = Object.create(Object.getPrototypeOf(error));
|
|
913
|
-
for (const key of Object.getOwnPropertyNames(error)) {
|
|
914
|
-
const descriptor = Object.getOwnPropertyDescriptor(error, key);
|
|
915
|
-
if ("value" in descriptor) descriptor.value = maskActionSecretValue(descriptor.value, secrets);
|
|
916
|
-
Object.defineProperty(masked, key, descriptor);
|
|
917
|
-
}
|
|
918
|
-
return masked;
|
|
919
|
-
}
|
|
920
|
-
var encoder = new TextEncoder();
|
|
921
|
-
function encodeBase64Url(value) {
|
|
922
|
-
const bytes = value instanceof Uint8Array ? value : new Uint8Array(value);
|
|
923
|
-
let binary = "";
|
|
924
|
-
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
925
|
-
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
926
|
-
}
|
|
927
|
-
function encodeJson(value) {
|
|
928
|
-
return encodeBase64Url(encoder.encode(JSON.stringify(value)));
|
|
929
|
-
}
|
|
930
|
-
async function sha256Base64Url(value) {
|
|
931
|
-
return encodeBase64Url(await crypto.subtle.digest("SHA-256", encoder.encode(value)));
|
|
932
|
-
}
|
|
933
|
-
function publicJwk(privateJwk) {
|
|
934
|
-
const { crv, kty, x, y } = privateJwk;
|
|
935
|
-
if (kty !== "EC" || crv !== "P-256" || !x || !y || !privateJwk.d) {
|
|
936
|
-
throw new TypeError("A private P-256 JSON Web Key is required for DPoP signing.");
|
|
937
|
-
}
|
|
938
|
-
return { crv, kty, x, y };
|
|
939
|
-
}
|
|
940
|
-
function canonicalTargetUrl(value) {
|
|
941
|
-
const url = new URL(value);
|
|
942
|
-
return `${url.origin}${url.pathname}`;
|
|
943
|
-
}
|
|
944
|
-
async function calculateDpopJkt(privateJwk) {
|
|
945
|
-
const jwk = publicJwk(privateJwk);
|
|
946
|
-
return sha256Base64Url(JSON.stringify({ crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y }));
|
|
947
|
-
}
|
|
948
|
-
async function createDpopProof(input2) {
|
|
949
|
-
const jwk = publicJwk(input2.privateJwk);
|
|
950
|
-
const key = await crypto.subtle.importKey(
|
|
951
|
-
"jwk",
|
|
952
|
-
input2.privateJwk,
|
|
953
|
-
{ name: "ECDSA", namedCurve: "P-256" },
|
|
954
|
-
false,
|
|
955
|
-
["sign"]
|
|
956
|
-
);
|
|
957
|
-
const header = encodeJson({ alg: "ES256", typ: "dpop+jwt", jwk });
|
|
958
|
-
const claims = encodeJson({
|
|
959
|
-
jti: crypto.randomUUID(),
|
|
960
|
-
iat: Math.floor(Date.now() / 1e3),
|
|
961
|
-
htm: input2.method.toUpperCase(),
|
|
962
|
-
htu: canonicalTargetUrl(input2.targetUrl),
|
|
963
|
-
ath: await sha256Base64Url(input2.accessToken)
|
|
964
|
-
});
|
|
965
|
-
const signature = await crypto.subtle.sign(
|
|
966
|
-
{ name: "ECDSA", hash: "SHA-256" },
|
|
967
|
-
key,
|
|
968
|
-
encoder.encode(`${header}.${claims}`)
|
|
969
|
-
);
|
|
970
|
-
return `${header}.${claims}.${encodeBase64Url(signature)}`;
|
|
971
|
-
}
|
|
972
758
|
var TOPOLO_FIRST_PARTY_ORIGINS = Object.freeze({
|
|
973
759
|
production: Object.freeze([
|
|
974
760
|
"https://admin.topolo.app",
|
|
@@ -1269,6 +1055,270 @@ async function fetchWithCredentialBoundary(fetchImpl, environment, service, targ
|
|
|
1269
1055
|
}
|
|
1270
1056
|
return response;
|
|
1271
1057
|
}
|
|
1058
|
+
var MARKETING_ORIGINS = Object.freeze({
|
|
1059
|
+
development: "https://topolo.dev",
|
|
1060
|
+
staging: "https://stg.topolo.us",
|
|
1061
|
+
production: "https://topolo.io"
|
|
1062
|
+
});
|
|
1063
|
+
function isOnePublicMarketingAction(entry) {
|
|
1064
|
+
return entry.appId === "app_topolo_one" && entry.target === "marketing" && entry.authorizationMode === "public";
|
|
1065
|
+
}
|
|
1066
|
+
function publicMarketingOrigin(entry, environment) {
|
|
1067
|
+
const selected = requireTopoloRuntimeEnvironment(environment);
|
|
1068
|
+
const origin = selected === "local" ? void 0 : MARKETING_ORIGINS[selected];
|
|
1069
|
+
if (!isOnePublicMarketingAction(entry) || !origin || entry.apiBaseUrl !== origin && entry.apiBaseUrl !== origin + "/") {
|
|
1070
|
+
throw new TopoloSdkError("environment_mismatch", "Public action target does not match the registered application, target and environment.");
|
|
1071
|
+
}
|
|
1072
|
+
return origin;
|
|
1073
|
+
}
|
|
1074
|
+
async function fetchPublicMarketingAction(fetchImpl, entry, environment, target, init) {
|
|
1075
|
+
const origin = publicMarketingOrigin(entry, environment);
|
|
1076
|
+
if (target.origin !== origin || target.protocol !== "https:" || target.username || target.password || target.port) {
|
|
1077
|
+
throw new TopoloSdkError("service_path_origin_mismatch", "Public action path changes the registered target origin.");
|
|
1078
|
+
}
|
|
1079
|
+
init.signal?.throwIfAborted();
|
|
1080
|
+
const headers = new Headers({
|
|
1081
|
+
Accept: "application/json",
|
|
1082
|
+
"X-Topolo-Action-Id": entry.actionId,
|
|
1083
|
+
"X-Topolo-Action-Name": entry.name
|
|
1084
|
+
});
|
|
1085
|
+
const contentType = new Headers(init.headers).get("Content-Type");
|
|
1086
|
+
if (contentType) headers.set("Content-Type", contentType);
|
|
1087
|
+
const response = await fetchImpl(target.toString(), {
|
|
1088
|
+
method: init.method,
|
|
1089
|
+
headers,
|
|
1090
|
+
body: init.body,
|
|
1091
|
+
signal: init.signal,
|
|
1092
|
+
credentials: "omit",
|
|
1093
|
+
redirect: "manual",
|
|
1094
|
+
referrerPolicy: "no-referrer"
|
|
1095
|
+
});
|
|
1096
|
+
let responseOrigin = origin;
|
|
1097
|
+
try {
|
|
1098
|
+
if (response.url) responseOrigin = new URL(response.url).origin;
|
|
1099
|
+
} catch {
|
|
1100
|
+
responseOrigin = "";
|
|
1101
|
+
}
|
|
1102
|
+
if (response.redirected || responseOrigin !== origin || response.status >= 300 && response.status < 400) {
|
|
1103
|
+
await response.body?.cancel().catch(() => void 0);
|
|
1104
|
+
throw new TopoloSdkError("public_action_redirect_refused", "Public action redirects are refused.");
|
|
1105
|
+
}
|
|
1106
|
+
return response;
|
|
1107
|
+
}
|
|
1108
|
+
function record2(value) {
|
|
1109
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
1110
|
+
}
|
|
1111
|
+
function text(value, limit = 512) {
|
|
1112
|
+
return typeof value === "string" && value.trim() ? value.trim().slice(0, limit) : null;
|
|
1113
|
+
}
|
|
1114
|
+
function strings2(value) {
|
|
1115
|
+
return Array.isArray(value) ? value.slice(0, 8).flatMap((item) => {
|
|
1116
|
+
const result = text(item);
|
|
1117
|
+
return result ? [result] : [];
|
|
1118
|
+
}) : [];
|
|
1119
|
+
}
|
|
1120
|
+
function pairs(value, first, second) {
|
|
1121
|
+
return Array.isArray(value) ? value.slice(0, 8).flatMap((item) => {
|
|
1122
|
+
if (!record2(item)) return [];
|
|
1123
|
+
const a = text(item[first], 160);
|
|
1124
|
+
const b = text(item[second]);
|
|
1125
|
+
return a && b ? [{ [first]: a, [second]: b }] : [];
|
|
1126
|
+
}) : [];
|
|
1127
|
+
}
|
|
1128
|
+
function docs(value) {
|
|
1129
|
+
const result = text(value, 2048);
|
|
1130
|
+
if (!result) return null;
|
|
1131
|
+
try {
|
|
1132
|
+
const url = new URL(result);
|
|
1133
|
+
return url.protocol === "https:" && !url.username && !url.password ? url.href : null;
|
|
1134
|
+
} catch {
|
|
1135
|
+
return null;
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
function normalizeApplicationGuide(value) {
|
|
1139
|
+
if (!record2(value) || value.schemaVersion !== 1 || value.source !== "published_application_manifest") return null;
|
|
1140
|
+
const purpose = text(value.purpose, 2048);
|
|
1141
|
+
const gettingStarted = strings2(value.gettingStarted);
|
|
1142
|
+
const docsUrl = docs(value.docsUrl);
|
|
1143
|
+
return {
|
|
1144
|
+
schemaVersion: 1,
|
|
1145
|
+
source: "published_application_manifest",
|
|
1146
|
+
publishedAt: text(value.publishedAt, 160),
|
|
1147
|
+
purpose,
|
|
1148
|
+
problemStatement: text(value.problemStatement, 2048),
|
|
1149
|
+
solutionStatement: text(value.solutionStatement, 2048),
|
|
1150
|
+
benefits: strings2(value.benefits),
|
|
1151
|
+
features: pairs(value.features, "title", "description"),
|
|
1152
|
+
gettingStarted,
|
|
1153
|
+
worksWellWith: pairs(value.worksWellWith, "appId", "reason"),
|
|
1154
|
+
docsUrl,
|
|
1155
|
+
missingFields: [...!purpose ? ["purpose"] : [], ...!docsUrl ? ["docsUrl"] : [], ...!gettingStarted.length ? ["gettingStarted"] : []]
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
function applyAuthHeaders(headers, credential) {
|
|
1159
|
+
if (credential.kind === "api_key") {
|
|
1160
|
+
headers.set("X-Api-Key", credential.apiKey);
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1163
|
+
headers.set("Authorization", `${credential.kind === "dpop_access_token" ? "DPoP" : "Bearer"} ${credential.accessToken}`);
|
|
1164
|
+
}
|
|
1165
|
+
function applyAuditHeaders(headers, agent, requestId) {
|
|
1166
|
+
headers.set("X-Topolo-Client", `${agent.clientName}/${agent.clientVersion}`);
|
|
1167
|
+
if (agent.agentName) headers.set("X-Topolo-Agent", agent.agentName);
|
|
1168
|
+
headers.set("X-Topolo-Request-Id", requestId);
|
|
1169
|
+
}
|
|
1170
|
+
function generateRequestId() {
|
|
1171
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
1172
|
+
return crypto.randomUUID();
|
|
1173
|
+
}
|
|
1174
|
+
return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
1175
|
+
}
|
|
1176
|
+
var ACTION_SECRET_PREFIX = "topolo-secret:";
|
|
1177
|
+
function isActionSecretReference(value) {
|
|
1178
|
+
return typeof value === "string" && value.startsWith(ACTION_SECRET_PREFIX);
|
|
1179
|
+
}
|
|
1180
|
+
function isRecord(value) {
|
|
1181
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1182
|
+
}
|
|
1183
|
+
function sensitive(key, value) {
|
|
1184
|
+
const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
1185
|
+
if (normalized === "capability") {
|
|
1186
|
+
if (typeof value !== "string") return value !== null && value !== void 0 && typeof value !== "boolean" && typeof value !== "number";
|
|
1187
|
+
const text4 = value.trim();
|
|
1188
|
+
return Boolean(text4) && !/^[a-z][a-z0-9_-]{0,31}$/.test(text4);
|
|
1189
|
+
}
|
|
1190
|
+
return ["authorization", "cookie", "setcookie", "proxyauthorization"].includes(normalized) || /(token|secret|password|privatekey|apikey|backupcodes?|recoverycodes?)$/.test(normalized);
|
|
1191
|
+
}
|
|
1192
|
+
function maskActionSecrets(value, secrets) {
|
|
1193
|
+
let masked = value;
|
|
1194
|
+
for (const [secret, reference] of secrets) {
|
|
1195
|
+
const encoded = encodeURIComponent(secret);
|
|
1196
|
+
const variants = [.../* @__PURE__ */ new Set([secret, encoded])].map((item) => item.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
1197
|
+
masked = masked.replace(new RegExp(variants.join("|"), "g"), (match) => match === secret ? reference : encodeURIComponent(reference));
|
|
1198
|
+
}
|
|
1199
|
+
return masked;
|
|
1200
|
+
}
|
|
1201
|
+
async function resolveActionSecrets(value, store, secrets) {
|
|
1202
|
+
if (isActionSecretReference(value)) {
|
|
1203
|
+
if (!store) throw new TopoloSdkError("action_secret_store_required", "Protected action references require a secret store.");
|
|
1204
|
+
const resolved = await store.load(value);
|
|
1205
|
+
if (typeof resolved !== "string" || !resolved) throw new TopoloSdkError("action_secret_unsupported_type", "Protected action handoff requires a nonempty string credential.");
|
|
1206
|
+
secrets.set(resolved, value);
|
|
1207
|
+
return resolved;
|
|
1208
|
+
}
|
|
1209
|
+
if (Array.isArray(value)) return Promise.all(value.map((item) => resolveActionSecrets(item, store, secrets)));
|
|
1210
|
+
if (!isRecord(value)) return value;
|
|
1211
|
+
return Object.fromEntries(await Promise.all(Object.entries(value).map(async ([key, item]) => [key, await resolveActionSecrets(item, store, secrets)])));
|
|
1212
|
+
}
|
|
1213
|
+
async function protectActionResult(value, store, options = {}) {
|
|
1214
|
+
const secrets = /* @__PURE__ */ new Map();
|
|
1215
|
+
function documentation(item, key) {
|
|
1216
|
+
if (options.preserveActionSchemas === true && ["inputSchema", "outputSchema", "input_schema", "output_schema"].includes(key) && isRecord(item)) return true;
|
|
1217
|
+
if (options.preserveActionContracts === true && ["agentContract", "agent_contract"].includes(key) && isRecord(item)) return true;
|
|
1218
|
+
return options.preserveAgentGuidance === true && key === "agentGuidance" && isRecord(item) && item.schemaVersion === 1 && typeof item.kind === "string" && ["action-guide", "product-guide", "concept"].includes(item.kind);
|
|
1219
|
+
}
|
|
1220
|
+
function localizationMap(path) {
|
|
1221
|
+
const location = path.join("/");
|
|
1222
|
+
if (options.localizationAction === "sources.verify") return location === "data/hashes";
|
|
1223
|
+
if (options.localizationAction === "values.bulk_upsert") return location === "data/sourceHashes";
|
|
1224
|
+
return ["translation.release.prepare", "translation.release.import", "translation.release.get"].includes(options.localizationAction ?? "") && /^data\/bundle\/catalogs\/\*\/(sources|(?:packs|provenance)\/[^/]+)$/.test(location);
|
|
1225
|
+
}
|
|
1226
|
+
async function protect(item, key = "", path = []) {
|
|
1227
|
+
if (documentation(item, key)) return item;
|
|
1228
|
+
if (isActionSecretReference(item)) return item;
|
|
1229
|
+
if (Array.isArray(item) && /(?:backup|recovery)codes$/.test(key.toLowerCase().replace(/[^a-z0-9]/g, ""))) {
|
|
1230
|
+
return Promise.all(item.map((child) => protect(child, key, [...path, "*"])));
|
|
1231
|
+
}
|
|
1232
|
+
if (sensitive(key, item)) {
|
|
1233
|
+
const reference = store ? await store.save(item) : "[REDACTED]";
|
|
1234
|
+
if (typeof item === "string" && item) secrets.set(item, reference);
|
|
1235
|
+
return reference;
|
|
1236
|
+
}
|
|
1237
|
+
if (Array.isArray(item)) return Promise.all(item.map((child) => protect(child, "", [...path, "*"])));
|
|
1238
|
+
if (!isRecord(item)) return item;
|
|
1239
|
+
return Object.fromEntries(await Promise.all(Object.entries(item).map(async ([name, child]) => [name, await protect(child, localizationMap(path) ? "" : name, [...path, name])])));
|
|
1240
|
+
}
|
|
1241
|
+
const protectedValue = await protect(value);
|
|
1242
|
+
async function protectEmbedded(item, key = "") {
|
|
1243
|
+
if (documentation(item, key)) return item;
|
|
1244
|
+
if (typeof item === "string" && !isActionSecretReference(item) && maskActionSecrets(item, secrets) !== item) {
|
|
1245
|
+
return store ? store.save(item) : maskActionSecrets(item, secrets);
|
|
1246
|
+
}
|
|
1247
|
+
if (Array.isArray(item)) return Promise.all(item.map((child) => protectEmbedded(child)));
|
|
1248
|
+
if (!isRecord(item)) return item;
|
|
1249
|
+
return Object.fromEntries(await Promise.all(Object.entries(item).map(async ([key2, child]) => [key2, await protectEmbedded(child, key2)])));
|
|
1250
|
+
}
|
|
1251
|
+
return protectEmbedded(protectedValue);
|
|
1252
|
+
}
|
|
1253
|
+
function maskActionSecretValue(value, secrets) {
|
|
1254
|
+
if (value instanceof Error) return maskActionSecretError(value, secrets);
|
|
1255
|
+
if (typeof value === "string") return maskActionSecrets(value, secrets);
|
|
1256
|
+
if (Array.isArray(value)) return value.map((item) => maskActionSecretValue(item, secrets));
|
|
1257
|
+
if (!isRecord(value)) return value;
|
|
1258
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, maskActionSecretValue(item, secrets)]));
|
|
1259
|
+
}
|
|
1260
|
+
function maskActionSecretError(error, secrets) {
|
|
1261
|
+
if (!(error instanceof Error)) return maskActionSecretValue(error, secrets);
|
|
1262
|
+
const masked = Object.create(Object.getPrototypeOf(error));
|
|
1263
|
+
for (const key of Object.getOwnPropertyNames(error)) {
|
|
1264
|
+
const descriptor = Object.getOwnPropertyDescriptor(error, key);
|
|
1265
|
+
if ("value" in descriptor) descriptor.value = maskActionSecretValue(descriptor.value, secrets);
|
|
1266
|
+
Object.defineProperty(masked, key, descriptor);
|
|
1267
|
+
}
|
|
1268
|
+
return masked;
|
|
1269
|
+
}
|
|
1270
|
+
var encoder = new TextEncoder();
|
|
1271
|
+
function encodeBase64Url(value) {
|
|
1272
|
+
const bytes = value instanceof Uint8Array ? value : new Uint8Array(value);
|
|
1273
|
+
let binary = "";
|
|
1274
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
1275
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
1276
|
+
}
|
|
1277
|
+
function encodeJson(value) {
|
|
1278
|
+
return encodeBase64Url(encoder.encode(JSON.stringify(value)));
|
|
1279
|
+
}
|
|
1280
|
+
async function sha256Base64Url(value) {
|
|
1281
|
+
return encodeBase64Url(await crypto.subtle.digest("SHA-256", encoder.encode(value)));
|
|
1282
|
+
}
|
|
1283
|
+
function publicJwk(privateJwk) {
|
|
1284
|
+
const { crv, kty, x, y } = privateJwk;
|
|
1285
|
+
if (kty !== "EC" || crv !== "P-256" || !x || !y || !privateJwk.d) {
|
|
1286
|
+
throw new TypeError("A private P-256 JSON Web Key is required for DPoP signing.");
|
|
1287
|
+
}
|
|
1288
|
+
return { crv, kty, x, y };
|
|
1289
|
+
}
|
|
1290
|
+
function canonicalTargetUrl(value) {
|
|
1291
|
+
const url = new URL(value);
|
|
1292
|
+
return `${url.origin}${url.pathname}`;
|
|
1293
|
+
}
|
|
1294
|
+
async function calculateDpopJkt(privateJwk) {
|
|
1295
|
+
const jwk = publicJwk(privateJwk);
|
|
1296
|
+
return sha256Base64Url(JSON.stringify({ crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y }));
|
|
1297
|
+
}
|
|
1298
|
+
async function createDpopProof(input2) {
|
|
1299
|
+
const jwk = publicJwk(input2.privateJwk);
|
|
1300
|
+
const key = await crypto.subtle.importKey(
|
|
1301
|
+
"jwk",
|
|
1302
|
+
input2.privateJwk,
|
|
1303
|
+
{ name: "ECDSA", namedCurve: "P-256" },
|
|
1304
|
+
false,
|
|
1305
|
+
["sign"]
|
|
1306
|
+
);
|
|
1307
|
+
const header = encodeJson({ alg: "ES256", typ: "dpop+jwt", jwk });
|
|
1308
|
+
const claims = encodeJson({
|
|
1309
|
+
jti: crypto.randomUUID(),
|
|
1310
|
+
iat: Math.floor(Date.now() / 1e3),
|
|
1311
|
+
htm: input2.method.toUpperCase(),
|
|
1312
|
+
htu: canonicalTargetUrl(input2.targetUrl),
|
|
1313
|
+
ath: await sha256Base64Url(input2.accessToken)
|
|
1314
|
+
});
|
|
1315
|
+
const signature = await crypto.subtle.sign(
|
|
1316
|
+
{ name: "ECDSA", hash: "SHA-256" },
|
|
1317
|
+
key,
|
|
1318
|
+
encoder.encode(`${header}.${claims}`)
|
|
1319
|
+
);
|
|
1320
|
+
return `${header}.${claims}.${encodeBase64Url(signature)}`;
|
|
1321
|
+
}
|
|
1272
1322
|
var APP_API_URLS = {
|
|
1273
1323
|
auth: "https://auth.topolo.app",
|
|
1274
1324
|
developers: "https://developers.topolo.app"
|
|
@@ -2140,7 +2190,17 @@ var TopoloClient = class _TopoloClient {
|
|
|
2140
2190
|
* use and for the generic `topolo api` / MCP passthrough tool.
|
|
2141
2191
|
*/
|
|
2142
2192
|
async request(opts) {
|
|
2193
|
+
return this.requestWithTarget(opts);
|
|
2194
|
+
}
|
|
2195
|
+
async requestWithTarget(opts, publicAction) {
|
|
2143
2196
|
requireTopoloRuntimeEnvironment(this.environment);
|
|
2197
|
+
const publicOrigin = publicAction ? publicMarketingOrigin(publicAction, this.environment) : void 0;
|
|
2198
|
+
if (publicOrigin && (opts.actorEnvelope !== void 0 || opts.resource !== void 0)) {
|
|
2199
|
+
throw new TopoloSdkError("public_action_context_not_supported", "Public marketing actions do not accept actor or resource authority.");
|
|
2200
|
+
}
|
|
2201
|
+
if (publicOrigin && (!opts.path.startsWith("/") || opts.path.startsWith("//") || opts.path.includes("\\"))) {
|
|
2202
|
+
throw new TopoloSdkError("service_path_origin_mismatch", "Public action paths must be origin-relative paths.");
|
|
2203
|
+
}
|
|
2144
2204
|
const method = opts.method ?? "GET";
|
|
2145
2205
|
if (this.requireConfirmForWrites && WRITE_METHODS.has(method) && !opts.confirm) {
|
|
2146
2206
|
throw new TopoloConfirmationRequiredError(
|
|
@@ -2149,7 +2209,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2149
2209
|
}
|
|
2150
2210
|
const actionId = requestActionId(opts.headers);
|
|
2151
2211
|
const taskId = opts.actorEnvelope?.delegation?.taskId ?? this.actorContext?.taskId;
|
|
2152
|
-
let requestCredential = await this.loadCurrentCredential({
|
|
2212
|
+
let requestCredential = publicOrigin ? void 0 : await this.loadCurrentCredential({
|
|
2153
2213
|
service: normalizeLookupKey(opts.service),
|
|
2154
2214
|
method,
|
|
2155
2215
|
path: opts.path,
|
|
@@ -2157,7 +2217,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2157
2217
|
...taskId ? { taskId } : {},
|
|
2158
2218
|
...opts.resource ? { resource: opts.resource } : {}
|
|
2159
2219
|
});
|
|
2160
|
-
const resolvedService = opts.baseUrl ? { serviceKey: normalizeLookupKey(opts.service), baseUrl: this.validatedServiceOrigin(opts.service, opts.baseUrl) } : await this.resolveRequestService(opts.service);
|
|
2220
|
+
const resolvedService = publicOrigin ? { serviceKey: normalizeLookupKey(opts.service), baseUrl: publicOrigin } : opts.baseUrl ? { serviceKey: normalizeLookupKey(opts.service), baseUrl: this.validatedServiceOrigin(opts.service, opts.baseUrl) } : await this.resolveRequestService(opts.service);
|
|
2161
2221
|
const baseUrl = resolvedService.baseUrl;
|
|
2162
2222
|
const url = new URL(opts.path, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`);
|
|
2163
2223
|
if (url.origin !== new URL(baseUrl).origin) {
|
|
@@ -2178,17 +2238,21 @@ var TopoloClient = class _TopoloClient {
|
|
|
2178
2238
|
headers.set("Accept", "application/json");
|
|
2179
2239
|
if (opts.body !== void 0) headers.set("Content-Type", "application/json");
|
|
2180
2240
|
const platformAppId = resolveConfiguredAppId(resolvedService.serviceKey, this.appIds);
|
|
2181
|
-
if (platformAppId) headers.set("X-App-ID", platformAppId);
|
|
2182
|
-
const actorEnvelope = opts.actorEnvelope === void 0 ? void 0 : parseActorEnvelope(opts.actorEnvelope);
|
|
2241
|
+
if (platformAppId && !publicOrigin) headers.set("X-App-ID", platformAppId);
|
|
2242
|
+
const actorEnvelope = publicOrigin || opts.actorEnvelope === void 0 ? void 0 : parseActorEnvelope(opts.actorEnvelope);
|
|
2183
2243
|
const requestId = actorEnvelope?.action.requestId ?? generateRequestId();
|
|
2184
|
-
applyAuditHeaders(headers, this.agent, requestId);
|
|
2185
|
-
if (
|
|
2244
|
+
if (!publicOrigin) applyAuditHeaders(headers, this.agent, requestId);
|
|
2245
|
+
if (publicAction) {
|
|
2246
|
+
headers.set(TOPOLO_ACTION_ID_HEADER, publicAction.actionId);
|
|
2247
|
+
headers.set(TOPOLO_ACTION_NAME_HEADER, publicAction.name);
|
|
2248
|
+
}
|
|
2249
|
+
if (opts.headers && !publicOrigin) {
|
|
2186
2250
|
for (const [k, v] of Object.entries(opts.headers)) headers.set(k, v);
|
|
2187
2251
|
}
|
|
2188
2252
|
if (actorEnvelope) {
|
|
2189
2253
|
headers.set(TOPOLO_ACTOR_ENVELOPE_HEADER, encodeActorEnvelopeHeader(actorEnvelope));
|
|
2190
2254
|
}
|
|
2191
|
-
if (opts.resource) {
|
|
2255
|
+
if (opts.resource && !publicOrigin) {
|
|
2192
2256
|
const resourceType = opts.resource.resourceType.trim();
|
|
2193
2257
|
const resourceId = opts.resource.resourceId.trim();
|
|
2194
2258
|
if (!resourceType || !resourceId) {
|
|
@@ -2213,8 +2277,8 @@ var TopoloClient = class _TopoloClient {
|
|
|
2213
2277
|
const signal = opts.signal ? mergeSignals(opts.signal, controller.signal) : controller.signal;
|
|
2214
2278
|
try {
|
|
2215
2279
|
const requestHeaders = new Headers(headers);
|
|
2216
|
-
applyAuthHeaders(requestHeaders, requestCredential);
|
|
2217
|
-
if (requestCredential
|
|
2280
|
+
if (requestCredential) applyAuthHeaders(requestHeaders, requestCredential);
|
|
2281
|
+
if (requestCredential?.kind === "dpop_access_token") {
|
|
2218
2282
|
requestHeaders.set("DPoP", await createDpopProof({
|
|
2219
2283
|
accessToken: requestCredential.accessToken,
|
|
2220
2284
|
method,
|
|
@@ -2222,12 +2286,13 @@ var TopoloClient = class _TopoloClient {
|
|
|
2222
2286
|
privateJwk: requestCredential.privateJwk
|
|
2223
2287
|
}));
|
|
2224
2288
|
}
|
|
2225
|
-
|
|
2289
|
+
const init = {
|
|
2226
2290
|
method,
|
|
2227
2291
|
headers: requestHeaders,
|
|
2228
2292
|
body: opts.rawBody ?? (opts.body !== void 0 ? JSON.stringify(opts.body) : null),
|
|
2229
2293
|
signal
|
|
2230
|
-
}
|
|
2294
|
+
};
|
|
2295
|
+
return publicOrigin ? await fetchPublicMarketingAction((input2, requestInit) => this.fetchImpl(input2, requestInit), publicAction, this.environment, url, init) : await this.credentialedFetch(resolvedService.serviceKey, urlStr, init);
|
|
2231
2296
|
} catch (error) {
|
|
2232
2297
|
if (timedOut) {
|
|
2233
2298
|
throw new TopoloSdkError(
|
|
@@ -2235,6 +2300,9 @@ var TopoloClient = class _TopoloClient {
|
|
|
2235
2300
|
`Topolo request timed out after ${this.timeoutMs}ms. Verify current state before retrying a mutation.`
|
|
2236
2301
|
);
|
|
2237
2302
|
}
|
|
2303
|
+
if (publicOrigin && opts.signal?.aborted) {
|
|
2304
|
+
throw new TopoloSdkError("request_cancelled", "Public action request was cancelled.");
|
|
2305
|
+
}
|
|
2238
2306
|
throw error;
|
|
2239
2307
|
} finally {
|
|
2240
2308
|
clearTimeout(timeoutId);
|
|
@@ -2257,7 +2325,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2257
2325
|
try {
|
|
2258
2326
|
const attemptedCredential = requestCredential;
|
|
2259
2327
|
res = await fetchWithReadRetry();
|
|
2260
|
-
if (res.status === 401 && attemptedCredential
|
|
2328
|
+
if (res.status === 401 && attemptedCredential?.kind === "access_token" && this.refreshCredential) {
|
|
2261
2329
|
await res.body?.cancel().catch(() => void 0);
|
|
2262
2330
|
const refreshed = await this.refreshRejectedAccessToken(attemptedCredential.accessToken);
|
|
2263
2331
|
if (refreshed) {
|
|
@@ -2411,6 +2479,9 @@ var TopoloClient = class _TopoloClient {
|
|
|
2411
2479
|
return fetchWithCredentialBoundary((input2, requestInit) => this.fetchImpl(input2, requestInit), this.environment, service, target, init);
|
|
2412
2480
|
}
|
|
2413
2481
|
validatedActionEntry(entry) {
|
|
2482
|
+
if (isOnePublicMarketingAction(entry)) {
|
|
2483
|
+
return { ...entry, apiBaseUrl: publicMarketingOrigin(entry, this.environment) };
|
|
2484
|
+
}
|
|
2414
2485
|
if (!entry.apiBaseUrl) return entry;
|
|
2415
2486
|
return {
|
|
2416
2487
|
...entry,
|
|
@@ -2652,7 +2723,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2652
2723
|
"TopoloAuth did not return an action catalog for the current credential."
|
|
2653
2724
|
);
|
|
2654
2725
|
}
|
|
2655
|
-
const entries = raw.map((item) => normalizeActionCatalogEntry(item)).filter((entry) => Boolean(entry))
|
|
2726
|
+
const entries = raw.map((item) => normalizeActionCatalogEntry(item)).filter((entry) => Boolean(entry));
|
|
2656
2727
|
return {
|
|
2657
2728
|
actions: entries,
|
|
2658
2729
|
page: normalizeCatalogPage(
|
|
@@ -2717,11 +2788,18 @@ var TopoloClient = class _TopoloClient {
|
|
|
2717
2788
|
const raw = res.data?.action ?? res.action;
|
|
2718
2789
|
const match = normalizeActionCatalogEntry(raw);
|
|
2719
2790
|
if (!match) throw new TopoloSdkError("unknown_action", `Unknown or unavailable Topolo action "${action}".`);
|
|
2791
|
+
if (isOnePublicMarketingAction(match) && match.actionId !== actionId) {
|
|
2792
|
+
throw new TopoloSdkError("action_contract_mismatch", "Public action catalog response does not match the requested action ID.");
|
|
2793
|
+
}
|
|
2720
2794
|
return this.validatedActionEntry(match);
|
|
2721
2795
|
}
|
|
2722
2796
|
async callAction(action, input2 = {}, options = {}) {
|
|
2723
|
-
const entry = await this.getAction(action);
|
|
2724
|
-
|
|
2797
|
+
const entry = Object.freeze({ ...await this.getAction(action) });
|
|
2798
|
+
const publicAction = isOnePublicMarketingAction(entry);
|
|
2799
|
+
if (publicAction && entry.actionId !== action.trim()) {
|
|
2800
|
+
throw new TopoloSdkError("action_contract_mismatch", "Public action catalog response does not match the requested action ID.");
|
|
2801
|
+
}
|
|
2802
|
+
return this.executeResolvedAction(entry, input2, options, false, publicAction);
|
|
2725
2803
|
}
|
|
2726
2804
|
async issueExternalAgentCredential(input2) {
|
|
2727
2805
|
const actionId = "app_topolo_auth.principal_credentials.issue";
|
|
@@ -2865,7 +2943,15 @@ var TopoloClient = class _TopoloClient {
|
|
|
2865
2943
|
}
|
|
2866
2944
|
return this.executeResolvedAction(entry, input2, options);
|
|
2867
2945
|
}
|
|
2868
|
-
async executeResolvedAction(entry, input2, options, preserveSensitiveResult = false) {
|
|
2946
|
+
async executeResolvedAction(entry, input2, options, preserveSensitiveResult = false, allowPublicMarketing = false) {
|
|
2947
|
+
if (isOnePublicMarketingAction(entry)) {
|
|
2948
|
+
if (!allowPublicMarketing) {
|
|
2949
|
+
throw new TopoloSdkError("public_action_entrypoint_required", "Public marketing actions require callAction.");
|
|
2950
|
+
}
|
|
2951
|
+
if (options.actorEnvelope !== void 0 || options.resource !== void 0) {
|
|
2952
|
+
throw new TopoloSdkError("public_action_context_not_supported", "Public marketing actions do not accept actor or resource authority.");
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2869
2955
|
const agentAccess = entry.agentAccess ?? (entry.destructive ? "off" : entry.readOnly && !entry.requiresConfirmation ? "auto" : "confirm");
|
|
2870
2956
|
if (agentAccess === "off") {
|
|
2871
2957
|
throw new TopoloPermissionError(
|
|
@@ -2894,7 +2980,8 @@ var TopoloClient = class _TopoloClient {
|
|
|
2894
2980
|
);
|
|
2895
2981
|
}
|
|
2896
2982
|
const mapped = mapActionInput(entry, input2);
|
|
2897
|
-
const
|
|
2983
|
+
const publicAction = isOnePublicMarketingAction(entry);
|
|
2984
|
+
const resolvedActorEnvelope = publicAction ? void 0 : options.actorEnvelope ?? await this.buildVerifiedAgentActorEnvelope(entry.actionId, input2, options.resource);
|
|
2898
2985
|
if (resolvedActorEnvelope) {
|
|
2899
2986
|
const actorEnvelope = parseActorEnvelope(resolvedActorEnvelope);
|
|
2900
2987
|
if (actorEnvelope.action.actionId !== entry.actionId) {
|
|
@@ -2911,8 +2998,9 @@ var TopoloClient = class _TopoloClient {
|
|
|
2911
2998
|
const service = entry.appSlug || entry.appId;
|
|
2912
2999
|
let result;
|
|
2913
3000
|
try {
|
|
2914
|
-
result = await this.
|
|
3001
|
+
result = await this.requestWithTarget({
|
|
2915
3002
|
service,
|
|
3003
|
+
signal: options.signal,
|
|
2916
3004
|
...entry.apiBaseUrl ? { baseUrl: entry.apiBaseUrl } : {},
|
|
2917
3005
|
method: entry.method,
|
|
2918
3006
|
path: mapped.path,
|
|
@@ -2925,7 +3013,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2925
3013
|
[TOPOLO_ACTION_NAME_HEADER]: entry.name
|
|
2926
3014
|
},
|
|
2927
3015
|
confirm: options.confirm === true || entry.readOnly && !entry.destructive && !entry.requiresConfirmation
|
|
2928
|
-
});
|
|
3016
|
+
}, publicAction ? entry : void 0);
|
|
2929
3017
|
} catch (error) {
|
|
2930
3018
|
throw maskActionSecretError(error, this.actionSecrets);
|
|
2931
3019
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topolo/cli",
|
|
3
3
|
"packageManager": "pnpm@10.17.1",
|
|
4
|
-
"version": "0.13.
|
|
5
|
-
"topoloPublishedVersion": "0.13.
|
|
4
|
+
"version": "0.13.27",
|
|
5
|
+
"topoloPublishedVersion": "0.13.27",
|
|
6
6
|
"description": "Public command-line interface for Topolo customer organizations, developers, and agents.",
|
|
7
7
|
"license": "UNLICENSED",
|
|
8
8
|
"author": "Topolo",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@modelcontextprotocol/sdk": "1.31.0",
|
|
36
|
-
"@topolo/mcp": "0.14.
|
|
37
|
-
"@topolo/sdk": "0.24.
|
|
36
|
+
"@topolo/mcp": "0.14.39",
|
|
37
|
+
"@topolo/sdk": "0.24.1",
|
|
38
38
|
"commander": "^12.1.0",
|
|
39
39
|
"undici": "6.29.0"
|
|
40
40
|
},
|