@topolo/sdk 0.8.0 → 0.8.2

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.cjs CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ ACTION_CATALOG_DIGEST_ALGORITHM: () => ACTION_CATALOG_DIGEST_ALGORITHM,
23
24
  APPLICATIONS: () => APPLICATIONS,
24
25
  APPLICATION_REQUIREMENTS: () => APPLICATION_REQUIREMENTS,
25
26
  APPLICATION_REQUIREMENTS_VERSION: () => APPLICATION_REQUIREMENTS_VERSION,
@@ -47,6 +48,7 @@ __export(index_exports, {
47
48
  defineTopoloQuickActionsWidget: () => defineTopoloQuickActionsWidget,
48
49
  defineTopoloRecentActivityWidget: () => defineTopoloRecentActivityWidget,
49
50
  defineTopoloStatsWidget: () => defineTopoloStatsWidget,
51
+ digestTopoloActionCatalog: () => digestTopoloActionCatalog,
50
52
  requirementsForApplication: () => requirementsForApplication,
51
53
  resolveCatalogServiceUrl: () => resolveCatalogServiceUrl,
52
54
  resolveServiceUrl: () => resolveServiceUrl,
@@ -2507,6 +2509,31 @@ var TopoloClient = class _TopoloClient {
2507
2509
  )
2508
2510
  };
2509
2511
  }
2512
+ async getActionCatalogSummary(service) {
2513
+ const boundedService = service.trim();
2514
+ if (!boundedService) {
2515
+ throw new TopoloSdkError("service_required", "service is required for bounded action discovery");
2516
+ }
2517
+ const res = await this.request({
2518
+ service: "developers",
2519
+ method: "GET",
2520
+ path: "/api/actions/catalog",
2521
+ query: { service: boundedService, summary: "true" }
2522
+ });
2523
+ const raw = res.data?.summary ?? res.summary;
2524
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
2525
+ throw new TopoloSdkError("action_catalog_summary_unavailable", "Action catalog summary is unavailable.");
2526
+ }
2527
+ const record = raw;
2528
+ if (record.algorithm !== "sha256-v1" || typeof record.digest !== "string" || !/^[a-f0-9]{64}$/.test(record.digest) || !Number.isSafeInteger(record.actionCount) || Number(record.actionCount) < 0) {
2529
+ throw new TopoloSdkError("action_catalog_summary_unavailable", "Action catalog summary is invalid.");
2530
+ }
2531
+ return {
2532
+ algorithm: "sha256-v1",
2533
+ digest: record.digest,
2534
+ actionCount: Number(record.actionCount)
2535
+ };
2536
+ }
2510
2537
  /** @deprecated Prefer searchActions() so callers retain the continuation cursor. */
2511
2538
  async listActions(options) {
2512
2539
  if (!options) {
@@ -2522,15 +2549,23 @@ var TopoloClient = class _TopoloClient {
2522
2549
  "action id is required"
2523
2550
  );
2524
2551
  }
2525
- const res = await this.request({
2526
- service: "developers",
2527
- method: "GET",
2528
- path: "/api/actions/catalog",
2529
- query: { actionId }
2530
- });
2552
+ let res;
2553
+ try {
2554
+ res = await this.request({
2555
+ service: "developers",
2556
+ method: "GET",
2557
+ path: "/api/actions/catalog",
2558
+ query: { actionId }
2559
+ });
2560
+ } catch (error) {
2561
+ if (error instanceof TopoloHttpError && error.status === 404) {
2562
+ throw new TopoloSdkError("unknown_action", `Unknown or unavailable Topolo action "${action}".`);
2563
+ }
2564
+ throw error;
2565
+ }
2531
2566
  const raw = res.data?.action ?? res.action;
2532
2567
  const match = normalizeActionCatalogEntry(raw);
2533
- if (!match) throw new TopoloSdkError("unknown_action", `Unknown Topolo action "${action}".`);
2568
+ if (!match) throw new TopoloSdkError("unknown_action", `Unknown or unavailable Topolo action "${action}".`);
2534
2569
  return match;
2535
2570
  }
