@topolo/cli 0.12.20 → 0.12.21

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 +78 -58
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -9,7 +9,24 @@ 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.23.8/node_modules/@topolo/sdk/dist/index.js
12
+ // node_modules/@topolo/sdk/dist/index.js
13
+ function record(value) {
14
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
15
+ }
16
+ function strings(value) {
17
+ return Array.isArray(value) && value.length > 0 && value.every((entry) => typeof entry === "string" && entry.trim().length > 0) && new Set(value).size === value.length;
18
+ }
19
+ function validTopoloActionAccessPolicy(value) {
20
+ if (!record(value) || Object.keys(value).some((key) => key !== "human" && key !== "service") || !value.human && !value.service) return false;
21
+ if (value.human !== void 0) {
22
+ const human = value.human;
23
+ if (!record(human) || Object.keys(human).some((key) => !["organizationId", "permissionAnyOf", "platformAccess"].includes(key)) || Object.keys(human).length === 0 || human.organizationId !== void 0 && (typeof human.organizationId !== "string" || !human.organizationId.trim()) || human.permissionAnyOf !== void 0 && !strings(human.permissionAnyOf) || human.platformAccess !== void 0 && !["platform_admin", "platform_super_admin"].includes(String(human.platformAccess))) return false;
24
+ }
25
+ if (value.service !== void 0) {
26
+ if (!record(value.service) || Object.keys(value.service).some((key) => key !== "scopeAnyOf") || !strings(value.service.scopeAnyOf)) return false;
27
+ }
28
+ return true;
29
+ }
13
30
  function applyAuthHeaders(headers, credential) {
14
31
  if (credential.kind === "api_key") {
15
32
  headers.set("X-Api-Key", credential.apiKey);
@@ -194,10 +211,10 @@ var TopoloPermissionError = class extends TopoloSdkError {
194
211
  };
195
212
  function extractTopoloServiceErrorCode(body) {
196
213
  if (!body || typeof body !== "object" || Array.isArray(body)) return null;
197
- const record3 = body;
198
- const topLevel = canonicalTopoloServiceErrorCode(record3.code);
214
+ const record4 = body;
215
+ const topLevel = canonicalTopoloServiceErrorCode(record4.code);
199
216
  if (topLevel) return topLevel;
200
- const nested = record3.error;
217
+ const nested = record4.error;
201
218
  const nestedString = canonicalTopoloServiceErrorCode(nested);
202
219
  if (nestedString) return nestedString;
203
220
  if (nested && typeof nested === "object" && !Array.isArray(nested)) {
@@ -209,13 +226,13 @@ function extractTopoloServiceErrorCode(body) {
209
226
  }
210
227
  function extractTopoloServiceErrorMessage(body) {
211
228
  if (!body || typeof body !== "object" || Array.isArray(body)) return void 0;
212
- const record3 = body;
213
- const nested = record3.error;
229
+ const record4 = body;
230
+ const nested = record4.error;
214
231
  const candidates = [];
215
232
  if (nested && typeof nested === "object" && !Array.isArray(nested)) {
216
233
  candidates.push(nested.message);
217
234
  }
218
- candidates.push(record3.message, record3.error_description);
235
+ candidates.push(record4.message, record4.error_description);
219
236
  if (typeof nested === "string" && !canonicalTopoloServiceErrorCode(nested)) candidates.push(nested);
220
237
  for (const candidate of candidates) {
221
238
  const message2 = sanitizeTopoloServiceMessage(candidate);
@@ -228,14 +245,14 @@ function serviceErrorCode(body, fallback) {
228
245
  }
229
246
  function extractTopoloServiceErrorDetails(body) {
230
247
  if (!body || typeof body !== "object" || Array.isArray(body)) return void 0;
231
- const record3 = body;
232
- let candidate = record3.details;
233
- const nested = record3.error;
248
+ const record4 = body;
249
+ let candidate = record4.details;
250
+ const nested = record4.error;
234
251
  if (nested && typeof nested === "object" && !Array.isArray(nested)) {
235
252
  const nestedRecord = nested;
236
253
  if (candidate === void 0) candidate = nestedRecord.details ?? nestedRecord;
237
254
  }
238
- if (candidate === void 0) candidate = record3;
255
+ if (candidate === void 0) candidate = record4;
239
256
  if (Array.isArray(candidate)) return validationIssueDetails(canonicalTopoloValidationIssues(candidate)) ?? void 0;
240
257
  if (!candidate || typeof candidate !== "object") return void 0;
241
258
  const source = candidate;
@@ -302,10 +319,10 @@ function canonicalTopoloValidationIssues(values) {
302
319
  const issues = [];
303
320
  for (const value of values) {
304
321
  if (!value || typeof value !== "object" || Array.isArray(value)) continue;
305
- const record3 = value;
306
- const path = canonicalTopoloValidationPath(record3.field) ?? canonicalTopoloValidationPath(record3.path);
322
+ const record4 = value;
323
+ const path = canonicalTopoloValidationPath(record4.field) ?? canonicalTopoloValidationPath(record4.path);
307
324
  if (!path) continue;
308
- const projected = issue(path, record3.message);
325
+ const projected = issue(path, record4.message);
309
326
  if (projected) issues.push(projected);
310
327
  if (issues.length === SERVICE_ISSUE_LIMIT) break;
311
328
  }
@@ -1000,7 +1017,7 @@ var ActorEnvelopeValidationError = class extends Error {
1000
1017
  }
1001
1018
  };
1002
1019
  function parseActorEnvelope(value) {
1003
- const envelope = record(value, "actorEnvelope");
1020
+ const envelope = record2(value, "actorEnvelope");
1004
1021
  exactKeys(envelope, [
1005
1022
  "schemaVersion",
1006
1023
  "organizationId",
@@ -1025,13 +1042,13 @@ function parseActorEnvelope(value) {
1025
1042
  if (expiresAt && Date.parse(expiresAt) <= Date.parse(issuedAt)) {
1026
1043
  fail("actorEnvelope.expiresAt", "must be later than issuedAt");
1027
1044
  }
1028
- const assuranceValue = record(envelope.assurance, "actorEnvelope.assurance");
1045
+ const assuranceValue = record2(envelope.assurance, "actorEnvelope.assurance");
1029
1046
  exactKeys(assuranceValue, ["level", "methods"], "actorEnvelope.assurance");
1030
1047
  const assurance = {
1031
1048
  level: member(assuranceValue.level, ASSURANCE_LEVELS, "actorEnvelope.assurance.level"),
1032
1049
  methods: textArray(assuranceValue.methods, "actorEnvelope.assurance.methods")
1033
1050
  };
1034
- const actionValue = record(envelope.action, "actorEnvelope.action");
1051
+ const actionValue = record2(envelope.action, "actorEnvelope.action");
1035
1052
  exactKeys(actionValue, ["requestId", "actionId", "resourceType", "resourceId", "inputHash"], "actorEnvelope.action");
1036
1053
  const inputHash = text(actionValue.inputHash, "actorEnvelope.action.inputHash");
1037
1054
  if (!HASH_PATTERN.test(inputHash)) fail("actorEnvelope.action.inputHash", "must be a lowercase sha256 digest");
@@ -1101,7 +1118,7 @@ function canonicalJson(value) {
1101
1118
  }
1102
1119
  function parseAccountableSubject(value) {
1103
1120
  const path = "actorEnvelope.accountableSubject";
1104
- const subject = record(value, path);
1121
+ const subject = record2(value, path);
1105
1122
  exactKeys(subject, ["principalType", "principalId", "displayName"], path);
1106
1123
  return {
1107
1124
  principalType: member(subject.principalType, ACCOUNTABLE_SUBJECT_TYPES, `${path}.principalType`),
@@ -1115,7 +1132,7 @@ async function sha256CanonicalValue(value) {
1115
1132
  return `sha256:${Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
1116
1133
  }
1117
1134
  function parseIdentity(value, path) {
1118
- const identity = record(value, path);
1135
+ const identity = record2(value, path);
1119
1136
  exactKeys(identity, [
1120
1137
  "principalType",
1121
1138
  "principalId",
@@ -1141,7 +1158,7 @@ function parseIdentity(value, path) {
1141
1158
  }
1142
1159
  function parseDelegation(value) {
1143
1160
  if (value === null) return null;
1144
- const delegation = record(value, "actorEnvelope.delegation");
1161
+ const delegation = record2(value, "actorEnvelope.delegation");
1145
1162
  exactKeys(delegation, ["taskId", "runId", "lineage"], "actorEnvelope.delegation");
1146
1163
  if (!Array.isArray(delegation.lineage) || delegation.lineage.length === 0 || delegation.lineage.length > 16) {
1147
1164
  fail("actorEnvelope.delegation.lineage", "must contain between 1 and 16 hops");
@@ -1150,7 +1167,7 @@ function parseDelegation(value) {
1150
1167
  taskId: text(delegation.taskId, "actorEnvelope.delegation.taskId"),
1151
1168
  runId: text(delegation.runId, "actorEnvelope.delegation.runId"),
1152
1169
  lineage: delegation.lineage.map((value2, index) => {
1153
- const hop = record(value2, `actorEnvelope.delegation.lineage[${index}]`);
1170
+ const hop = record2(value2, `actorEnvelope.delegation.lineage[${index}]`);
1154
1171
  exactKeys(hop, ["principalType", "principalId"], `actorEnvelope.delegation.lineage[${index}]`);
1155
1172
  return {
1156
1173
  principalType: member(hop.principalType, PRINCIPAL_TYPES, `actorEnvelope.delegation.lineage[${index}].principalType`),
@@ -1159,7 +1176,7 @@ function parseDelegation(value) {
1159
1176
  })
1160
1177
  };
1161
1178
  }
1162
- function record(value, path) {
1179
+ function record2(value, path) {
1163
1180
  if (!value || typeof value !== "object" || Array.isArray(value)) fail(path, "must be an object");
1164
1181
  return value;
1165
1182
  }
@@ -1969,14 +1986,14 @@ var TopoloClient = class _TopoloClient {
1969
1986
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
1970
1987
  throw new TopoloSdkError("action_catalog_summary_unavailable", "Action catalog summary is unavailable.");
1971
1988
  }
1972
- const record3 = raw;
1973
- if (record3.algorithm !== "sha256-v1" || typeof record3.digest !== "string" || !/^[a-f0-9]{64}$/.test(record3.digest) || !Number.isSafeInteger(record3.actionCount) || Number(record3.actionCount) < 0) {
1989
+ const record4 = raw;
1990
+ if (record4.algorithm !== "sha256-v1" || typeof record4.digest !== "string" || !/^[a-f0-9]{64}$/.test(record4.digest) || !Number.isSafeInteger(record4.actionCount) || Number(record4.actionCount) < 0) {
1974
1991
  throw new TopoloSdkError("action_catalog_summary_unavailable", "Action catalog summary is invalid.");
1975
1992
  }
1976
1993
  return {
1977
1994
  algorithm: "sha256-v1",
1978
- digest: record3.digest,
1979
- actionCount: Number(record3.actionCount)
1995
+ digest: record4.digest,
1996
+ actionCount: Number(record4.actionCount)
1980
1997
  };
1981
1998
  }
1982
1999
  /** @deprecated Prefer searchActions() so callers retain the continuation cursor. */
@@ -2573,6 +2590,7 @@ function normalizeActionCatalogEntry(item) {
2573
2590
  permissionName: pickActionString(a.permission_name) ?? pickActionString(a.permissionName) ?? "",
2574
2591
  requiredPermission: pickActionString(a.required_permission) ?? pickActionString(a.requiredPermission) ?? "",
2575
2592
  principalAccess: pickPrincipalAccess(a.principal_access ?? a.principalAccess),
2593
+ ...validTopoloActionAccessPolicy(a.access_policy ?? a.accessPolicy) ? { accessPolicy: a.access_policy ?? a.accessPolicy } : {},
2576
2594
  authorizationMode: pickAuthorizationMode(a.authorization_mode ?? a.authorizationMode),
2577
2595
  allowedServices: stringArray(a.allowed_services ?? a.allowedServices),
2578
2596
  inputSchema: plainObject(a.input_schema ?? a.inputSchema),
@@ -2590,7 +2608,7 @@ function isHttpMethod(value) {
2590
2608
  return value === "GET" || value === "POST" || value === "PUT" || value === "PATCH" || value === "DELETE";
2591
2609
  }
2592
2610
  function pickPrincipalAccess(value) {
2593
- return value === "platform_admin" || value === "platform_super_admin" ? value : null;
2611
+ return value === "platform_admin" || value === "platform_super_admin" || value === "platform_admin_or_service" || value === "platform_super_admin_or_service" ? value : null;
2594
2612
  }
2595
2613
  function pickActionString(value) {
2596
2614
  return typeof value === "string" && value.trim() ? value.trim() : null;
@@ -2697,10 +2715,10 @@ function extractRequired(body) {
2697
2715
  if (Array.isArray(maybe.required)) return canonicalTopoloRequired(maybe.required);
2698
2716
  for (const nested of [maybe.details, maybe.error]) {
2699
2717
  if (!nested || typeof nested !== "object" || Array.isArray(nested)) continue;
2700
- const record3 = nested;
2701
- if (Array.isArray(record3.required)) return canonicalTopoloRequired(record3.required);
2702
- if (record3.details && typeof record3.details === "object" && !Array.isArray(record3.details)) {
2703
- const required = record3.details.required;
2718
+ const record4 = nested;
2719
+ if (Array.isArray(record4.required)) return canonicalTopoloRequired(record4.required);
2720
+ if (record4.details && typeof record4.details === "object" && !Array.isArray(record4.details)) {
2721
+ const required = record4.details.required;
2704
2722
  if (Array.isArray(required)) return canonicalTopoloRequired(required);
2705
2723
  }
2706
2724
  }
@@ -2729,6 +2747,8 @@ function compactActionCatalogEntry(action) {
2729
2747
  requiresConfirmation: action.requiresConfirmation,
2730
2748
  agentAccess: action.agentAccess ?? (action.requiresConfirmation ? "confirm" : action.readOnly ? "auto" : "confirm"),
2731
2749
  requiredPermission: action.requiredPermission,
2750
+ ...action.principalAccess ? { principalAccess: action.principalAccess } : {},
2751
+ ...action.accessPolicy ? { accessPolicy: action.accessPolicy } : {},
2732
2752
  requiredInput: required,
2733
2753
  resourceType: action.agentContract?.resourceContext?.kind ?? (action.permissionName.startsWith("workspace:") ? "workspace" : null),
2734
2754
  resultResourceType: action.agentContract?.resource?.kind ?? null,
@@ -2775,8 +2795,8 @@ function compactResultValue(value, depth, budget) {
2775
2795
  return value.length > ACTION_RESULT_MAX_ITEMS ? { count: value.length, items, omittedItems: value.length - ACTION_RESULT_MAX_ITEMS } : items;
2776
2796
  }
2777
2797
  if (typeof value === "object") {
2778
- const record3 = value;
2779
- const allKeys = Object.keys(record3);
2798
+ const record4 = value;
2799
+ const allKeys = Object.keys(record4);
2780
2800
  const ranked = allKeys.sort((left, right) => resultKeyPriority(left) - resultKeyPriority(right));
2781
2801
  const prioritized = ranked.filter((key) => resultKeyPriority(key) < 2);
2782
2802
  const ordinary = ranked.filter((key) => resultKeyPriority(key) === 2);
@@ -2785,7 +2805,7 @@ function compactResultValue(value, depth, budget) {
2785
2805
  ...prioritized,
2786
2806
  ...ordinary.slice(0, ordinaryLimit)
2787
2807
  ].slice(0, ACTION_RESULT_MAX_KEYS);
2788
- const compact = Object.fromEntries(keys.map((key) => [key, compactResultValue(record3[key], depth + 1, budget)]));
2808
+ const compact = Object.fromEntries(keys.map((key) => [key, compactResultValue(record4[key], depth + 1, budget)]));
2789
2809
  if (allKeys.length > keys.length) compact["_omittedKeys"] = allKeys.length - keys.length;
2790
2810
  return compact;
2791
2811
  }
@@ -3549,7 +3569,7 @@ function createTopolo(options) {
3549
3569
  };
3550
3570
  }
3551
3571
 
3552
- // node_modules/.pnpm/@topolo+sdk@0.23.8/node_modules/@topolo/sdk/dist/node/credential-store.js
3572
+ // node_modules/@topolo/sdk/dist/node/credential-store.js
3553
3573
  import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2, chmod as chmod2, rm as rm2, stat } from "fs/promises";
3554
3574
  import { existsSync as existsSync2 } from "fs";
3555
3575
  import { homedir as homedir2, platform } from "os";
@@ -3700,10 +3720,10 @@ var TopoloAuthError2 = class extends TopoloSdkError2 {
3700
3720
  };
3701
3721
  function extractTopoloServiceErrorCode2(body) {
3702
3722
  if (!body || typeof body !== "object" || Array.isArray(body)) return null;
3703
- const record2 = body;
3704
- const topLevel = canonicalTopoloServiceErrorCode2(record2.code);
3723
+ const record3 = body;
3724
+ const topLevel = canonicalTopoloServiceErrorCode2(record3.code);
3705
3725
  if (topLevel) return topLevel;
3706
- const nested = record2.error;
3726
+ const nested = record3.error;
3707
3727
  const nestedString = canonicalTopoloServiceErrorCode2(nested);
3708
3728
  if (nestedString) return nestedString;
3709
3729
  if (nested && typeof nested === "object" && !Array.isArray(nested)) {
@@ -3718,14 +3738,14 @@ function serviceErrorCode2(body, fallback) {
3718
3738
  }
3719
3739
  function extractTopoloServiceErrorDetails2(body) {
3720
3740
  if (!body || typeof body !== "object" || Array.isArray(body)) return void 0;
3721
- const record2 = body;
3722
- let candidate = record2.details;
3723
- const nested = record2.error;
3741
+ const record3 = body;
3742
+ let candidate = record3.details;
3743
+ const nested = record3.error;
3724
3744
  if (nested && typeof nested === "object" && !Array.isArray(nested)) {
3725
3745
  const nestedRecord = nested;
3726
3746
  if (candidate === void 0) candidate = nestedRecord.details ?? nestedRecord;
3727
3747
  }
3728
- if (candidate === void 0) candidate = record2;
3748
+ if (candidate === void 0) candidate = record3;
3729
3749
  if (Array.isArray(candidate)) return validationIssueDetails2(canonicalTopoloValidationIssues2(candidate)) ?? void 0;
3730
3750
  if (!candidate || typeof candidate !== "object") return void 0;
3731
3751
  const source = candidate;
@@ -3792,10 +3812,10 @@ function canonicalTopoloValidationIssues2(values) {
3792
3812
  const issues = [];
3793
3813
  for (const value of values) {
3794
3814
  if (!value || typeof value !== "object" || Array.isArray(value)) continue;
3795
- const record2 = value;
3796
- const path = canonicalTopoloValidationPath2(record2.field) ?? canonicalTopoloValidationPath2(record2.path);
3815
+ const record3 = value;
3816
+ const path = canonicalTopoloValidationPath2(record3.field) ?? canonicalTopoloValidationPath2(record3.path);
3797
3817
  if (!path) continue;
3798
- const projected = issue2(path, record2.message);
3818
+ const projected = issue2(path, record3.message);
3799
3819
  if (projected) issues.push(projected);
3800
3820
  if (issues.length === SERVICE_ISSUE_LIMIT2) break;
3801
3821
  }
@@ -4199,18 +4219,18 @@ function createProtectedActionSecretStore(options) {
4199
4219
  const key = await account(reference);
4200
4220
  const encoded = await backend.get(key);
4201
4221
  if (!encoded) throw new TopoloSdkError2("action_secret_unavailable", "Protected action reference is missing or belongs to another identity or environment.");
4202
- let record2;
4222
+ let record3;
4203
4223
  try {
4204
- record2 = JSON.parse(encoded);
4224
+ record3 = JSON.parse(encoded);
4205
4225
  } catch {
4206
4226
  throw new TopoloSdkError2("action_secret_invalid", "Protected action reference is corrupt.");
4207
4227
  }
4208
- if (!Number.isFinite(record2?.expiresAt) || !Object.hasOwn(record2, "value")) throw new TopoloSdkError2("action_secret_invalid", "Protected action reference is corrupt.");
4209
- if (record2.expiresAt <= now()) {
4228
+ if (!Number.isFinite(record3?.expiresAt) || !Object.hasOwn(record3, "value")) throw new TopoloSdkError2("action_secret_invalid", "Protected action reference is corrupt.");
4229
+ if (record3.expiresAt <= now()) {
4210
4230
  await backend.delete(key);
4211
4231
  throw new TopoloSdkError2("action_secret_expired", "Protected action reference expired. Repeat the originating action if its contract permits.");
4212
4232
  }
4213
- return record2.value;
4233
+ return record3.value;
4214
4234
  },
4215
4235
  async delete(reference) {
4216
4236
  await backend.delete(await account(reference));
@@ -5398,9 +5418,9 @@ function externalApprovalHandoff(action, result) {
5398
5418
  if (!result || typeof result !== "object" || Array.isArray(result)) return null;
5399
5419
  const invocation = result.invocation;
5400
5420
  if (!invocation || typeof invocation !== "object" || Array.isArray(invocation)) return null;
5401
- const record2 = invocation;
5402
- if (record2.status !== "awaiting_approval") return null;
5403
- const approval = record2.approval;
5421
+ const record3 = invocation;
5422
+ if (record3.status !== "awaiting_approval") return null;
5423
+ const approval = record3.approval;
5404
5424
  if (!approval || typeof approval !== "object" || Array.isArray(approval)) return null;
5405
5425
  const handoff = approval;
5406
5426
  if (typeof handoff.requestId !== "string" || typeof handoff.verificationUrl !== "string") return null;
@@ -7460,16 +7480,16 @@ var REVOKE_CREDENTIAL = "app_topolo_auth.principal_credentials.revoke";
7460
7480
  var INSTALLATION_BOOTSTRAP_GRANT = "app_topolo_auth:identity";
7461
7481
  function actionData(value) {
7462
7482
  if (!value || typeof value !== "object") throw new Error("Topolo returned an invalid action response.");
7463
- const record2 = value;
7464
- const data = record2.data;
7465
- return data && typeof data === "object" ? data : record2;
7483
+ const record3 = value;
7484
+ const data = record3.data;
7485
+ return data && typeof data === "object" ? data : record3;
7466
7486
  }
7467
7487
  function requiredRecord(value, name) {
7468
7488
  if (!value || typeof value !== "object") throw new Error(`Topolo did not return ${name}.`);
7469
7489
  return value;
7470
7490
  }
7471
- function requiredString(record2, key) {
7472
- const value = record2[key];
7491
+ function requiredString(record3, key) {
7492
+ const value = record3[key];
7473
7493
  if (typeof value !== "string" || !value.trim()) throw new Error(`Topolo did not return ${key}.`);
7474
7494
  return value;
7475
7495
  }
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.20",
5
- "topoloPublishedVersion": "0.12.20",
4
+ "version": "0.12.21",
5
+ "topoloPublishedVersion": "0.12.21",
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.12",
32
- "@topolo/sdk": "0.23.8",
31
+ "@topolo/mcp": "0.14.13",
32
+ "@topolo/sdk": "0.23.9",
33
33
  "commander": "^12.1.0"
34
34
  },
35
35
  "devDependencies": {