@topolo/cli 0.12.12 → 0.12.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +40 -36
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import { platform as platform2 } from "os";
9
9
  import { createInterface } from "readline/promises";
10
10
  import { stdin as input } from "process";
11
11
 
12
- // node_modules/.pnpm/@topolo+sdk@0.22.0/node_modules/@topolo/sdk/dist/index.js
12
+ // node_modules/@topolo/sdk/dist/index.js
13
13
  function applyAuthHeaders(headers, credential) {
14
14
  if (credential.kind === "api_key") {
15
15
  headers.set("X-Api-Key", credential.apiKey);
@@ -124,9 +124,9 @@ function canonicalTopoloServiceErrorCode(value) {
124
124
  }
125
125
  function sanitizeTopoloServiceMessage(value) {
126
126
  if (typeof value !== "string") return void 0;
127
- const text2 = value.replace(/[\u0000-\u001f\u007f-\u009f\u200b-\u200f\u2028-\u202e\u2066-\u2069\ufeff]/g, " ").replace(/\b[a-z][a-z0-9+.-]*:\/\/\S+/gi, "[url]").replace(/[^\s@<>()[\],;:"']+@[^\s@<>()[\],;:"']+\.[a-z]{2,}/gi, "[email]").replace(/[A-Za-z0-9_\-+/=.]{20,}/g, (run) => /[0-9]/.test(run) && /[A-Za-z]/.test(run) ? "[redacted]" : run).replace(/\s+/g, " ").trim();
128
- if (!text2) return void 0;
129
- return text2.length > SERVICE_MESSAGE_MAX_LENGTH ? `${text2.slice(0, SERVICE_MESSAGE_MAX_LENGTH - 1).trimEnd()}\u2026` : text2;
127
+ const text3 = value.replace(/[\u0000-\u001f\u007f-\u009f\u200b-\u200f\u2028-\u202e\u2066-\u2069\ufeff]/g, " ").replace(/\b[a-z][a-z0-9+.-]*:\/\/\S+/gi, "[url]").replace(/[^\s@<>()[\],;:"']+@[^\s@<>()[\],;:"']+\.[a-z]{2,}/gi, "[email]").replace(/[A-Za-z0-9_\-+/=.]{20,}/g, (run) => /[0-9]/.test(run) && /[A-Za-z]/.test(run) ? "[redacted]" : run).replace(/\s+/g, " ").trim();
128
+ if (!text3) return void 0;
129
+ return text3.length > SERVICE_MESSAGE_MAX_LENGTH ? `${text3.slice(0, SERVICE_MESSAGE_MAX_LENGTH - 1).trimEnd()}\u2026` : text3;
130
130
  }
131
131
  function canonicalTopoloRequestId(value) {
132
132
  if (typeof value !== "string") return void 0;
@@ -194,10 +194,10 @@ var TopoloPermissionError = class extends TopoloSdkError {
194
194
  };
195
195
  function extractTopoloServiceErrorCode(body) {
196
196
  if (!body || typeof body !== "object" || Array.isArray(body)) return null;
197
- const record2 = body;
198
- const topLevel = canonicalTopoloServiceErrorCode(record2.code);
197
+ const record3 = body;
198
+ const topLevel = canonicalTopoloServiceErrorCode(record3.code);
199
199
  if (topLevel) return topLevel;
200
- const nested = record2.error;
200
+ const nested = record3.error;
201
201
  const nestedString = canonicalTopoloServiceErrorCode(nested);
202
202
  if (nestedString) return nestedString;
203
203
  if (nested && typeof nested === "object" && !Array.isArray(nested)) {
@@ -209,13 +209,13 @@ function extractTopoloServiceErrorCode(body) {
209
209
  }
210
210
  function extractTopoloServiceErrorMessage(body) {
211
211
  if (!body || typeof body !== "object" || Array.isArray(body)) return void 0;
212
- const record2 = body;
213
- const nested = record2.error;
212
+ const record3 = body;
213
+ const nested = record3.error;
214
214
  const candidates = [];
215
215
  if (nested && typeof nested === "object" && !Array.isArray(nested)) {
216
216
  candidates.push(nested.message);
217
217
  }
218
- candidates.push(record2.message, record2.error_description);
218
+ candidates.push(record3.message, record3.error_description);
219
219
  if (typeof nested === "string" && !canonicalTopoloServiceErrorCode(nested)) candidates.push(nested);
220
220
  for (const candidate of candidates) {
221
221
  const message2 = sanitizeTopoloServiceMessage(candidate);
@@ -228,14 +228,14 @@ function serviceErrorCode(body, fallback) {
228
228
  }
229
229
  function extractTopoloServiceErrorDetails(body) {
230
230
  if (!body || typeof body !== "object" || Array.isArray(body)) return void 0;
231
- const record2 = body;
232
- let candidate = record2.details;
233
- const nested = record2.error;
231
+ const record3 = body;
232
+ let candidate = record3.details;
233
+ const nested = record3.error;
234
234
  if (nested && typeof nested === "object" && !Array.isArray(nested)) {
235
235
  const nestedRecord = nested;
236
236
  if (candidate === void 0) candidate = nestedRecord.details ?? nestedRecord;
237
237
  }
238
- if (candidate === void 0) candidate = record2;
238
+ if (candidate === void 0) candidate = record3;
239
239
  if (Array.isArray(candidate)) return validationIssueDetails(canonicalTopoloValidationIssues(candidate)) ?? void 0;
240
240
  if (!candidate || typeof candidate !== "object") return void 0;
241
241
  const source = candidate;
@@ -294,18 +294,18 @@ function validationIssueDetails(issues) {
294
294
  return paths.length ? { paths, issues } : { issues };
295
295
  }
296
296
  function issue(path, message2) {
297
- const text2 = sanitizeTopoloServiceMessage(message2);
298
- if (!path && !text2) return null;
299
- return { ...path ? { path } : {}, ...text2 ? { message: text2 } : {} };
297
+ const text3 = sanitizeTopoloServiceMessage(message2);
298
+ if (!path && !text3) return null;
299
+ return { ...path ? { path } : {}, ...text3 ? { message: text3 } : {} };
300
300
  }
301
301
  function canonicalTopoloValidationIssues(values) {
302
302
  const issues = [];
303
303
  for (const value of values) {
304
304
  if (!value || typeof value !== "object" || Array.isArray(value)) continue;
305
- const record2 = value;
306
- const path = canonicalTopoloValidationPath(record2.field) ?? canonicalTopoloValidationPath(record2.path);
305
+ const record3 = value;
306
+ const path = canonicalTopoloValidationPath(record3.field) ?? canonicalTopoloValidationPath(record3.path);
307
307
  if (!path) continue;
308
- const projected = issue(path, record2.message);
308
+ const projected = issue(path, record3.message);
309
309
  if (projected) issues.push(projected);
310
310
  if (issues.length === SERVICE_ISSUE_LIMIT) break;
311
311
  }
@@ -437,10 +437,10 @@ function sensitive(key, value) {
437
437
  const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
438
438
  if (normalized === "capability") {
439
439
  if (typeof value !== "string") return value !== null && value !== void 0 && typeof value !== "boolean" && typeof value !== "number";
440
- const text2 = value.trim();
441
- return Boolean(text2) && !/^[a-z][a-z0-9_-]{0,31}$/.test(text2);
440
+ const text3 = value.trim();
441
+ return Boolean(text3) && !/^[a-z][a-z0-9_-]{0,31}$/.test(text3);
442
442
  }
443
- return ["authorization", "cookie", "setcookie", "proxyauthorization"].includes(normalized) || /(token|secret|password|privatekey|apikey)$/.test(normalized);
443
+ return ["authorization", "cookie", "setcookie", "proxyauthorization"].includes(normalized) || /(token|secret|password|privatekey|apikey|backupcodes?|recoverycodes?)$/.test(normalized);
444
444
  }
445
445
  function maskActionSecrets(value, secrets) {
446
446
  let masked = value;
@@ -467,6 +467,9 @@ async function protectActionResult(value, store) {
467
467
  const secrets = /* @__PURE__ */ new Map();
468
468
  async function protect(item, key = "") {
469
469
  if (isActionSecretReference(item)) return item;
470
+ if (Array.isArray(item) && /(?:backup|recovery)codes$/.test(key.toLowerCase().replace(/[^a-z0-9]/g, ""))) {
471
+ return Promise.all(item.map((child) => protect(child, key)));
472
+ }
470
473
  if (sensitive(key, item)) {
471
474
  const reference = store ? await store.save(item) : "[REDACTED]";
472
475
  if (typeof item === "string" && item) secrets.set(item, reference);
@@ -722,7 +725,7 @@ function inspectSchema(schema, path, root, depth) {
722
725
  if (unsupportedKeyword) {
723
726
  return { path, code: "unsupported_schema_keyword", message: `Action schema uses unsupported keyword ${unsupportedKeyword}.` };
724
727
  }
725
- if (typeof schema.format === "string" && !["uri", "email", "date-time"].includes(schema.format)) {
728
+ if (typeof schema.format === "string" && !["uri", "email", "date-time", "uuid"].includes(schema.format)) {
726
729
  return { path, code: "unsupported_schema_format", message: `Action schema uses unsupported format ${schema.format}.` };
727
730
  }
728
731
  if (typeof schema.$ref === "string" && !resolveLocalReference(root, schema.$ref)) {
@@ -859,6 +862,7 @@ function validateString(schema, value, path, errors) {
859
862
  if (schema.format === "uri" && !isUrl(value)) errors.push({ path, code: "format_uri", message: "Expected an absolute URL." });
860
863
  if (schema.format === "email" && !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(value)) errors.push({ path, code: "format_email", message: "Expected an email address." });
861
864
  if (schema.format === "date-time" && !isDateTime(value)) errors.push({ path, code: "format_date_time", message: "Expected an ISO-8601 date-time." });
865
+ if (schema.format === "uuid" && (value.length !== 36 || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value))) errors.push({ path, code: "format_uuid", message: "Expected a hyphenated UUID." });
862
866
  }
863
867
  function validateNumber(schema, value, path, errors) {
864
868
  if (typeof schema.minimum === "number" && value < schema.minimum) errors.push({ path, code: "minimum", message: `Expected a value of at least ${schema.minimum}.` });
@@ -1916,14 +1920,14 @@ var TopoloClient = class _TopoloClient {
1916
1920
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
1917
1921
  throw new TopoloSdkError("action_catalog_summary_unavailable", "Action catalog summary is unavailable.");
1918
1922
  }
1919
- const record2 = raw;
1920
- if (record2.algorithm !== "sha256-v1" || typeof record2.digest !== "string" || !/^[a-f0-9]{64}$/.test(record2.digest) || !Number.isSafeInteger(record2.actionCount) || Number(record2.actionCount) < 0) {
1923
+ const record3 = raw;
1924
+ if (record3.algorithm !== "sha256-v1" || typeof record3.digest !== "string" || !/^[a-f0-9]{64}$/.test(record3.digest) || !Number.isSafeInteger(record3.actionCount) || Number(record3.actionCount) < 0) {
1921
1925
  throw new TopoloSdkError("action_catalog_summary_unavailable", "Action catalog summary is invalid.");
1922
1926
  }
1923
1927
  return {
1924
1928
  algorithm: "sha256-v1",
1925
- digest: record2.digest,
1926
- actionCount: Number(record2.actionCount)
1929
+ digest: record3.digest,
1930
+ actionCount: Number(record3.actionCount)
1927
1931
  };
1928
1932
  }
1929
1933
  /** @deprecated Prefer searchActions() so callers retain the continuation cursor. */
@@ -2641,10 +2645,10 @@ function extractRequired(body) {
2641
2645
  if (Array.isArray(maybe.required)) return canonicalTopoloRequired(maybe.required);
2642
2646
  for (const nested of [maybe.details, maybe.error]) {
2643
2647
  if (!nested || typeof nested !== "object" || Array.isArray(nested)) continue;
2644
- const record2 = nested;
2645
- if (Array.isArray(record2.required)) return canonicalTopoloRequired(record2.required);
2646
- if (record2.details && typeof record2.details === "object" && !Array.isArray(record2.details)) {
2647
- const required = record2.details.required;
2648
+ const record3 = nested;
2649
+ if (Array.isArray(record3.required)) return canonicalTopoloRequired(record3.required);
2650
+ if (record3.details && typeof record3.details === "object" && !Array.isArray(record3.details)) {
2651
+ const required = record3.details.required;
2648
2652
  if (Array.isArray(required)) return canonicalTopoloRequired(required);
2649
2653
  }
2650
2654
  }
@@ -2719,8 +2723,8 @@ function compactResultValue(value, depth, budget) {
2719
2723
  return value.length > ACTION_RESULT_MAX_ITEMS ? { count: value.length, items, omittedItems: value.length - ACTION_RESULT_MAX_ITEMS } : items;
2720
2724
  }
2721
2725
  if (typeof value === "object") {
2722
- const record2 = value;
2723
- const allKeys = Object.keys(record2);
2726
+ const record3 = value;
2727
+ const allKeys = Object.keys(record3);
2724
2728
  const ranked = allKeys.sort((left, right) => resultKeyPriority(left) - resultKeyPriority(right));
2725
2729
  const prioritized = ranked.filter((key) => resultKeyPriority(key) < 2);
2726
2730
  const ordinary = ranked.filter((key) => resultKeyPriority(key) === 2);
@@ -2729,7 +2733,7 @@ function compactResultValue(value, depth, budget) {
2729
2733
  ...prioritized,
2730
2734
  ...ordinary.slice(0, ordinaryLimit)
2731
2735
  ].slice(0, ACTION_RESULT_MAX_KEYS);
2732
- const compact = Object.fromEntries(keys.map((key) => [key, compactResultValue(record2[key], depth + 1, budget)]));
2736
+ const compact = Object.fromEntries(keys.map((key) => [key, compactResultValue(record3[key], depth + 1, budget)]));
2733
2737
  if (allKeys.length > keys.length) compact["_omittedKeys"] = allKeys.length - keys.length;
2734
2738
  return compact;
2735
2739
  }
@@ -3493,7 +3497,7 @@ function createTopolo(options) {
3493
3497
  };
3494
3498
  }
3495
3499
 
3496
- // node_modules/.pnpm/@topolo+sdk@0.22.0/node_modules/@topolo/sdk/dist/node/credential-store.js
3500
+ // node_modules/@topolo/sdk/dist/node/credential-store.js
3497
3501
  import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2, chmod as chmod2, rm as rm2, stat } from "fs/promises";
3498
3502
  import { existsSync as existsSync2 } from "fs";
3499
3503
  import { homedir as homedir2, platform } from "os";
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.12.12",
5
- "topoloPublishedVersion": "0.12.12",
4
+ "version": "0.12.14",
5
+ "topoloPublishedVersion": "0.12.14",
6
6
  "description": "Public command-line interface for Topolo customer organizations, developers, and agents.",
7
7
  "license": "UNLICENSED",
8
8
  "author": "Topolo",
@@ -28,8 +28,8 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@modelcontextprotocol/sdk": "^1.0.0",
31
- "@topolo/mcp": "0.14.5",
32
- "@topolo/sdk": "0.22.0",
31
+ "@topolo/mcp": "0.14.7",
32
+ "@topolo/sdk": "0.23.2",
33
33
  "commander": "^12.1.0"
34
34
  },
35
35
  "devDependencies": {