2536
2571
  async callAction(action, input = {}, options = {}) {
@@ -2606,6 +2641,7 @@ var TopoloClient = class _TopoloClient {
2606
2641
  const kind = payload.credentialType === "api_key" ? "api_key" : "access_token";
2607
2642
  return {
2608
2643
  kind,
2644
+ authorizationMode: normalizeCredentialAuthorizationMode(payload.authorizationMode, kind),
2609
2645
  user: {
2610
2646
  id: user.id,
2611
2647
  email: user.email,
@@ -2868,6 +2904,11 @@ function objectToQuery(value) {
2868
2904
  }
2869
2905
  return Object.keys(query).length > 0 ? query : void 0;
2870
2906
  }
2907
+ function normalizeCredentialAuthorizationMode(value, kind) {
2908
+ if (kind === "api_key") return "api_key";
2909
+ if (value === "context_rbac" || value === "oauth_scopes" || value === "session_rbac") return value;
2910
+ return "unknown";
2911
+ }
2871
2912
  function describeError(body, fallback) {
2872
2913
  if (body && typeof body === "object") {
2873
2914
  const maybe = body;
@@ -2903,6 +2944,40 @@ function mergeSignals(a, b) {
2903
2944
  return controller.signal;
2904
2945
  }
2905
2946
 
2947
+ // src/action-catalog-digest.ts
2948
+ var ACTION_CATALOG_DIGEST_ALGORITHM = "sha256-v1";
2949
+ function canonicalPermission(value, appId) {
2950
+ let permission = String(value || "").trim().toLowerCase().replace(/\s+/g, "");
2951
+ const prefix = `${String(appId || "").trim().toLowerCase()}.`;
2952
+ if (prefix !== "." && permission.startsWith(prefix)) permission = permission.slice(prefix.length);
2953
+ return permission.replace(/\./g, ":");
2954
+ }
2955
+ function stableJson(value) {
2956
+ if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
2957
+ if (value && typeof value === "object") {
2958
+ const record = value;
2959
+ return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableJson(record[key])}`).join(",")}}`;
2960
+ }
2961
+ return JSON.stringify(value);
2962
+ }
2963
+ async function digestTopoloActionCatalog(actions, appId) {
2964
+ const canonical = actions.filter((action) => action.agentAccess !== "off").map((action) => ({
2965
+ actionId: action.actionId || `${appId}.${action.name}`,
2966
+ authorizationMode: action.authorizationMode === "runtime" ? "runtime" : "static",
2967
+ inputSchema: action.inputSchema,
2968
+ method: action.method,
2969
+ outputSchema: action.outputSchema,
2970
+ path: action.path,
2971
+ permission: canonicalPermission(action.permission ?? action.permissionName ?? "", appId),
2972
+ readOnly: action.readOnly,
2973
+ requiresConfirmation: action.requiresConfirmation,
2974
+ target: action.target ?? ""
2975
+ })).sort((left, right) => left.actionId.localeCompare(right.actionId));
2976
+ const bytes = new TextEncoder().encode(canonical.map(stableJson).join("\n"));
2977
+ const digest = await crypto.subtle.digest("SHA-256", bytes);
2978
+ return [...new Uint8Array(digest)].map((value) => value.toString(16).padStart(2, "0")).join("");
2979
+ }
2980
+
2906
2981
  // src/modules/crm.ts
2907
2982
  var CrmModule = class {
2908
2983
  constructor(client) {
@@ -3428,6 +3503,7 @@ function createTopolo(options) {
3428
3503
  }
3429
3504
  // Annotate the CommonJS export names for ESM import in node:
3430
3505
  0 && (module.exports = {
3506
+ ACTION_CATALOG_DIGEST_ALGORITHM,
3431
3507
  APPLICATIONS,
3432
3508
  APPLICATION_REQUIREMENTS,
3433
3509
  APPLICATION_REQUIREMENTS_VERSION,
@@ -3455,6 +3531,7 @@ function createTopolo(options) {
3455
3531
  defineTopoloQuickActionsWidget,
3456
3532
  defineTopoloRecentActivityWidget,
3457
3533
  defineTopoloStatsWidget,
3534
+ digestTopoloActionCatalog,
3458
3535
  requirementsForApplication,
3459
3536
  resolveCatalogServiceUrl,
3460
3537
  resolveServiceUrl,
package/dist/index.d.cts CHANGED
@@ -174,6 +174,11 @@ interface TopoloActionCatalogPage {
174
174
  actions: TopoloActionCatalogEntry[];
175
175
  page: TopoloCatalogPage;
176
176
  }
177
+ interface TopoloActionCatalogSummary {
178
+ algorithm: 'sha256-v1';
179
+ digest: string;
180
+ actionCount: number;
181
+ }
177
182
  interface TopoloCatalogSearchOptions {
178
183
  query?: string;
179
184
  cursor?: string;
@@ -249,6 +254,7 @@ declare class TopoloClient {
249
254
  searchActions(options: TopoloCatalogSearchOptions & {
250
255
  service: string;
251
256
  }): Promise<TopoloActionCatalogPage>;
257
+ getActionCatalogSummary(service: string): Promise<TopoloActionCatalogSummary>;
252
258
  /** @deprecated Prefer searchActions() so callers retain the continuation cursor. */
253
259
  listActions(options?: TopoloCatalogSearchOptions & {
254
260
  service: string;
@@ -279,6 +285,7 @@ declare class TopoloClient {
279
285
  }
280
286
  interface CredentialIntrospection {
281
287
  kind: 'api_key' | 'access_token';
288
+ authorizationMode: 'context_rbac' | 'oauth_scopes' | 'session_rbac' | 'api_key' | 'unknown';
282
289
  user: {
283
290
  id: string;
284
291
  email: string;
@@ -293,6 +300,24 @@ interface CredentialIntrospection {
293
300
  } | null;
294
301
  }
295
302
 
303
+ declare const ACTION_CATALOG_DIGEST_ALGORITHM: "sha256-v1";
304
+ interface TopoloActionDigestInput {
305
+ actionId?: string;
306
+ name: string;
307
+ method: string;
308
+ path: string;
309
+ permission?: string | null;
310
+ permissionName?: string | null;
311
+ authorizationMode?: string | null;
312
+ target?: string | null;
313
+ readOnly: boolean;
314
+ requiresConfirmation: boolean;
315
+ agentAccess?: string | null;
316
+ inputSchema: Record<string, unknown>;
317
+ outputSchema: Record<string, unknown>;
318
+ }
319
+ declare function digestTopoloActionCatalog(actions: TopoloActionDigestInput[], appId: string): Promise<string>;
320
+
296
321
  declare const APP_API_URLS: {
297
322
  readonly agent: "https://agent.topolo.app";
298
323
  readonly auth: "https://auth.topolo.app";
@@ -2136,4 +2161,4 @@ declare function createTopolo(options: TopoloClientOptions): {
2136
2161
  };
2137
2162
  type Topolo = ReturnType<typeof createTopolo>;
2138
2163
 
2139
- export { APPLICATIONS, APPLICATION_REQUIREMENTS, APPLICATION_REQUIREMENTS_VERSION, type AgentIdentity, type AppApiId, type ApplicationCatalogEntry, type ApplicationDeployTarget, type ApplicationId, type ApplicationRequirement, type ApplicationRequirementAudit, type ApplicationRequirementFinding, type ApplicationRequirementMigrationItem, type ApplicationRequirementScope, type ApplicationRequirementScore, type ApplicationRequirementStatus, type ApplicationRequirementsAuditReport, type CredentialIntrospection, type CrmContactSummary, CrmModule, DEFAULT_APP_URLS, type DeviceAuthorizationResponse, IdentityModule, type ListContactsOptions, type ListContactsResult, type OAuthHelperOptions, type P2PActionDetail, type P2PActionRequestInput, type P2PActionRequestResult, type P2PActionRow, type P2PActionRun, type P2PCapability, type P2PConnection, type P2PHold, type P2PLedgerEntry, P2PModule, type P2PPolicy, type P2PPricingModel, type P2PSettlementBatch, type P2PSettlementGroup, type PublishCapabilityInput, type RequestOptions, type ServiceCatalogUrlEntry, TOPOLO_WIDGET_ENDPOINT, TOPOLO_WIDGET_REFRESH_INTERVAL_MS, type TokenResponse, type Topolo, type TopoloActionCatalogEntry, type TopoloApiKeyResourceMetadata, TopoloAuthError, type TopoloChartWidget, TopoloClient, type TopoloClientOptions, TopoloConfirmationRequiredError, type TopoloCredential, type TopoloDebugEvent, TopoloHttpError, type TopoloNotificationsWidget, TopoloOAuth, TopoloPermissionError, type TopoloQuickActionsWidget, type TopoloRecentActivityWidget, TopoloSdkError, type TopoloServiceCatalogEntry, type TopoloStatsWidget, type TopoloWidget, type TopoloWidgetActionItem, type TopoloWidgetActivityItem, type TopoloWidgetApiResponse, type TopoloWidgetBase, type TopoloWidgetConfig, type TopoloWidgetDraft, type TopoloWidgetMetric, type TopoloWidgetNotificationItem, type TopoloWidgetResponseOptions, type TopoloWidgetSnapshotMetadata, type TopoloWidgetSnapshotMetric, type TopoloWidgetType, type TopoloWidgetValidationResult, applicationRequirementScopes, auditAllApplicationRequirements, auditApplicationRequirements, createTopolo, createTopoloWidgetError, createTopoloWidgetResponse, defineTopoloChartWidget, defineTopoloNotificationsWidget, defineTopoloQuickActionsWidget, defineTopoloRecentActivityWidget, defineTopoloStatsWidget, requirementsForApplication, resolveCatalogServiceUrl, resolveServiceUrl, validateTopoloWidgetResponse };
2164
+ export { ACTION_CATALOG_DIGEST_ALGORITHM, APPLICATIONS, APPLICATION_REQUIREMENTS, APPLICATION_REQUIREMENTS_VERSION, type AgentIdentity, type AppApiId, type ApplicationCatalogEntry, type ApplicationDeployTarget, type ApplicationId, type ApplicationRequirement, type ApplicationRequirementAudit, type ApplicationRequirementFinding, type ApplicationRequirementMigrationItem, type ApplicationRequirementScope, type ApplicationRequirementScore, type ApplicationRequirementStatus, type ApplicationRequirementsAuditReport, type CredentialIntrospection, type CrmContactSummary, CrmModule, DEFAULT_APP_URLS, type DeviceAuthorizationResponse, IdentityModule, type ListContactsOptions, type ListContactsResult, type OAuthHelperOptions, type P2PActionDetail, type P2PActionRequestInput, type P2PActionRequestResult, type P2PActionRow, type P2PActionRun, type P2PCapability, type P2PConnection, type P2PHold, type P2PLedgerEntry, P2PModule, type P2PPolicy, type P2PPricingModel, type P2PSettlementBatch, type P2PSettlementGroup, type PublishCapabilityInput, type RequestOptions, type ServiceCatalogUrlEntry, TOPOLO_WIDGET_ENDPOINT, TOPOLO_WIDGET_REFRESH_INTERVAL_MS, type TokenResponse, type Topolo, type TopoloActionCatalogEntry, type TopoloActionCatalogSummary, type TopoloActionDigestInput, type TopoloApiKeyResourceMetadata, TopoloAuthError, type TopoloChartWidget, TopoloClient, type TopoloClientOptions, TopoloConfirmationRequiredError, type TopoloCredential, type TopoloDebugEvent, TopoloHttpError, type TopoloNotificationsWidget, TopoloOAuth, TopoloPermissionError, type TopoloQuickActionsWidget, type TopoloRecentActivityWidget, TopoloSdkError, type TopoloServiceCatalogEntry, type TopoloStatsWidget, type TopoloWidget, type TopoloWidgetActionItem, type TopoloWidgetActivityItem, type TopoloWidgetApiResponse, type TopoloWidgetBase, type TopoloWidgetConfig, type TopoloWidgetDraft, type TopoloWidgetMetric, type TopoloWidgetNotificationItem, type TopoloWidgetResponseOptions, type TopoloWidgetSnapshotMetadata, type TopoloWidgetSnapshotMetric, type TopoloWidgetType, type TopoloWidgetValidationResult, applicationRequirementScopes, auditAllApplicationRequirements, auditApplicationRequirements, createTopolo, createTopoloWidgetError, createTopoloWidgetResponse, defineTopoloChartWidget, defineTopoloNotificationsWidget, defineTopoloQuickActionsWidget, defineTopoloRecentActivityWidget, defineTopoloStatsWidget, digestTopoloActionCatalog, requirementsForApplication, resolveCatalogServiceUrl, resolveServiceUrl, validateTopoloWidgetResponse };
package/dist/index.d.ts CHANGED
@@ -174,6 +174,11 @@ interface TopoloActionCatalogPage {
174
174
  actions: TopoloActionCatalogEntry[];
175
175
  page: TopoloCatalogPage;
176
176
  }
177
+ interface TopoloActionCatalogSummary {
178
+ algorithm: 'sha256-v1';
179
+ digest: string;
180
+ actionCount: number;
181
+ }
177
182
  interface TopoloCatalogSearchOptions {
178
183
  query?: string;
179
184
  cursor?: string;
@@ -249,6 +254,7 @@ declare class TopoloClient {
249
254
  searchActions(options: TopoloCatalogSearchOptions & {
250
255
  service: string;
251
256
  }): Promise<TopoloActionCatalogPage>;
257
+ getActionCatalogSummary(service: string): Promise<TopoloActionCatalogSummary>;
252
258
  /** @deprecated Prefer searchActions() so callers retain the continuation cursor. */
253
259
  listActions(options?: TopoloCatalogSearchOptions & {
254
260
  service: string;
@@ -279,6 +285,7 @@ declare class TopoloClient {
279
285
  }
280
286
  interface CredentialIntrospection {
281
287
  kind: 'api_key' | 'access_token';
288
+ authorizationMode: 'context_rbac' | 'oauth_scopes' | 'session_rbac' | 'api_key' | 'unknown';
282
289
  user: {
283
290
  id: string;
284
291
  email: string;
@@ -293,6 +300,24 @@ interface CredentialIntrospection {
293
300
  } | null;
294
301
  }
295
302
 
303
+ declare const ACTION_CATALOG_DIGEST_ALGORITHM: "sha256-v1";
304
+ interface TopoloActionDigestInput {
305
+ actionId?: string;
306
+ name: string;
307
+ method: string;
308
+ path: string;
309
+ permission?: string | null;
310
+ permissionName?: string | null;
311
+ authorizationMode?: string | null;
312
+ target?: string | null;
313
+ readOnly: boolean;
314
+ requiresConfirmation: boolean;
315
+ agentAccess?: string | null;
316
+ inputSchema: Record<string, unknown>;
317
+ outputSchema: Record<string, unknown>;
318
+ }
319
+ declare function digestTopoloActionCatalog(actions: TopoloActionDigestInput[], appId: string): Promise<string>;
320
+
296
321
  declare const APP_API_URLS: {
297
322
  readonly agent: "https://agent.topolo.app";
298
323
  readonly auth: "https://auth.topolo.app";
@@ -2136,4 +2161,4 @@ declare function createTopolo(options: TopoloClientOptions): {
2136
2161
  };
2137
2162
  type Topolo = ReturnType<typeof createTopolo>;
2138
2163
 
2139
- export { APPLICATIONS, APPLICATION_REQUIREMENTS, APPLICATION_REQUIREMENTS_VERSION, type AgentIdentity, type AppApiId, type ApplicationCatalogEntry, type ApplicationDeployTarget, type ApplicationId, type ApplicationRequirement, type ApplicationRequirementAudit, type ApplicationRequirementFinding, type ApplicationRequirementMigrationItem, type ApplicationRequirementScope, type ApplicationRequirementScore, type ApplicationRequirementStatus, type ApplicationRequirementsAuditReport, type CredentialIntrospection, type CrmContactSummary, CrmModule, DEFAULT_APP_URLS, type DeviceAuthorizationResponse, IdentityModule, type ListContactsOptions, type ListContactsResult, type OAuthHelperOptions, type P2PActionDetail, type P2PActionRequestInput, type P2PActionRequestResult, type P2PActionRow, type P2PActionRun, type P2PCapability, type P2PConnection, type P2PHold, type P2PLedgerEntry, P2PModule, type P2PPolicy, type P2PPricingModel, type P2PSettlementBatch, type P2PSettlementGroup, type PublishCapabilityInput, type RequestOptions, type ServiceCatalogUrlEntry, TOPOLO_WIDGET_ENDPOINT, TOPOLO_WIDGET_REFRESH_INTERVAL_MS, type TokenResponse, type Topolo, type TopoloActionCatalogEntry, type TopoloApiKeyResourceMetadata, TopoloAuthError, type TopoloChartWidget, TopoloClient, type TopoloClientOptions, TopoloConfirmationRequiredError, type TopoloCredential, type TopoloDebugEvent, TopoloHttpError, type TopoloNotificationsWidget, TopoloOAuth, TopoloPermissionError, type TopoloQuickActionsWidget, type TopoloRecentActivityWidget, TopoloSdkError, type TopoloServiceCatalogEntry, type TopoloStatsWidget, type TopoloWidget, type TopoloWidgetActionItem, type TopoloWidgetActivityItem, type TopoloWidgetApiResponse, type TopoloWidgetBase, type TopoloWidgetConfig, type TopoloWidgetDraft, type TopoloWidgetMetric, type TopoloWidgetNotificationItem, type TopoloWidgetResponseOptions, type TopoloWidgetSnapshotMetadata, type TopoloWidgetSnapshotMetric, type TopoloWidgetType, type TopoloWidgetValidationResult, applicationRequirementScopes, auditAllApplicationRequirements, auditApplicationRequirements, createTopolo, createTopoloWidgetError, createTopoloWidgetResponse, defineTopoloChartWidget, defineTopoloNotificationsWidget, defineTopoloQuickActionsWidget, defineTopoloRecentActivityWidget, defineTopoloStatsWidget, requirementsForApplication, resolveCatalogServiceUrl, resolveServiceUrl, validateTopoloWidgetResponse };
2164
+ export { ACTION_CATALOG_DIGEST_ALGORITHM, APPLICATIONS, APPLICATION_REQUIREMENTS, APPLICATION_REQUIREMENTS_VERSION, type AgentIdentity, type AppApiId, type ApplicationCatalogEntry, type ApplicationDeployTarget, type ApplicationId, type ApplicationRequirement, type ApplicationRequirementAudit, type ApplicationRequirementFinding, type ApplicationRequirementMigrationItem, type ApplicationRequirementScope, type ApplicationRequirementScore, type ApplicationRequirementStatus, type ApplicationRequirementsAuditReport, type CredentialIntrospection, type CrmContactSummary, CrmModule, DEFAULT_APP_URLS, type DeviceAuthorizationResponse, IdentityModule, type ListContactsOptions, type ListContactsResult, type OAuthHelperOptions, type P2PActionDetail, type P2PActionRequestInput, type P2PActionRequestResult, type P2PActionRow, type P2PActionRun, type P2PCapability, type P2PConnection, type P2PHold, type P2PLedgerEntry, P2PModule, type P2PPolicy, type P2PPricingModel, type P2PSettlementBatch, type P2PSettlementGroup, type PublishCapabilityInput, type RequestOptions, type ServiceCatalogUrlEntry, TOPOLO_WIDGET_ENDPOINT, TOPOLO_WIDGET_REFRESH_INTERVAL_MS, type TokenResponse, type Topolo, type TopoloActionCatalogEntry, type TopoloActionCatalogSummary, type TopoloActionDigestInput, type TopoloApiKeyResourceMetadata, TopoloAuthError, type TopoloChartWidget, TopoloClient, type TopoloClientOptions, TopoloConfirmationRequiredError, type TopoloCredential, type TopoloDebugEvent, TopoloHttpError, type TopoloNotificationsWidget, TopoloOAuth, TopoloPermissionError, type TopoloQuickActionsWidget, type TopoloRecentActivityWidget, TopoloSdkError, type TopoloServiceCatalogEntry, type TopoloStatsWidget, type TopoloWidget, type TopoloWidgetActionItem, type TopoloWidgetActivityItem, type TopoloWidgetApiResponse, type TopoloWidgetBase, type TopoloWidgetConfig, type TopoloWidgetDraft, type TopoloWidgetMetric, type TopoloWidgetNotificationItem, type TopoloWidgetResponseOptions, type TopoloWidgetSnapshotMetadata, type TopoloWidgetSnapshotMetric, type TopoloWidgetType, type TopoloWidgetValidationResult, applicationRequirementScopes, auditAllApplicationRequirements, auditApplicationRequirements, createTopolo, createTopoloWidgetError, createTopoloWidgetResponse, defineTopoloChartWidget, defineTopoloNotificationsWidget, defineTopoloQuickActionsWidget, defineTopoloRecentActivityWidget, defineTopoloStatsWidget, digestTopoloActionCatalog, requirementsForApplication, resolveCatalogServiceUrl, resolveServiceUrl, validateTopoloWidgetResponse };
package/dist/index.js CHANGED
@@ -2451,6 +2451,31 @@ var TopoloClient = class _TopoloClient {
2451
2451
  )
2452
2452
  };
2453
2453
  }
2454
+ async getActionCatalogSummary(service) {
2455
+ const boundedService = service.trim();
2456
+ if (!boundedService) {
2457
+ throw new TopoloSdkError("service_required", "service is required for bounded action discovery");
2458
+ }
2459
+ const res = await this.request({
2460
+ service: "developers",
2461
+ method: "GET",
2462
+ path: "/api/actions/catalog",
2463
+ query: { service: boundedService, summary: "true" }
2464
+ });
2465
+ const raw = res.data?.summary ?? res.summary;
2466
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
2467
+ throw new TopoloSdkError("action_catalog_summary_unavailable", "Action catalog summary is unavailable.");
2468
+ }
2469
+ const record = raw;
2470
+ if (record.algorithm !== "sha256-v1" || typeof record.digest !== "string" || !/^[a-f0-9]{64}$/.test(record.digest) || !Number.isSafeInteger(record.actionCount) || Number(record.actionCount) < 0) {
2471
+ throw new TopoloSdkError("action_catalog_summary_unavailable", "Action catalog summary is invalid.");
2472
+ }
2473
+ return {
2474
+ algorithm: "sha256-v1",
2475
+ digest: record.digest,
2476
+ actionCount: Number(record.actionCount)
2477
+ };
2478
+ }
2454
2479
  /** @deprecated Prefer searchActions() so callers retain the continuation cursor. */
2455
2480
  async listActions(options) {
2456
2481
  if (!options) {
@@ -2466,15 +2491,23 @@ var TopoloClient = class _TopoloClient {
2466
2491
  "action id is required"
2467
2492
  );
2468
2493
  }
2469
- const res = await this.request({
2470
- service: "developers",
2471
- method: "GET",
2472
- path: "/api/actions/catalog",
2473
- query: { actionId }
2474
- });
2494
+ let res;
2495
+ try {
2496
+ res = await this.request({
2497
+ service: "developers",
2498
+ method: "GET",
2499
+ path: "/api/actions/catalog",
2500
+ query: { actionId }
2501
+ });
2502
+ } catch (error) {
2503
+ if (error instanceof TopoloHttpError && error.status === 404) {
2504
+ throw new TopoloSdkError("unknown_action", `Unknown or unavailable Topolo action "${action}".`);
2505
+ }
2506
+ throw error;
2507
+ }
2475
2508
  const raw = res.data?.action ?? res.action;
2476
2509
  const match = normalizeActionCatalogEntry(raw);
2477
- if (!match) throw new TopoloSdkError("unknown_action", `Unknown Topolo action "${action}".`);
2510
+ if (!match) throw new TopoloSdkError("unknown_action", `Unknown or unavailable Topolo action "${action}".`);
2478
2511
  return match;
2479
2512
  }
2480
2513
  async callAction(action, input = {}, options = {}) {
@@ -2550,6 +2583,7 @@ var TopoloClient = class _TopoloClient {
2550
2583
  const kind = payload.credentialType === "api_key" ? "api_key" : "access_token";
2551
2584
  return {
2552
2585
  kind,
2586
+ authorizationMode: normalizeCredentialAuthorizationMode(payload.authorizationMode, kind),
2553
2587
  user: {
2554
2588
  id: user.id,
2555
2589
  email: user.email,
@@ -2812,6 +2846,11 @@ function objectToQuery(value) {
2812
2846
  }
2813
2847
  return Object.keys(query).length > 0 ? query : void 0;
2814
2848
  }
2849
+ function normalizeCredentialAuthorizationMode(value, kind) {
2850
+ if (kind === "api_key") return "api_key";
2851
+ if (value === "context_rbac" || value === "oauth_scopes" || value === "session_rbac") return value;
2852
+ return "unknown";
2853
+ }
2815
2854
  function describeError(body, fallback) {
2816
2855
  if (body && typeof body === "object") {
2817
2856
  const maybe = body;
@@ -2847,6 +2886,40 @@ function mergeSignals(a, b) {
2847
2886
  return controller.signal;
2848
2887
  }
2849
2888
 
2889
+ // src/action-catalog-digest.ts
2890
+ var ACTION_CATALOG_DIGEST_ALGORITHM = "sha256-v1";
2891
+ function canonicalPermission(value, appId) {
2892
+ let permission = String(value || "").trim().toLowerCase().replace(/\s+/g, "");
2893
+ const prefix = `${String(appId || "").trim().toLowerCase()}.`;
2894
+ if (prefix !== "." && permission.startsWith(prefix)) permission = permission.slice(prefix.length);
2895
+ return permission.replace(/\./g, ":");
2896
+ }
2897
+ function stableJson(value) {
2898
+ if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
2899
+ if (value && typeof value === "object") {
2900
+ const record = value;
2901
+ return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableJson(record[key])}`).join(",")}}`;
2902
+ }
2903
+ return JSON.stringify(value);
2904
+ }
2905
+ async function digestTopoloActionCatalog(actions, appId) {
2906
+ const canonical = actions.filter((action) => action.agentAccess !== "off").map((action) => ({
2907
+ actionId: action.actionId || `${appId}.${action.name}`,
2908
+ authorizationMode: action.authorizationMode === "runtime" ? "runtime" : "static",
2909
+ inputSchema: action.inputSchema,
2910
+ method: action.method,
2911
+ outputSchema: action.outputSchema,
2912
+ path: action.path,
2913
+ permission: canonicalPermission(action.permission ?? action.permissionName ?? "", appId),
2914
+ readOnly: action.readOnly,
2915
+ requiresConfirmation: action.requiresConfirmation,
2916
+ target: action.target ?? ""
2917
+ })).sort((left, right) => left.actionId.localeCompare(right.actionId));
2918
+ const bytes = new TextEncoder().encode(canonical.map(stableJson).join("\n"));
2919
+ const digest = await crypto.subtle.digest("SHA-256", bytes);
2920
+ return [...new Uint8Array(digest)].map((value) => value.toString(16).padStart(2, "0")).join("");
2921
+ }
2922
+
2850
2923
  // src/modules/crm.ts
2851
2924
  var CrmModule = class {
2852
2925
  constructor(client) {
@@ -3371,6 +3444,7 @@ function createTopolo(options) {
3371
3444
  };
3372
3445
  }
3373
3446
  export {
3447
+ ACTION_CATALOG_DIGEST_ALGORITHM,
3374
3448
  APPLICATIONS,
3375
3449
  APPLICATION_REQUIREMENTS,
3376
3450
  APPLICATION_REQUIREMENTS_VERSION,
@@ -3398,6 +3472,7 @@ export {
3398
3472
  defineTopoloQuickActionsWidget,
3399
3473
  defineTopoloRecentActivityWidget,
3400
3474
  defineTopoloStatsWidget,
3475
+ digestTopoloActionCatalog,
3401
3476
  requirementsForApplication,
3402
3477
  resolveCatalogServiceUrl,
3403
3478
  resolveServiceUrl,