corsair 0.1.20 → 0.1.22

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.
@@ -87,13 +87,13 @@ type InferAllIntegrationKeys<Plugins extends readonly CorsairPlugin[]> = UnionTo
87
87
  type InferPluginNamespaces<Plugins extends readonly CorsairPlugin[]> = UnionToIntersection<InferPluginNamespace<Plugins[number]>>;
88
88
  /**
89
89
  * The main Corsair client type that provides access to all plugin APIs, entities, webhooks, and keys.
90
- * Also includes get_methods() and get_schema() for agent-facing endpoint discovery.
90
+ * Also includes list_operations() and get_schema() for agent-facing endpoint discovery.
91
91
  */
92
92
  export type CorsairClient<Plugins extends readonly CorsairPlugin[]> = InferPluginNamespaces<Plugins> & CorsairInspectMethods;
93
93
  /**
94
94
  * Multi-tenant wrapper that provides a `withTenant` method to scope operations to a specific tenant.
95
95
  * Also includes integration-level `keys` for managing shared secrets (OAuth2 client credentials, etc.)
96
- * Inspect methods (get_methods / get_schema) are available at the root — no need to call withTenant().
96
+ * Inspect methods (list_operations / get_schema) are available at the root — no need to call withTenant().
97
97
  */
98
98
  export type CorsairTenantWrapper<Plugins extends readonly CorsairPlugin[]> = {
99
99
  withTenant: (tenantId: string) => CorsairClient<Plugins>;
@@ -38,7 +38,7 @@ export type { AllProviders, AuthTypes, BaseProviders } from './constants';
38
38
  export type { BindEndpoints, BoundEndpointFn, BoundEndpointTree, CorsairContext, CorsairEndpoint, EndpointPathsOf, EndpointTree, } from './endpoints';
39
39
  export type { CorsairErrorHandler, ErrorContext, ErrorHandler, ErrorHandlerAndMatchFunction, ErrorMatcher, RetryStrategies, RetryStrategy, } from './errors';
40
40
  export type { CorsairInspectMethods, EndpointSchemaResult } from './inspect';
41
- export type { EnforcePermissionOptions, EnforcePermissionResult } from './permissions';
41
+ export type { EnforcePermissionOptions, EnforcePermissionResult, } from './permissions';
42
42
  export type { BeforeHookResult, CorsairIntegration, CorsairKeyBuilder, CorsairKeyBuilderBase, CorsairPlugin, CorsairPluginContext, EndpointHooks, EndpointMetaEntry, EndpointRiskLevel, KeyBuilderContext, PermissionMode, PermissionPolicy, PluginEndpointMeta, PluginPermissionsConfig, RequiredPluginEndpointMeta, RequiredPluginEndpointSchemas, RequiredPluginWebhookSchemas, WebhookHooks, } from './plugins';
43
43
  export type { Bivariant, UnionToIntersection } from './utils';
44
44
  export type { BindWebhooks, BoundWebhook, BoundWebhookTree, CorsairWebhook, CorsairWebhookHandler, CorsairWebhookMatcher, RawWebhookRequest, WebhookPathsOf, WebhookRequest, WebhookResponse, WebhookTree, } from './webhooks';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../core/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../core/index.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { CorsairPlugin } from '../plugins';
2
+ type DbFieldType = 'string' | 'number' | 'boolean' | 'date';
2
3
  export type EndpointSchemaResult = {
3
4
  /** Human-readable description of what this endpoint does. */
4
5
  description?: string;
@@ -34,102 +35,114 @@ export type WebhookSchemaResult = {
34
35
  */
35
36
  availableWebhooks?: Record<string, string[]>;
36
37
  };
37
- export type CorsairInspectMethods = {
38
+ export type DbSearchSchemaResult = {
38
39
  /**
39
- * Returns all available endpoint paths for every registered plugin.
40
- * Keys are plugin IDs, values are arrays of full-form paths (plugin.api.group.method), all lowercase.
41
- *
42
- * @example
43
- * corsair.get_methods()
44
- * // { slack: ['slack.api.channels.list', 'slack.api.messages.post', ...], github: ['github.api.issues.list', ...] }
40
+ * What this entity type represents and how to search it.
41
+ * Pass `limit` and `offset` as numbers for pagination.
45
42
  */
46
- get_methods(): Record<string, string[]>;
43
+ description: string;
47
44
  /**
48
- * Returns all available endpoint paths for a specific plugin.
49
- * Paths are full-form (plugin.api.group.method), all lowercase, and can be passed directly to get_schema().
45
+ * Filterable fields for the search() call.
46
+ * All active filters are AND-combined. Omit a field to skip filtering on it.
50
47
  *
51
- * @example
52
- * corsair.get_methods('slack')
53
- * // ['slack.api.channels.list', 'slack.api.channels.get', 'slack.api.messages.post', ...]
48
+ * Each operator shorthand: passing a raw value (string/number/boolean/Date) is
49
+ * equivalent to `{ equals: value }`.
54
50
  */
55
- get_methods(plugin: string): string[];
51
+ filters: {
52
+ /** Filter by the entity's external platform ID (e.g. a Slack channel ID). */
53
+ entity_id: {
54
+ type: 'string';
55
+ operators: string[];
56
+ };
57
+ /**
58
+ * Filter by fields inside the entity's data payload.
59
+ * Only flat primitive fields are listed — nested objects are not filterable.
60
+ */
61
+ data: Record<string, {
62
+ type: DbFieldType;
63
+ operators: string[];
64
+ }>;
65
+ };
66
+ };
67
+ export type ListOperationsOptions = {
56
68
  /**
57
- * Returns schema and metadata for a specific endpoint.
58
- * Pass the full dot-path including the plugin ID and 'api' segment: 'slack.api.channels.list'.
59
- * Casing is ignored the method string is lowercased before lookup.
60
- * If the method is not found, returns an empty result with `availableMethods` listing all valid paths.
61
- *
62
- * @example
63
- * corsair.get_schema('slack.api.channels.list')
64
- * // { description: '...', riskLevel: 'read', input: { type: 'object', ... }, output: { ... } }
65
- *
66
- * corsair.get_schema('slack.api.channels.getHistory') // casing normalised automatically
67
- * // { description: '...', riskLevel: 'read', input: { type: 'object', ... }, output: { ... } }
68
- *
69
- * corsair.get_schema('slack.api.invalid')
70
- * // { availableMethods: { slack: ['slack.api.channels.list', ...], ... } }
69
+ * Filter to a specific plugin by its ID (e.g. 'slack', 'github').
70
+ * - If the plugin is known but not added to the Corsair instance, a plain string message is returned.
71
+ * - If the string is completely unrecognised, returns all API endpoints as a fallback.
71
72
  */
72
- get_schema(method: string): EndpointSchemaResult;
73
+ plugin?: string;
73
74
  /**
74
- * Returns all available webhook paths for every registered plugin.
75
- * Keys are plugin IDs, values are arrays of full dot-paths (pluginId.group.event).
76
- * Pass a path directly to get_webhook_schema() to get its usage example and type info.
77
- *
78
- * @example
79
- * corsair.get_webhooks()
80
- * // {
81
- * // slack: ['slack.messages.message', 'slack.channels.created', ...],
82
- * // googlecalendar: ['googlecalendar.onEventChanged', 'googlecalendar.onEventCreated', ...],
83
- * // }
75
+ * Whether to list API endpoints, webhooks, or database entities.
76
+ * - 'api' (default) lists callable API endpoint paths
77
+ * - 'webhooks' lists receivable webhook event paths
78
+ * - 'db' — lists searchable database entity paths (one .search per entity type)
84
79
  */
85
- get_webhooks(): Record<string, string[]>;
80
+ type?: 'api' | 'webhooks' | 'db';
81
+ };
82
+ export type CorsairInspectMethods = {
86
83
  /**
87
- * Returns all available webhook paths for a specific plugin.
84
+ * Lists available operations (API endpoints, webhooks, or database entities) for the configured plugins.
85
+ *
86
+ * - No options → all API endpoint paths across every plugin, keyed by plugin ID
87
+ * - `{ type: 'webhooks' }` → all webhook paths across every plugin, keyed by plugin ID
88
+ * - `{ type: 'db' }` → all searchable DB entity paths across every plugin, keyed by plugin ID
89
+ * - `{ plugin: 'slack' }` → Slack API endpoint paths as a flat array
90
+ * - `{ plugin: 'slack', type: 'webhooks' }` → Slack webhook paths as a flat array
91
+ * - `{ plugin: 'slack', type: 'db' }` → Slack DB entity search paths as a flat array
92
+ * - If the plugin is known but not configured, returns a plain string message.
93
+ * - If the plugin string is completely unrecognised, returns all API endpoints (same as no options).
94
+ *
95
+ * API paths use the format `plugin.api.group.method` (e.g. `slack.api.messages.post`).
96
+ * Webhook paths use the format `plugin.webhooks.group.event` (e.g. `slack.webhooks.messages.message`).
97
+ * DB paths use the format `plugin.db.entityType.search` (e.g. `slack.db.messages.search`).
98
+ * All paths can be passed directly to `get_schema()`.
88
99
  *
89
100
  * @example
90
- * corsair.get_webhooks('slack')
91
- * // ['slack.messages.message', 'slack.channels.created', ...]
101
+ * corsair.list_operations()
102
+ * // { slack: ['slack.api.channels.list', 'slack.api.messages.post', ...], ... }
103
+ *
104
+ * corsair.list_operations({ plugin: 'slack' })
105
+ * // ['slack.api.channels.list', 'slack.api.messages.post', ...]
106
+ *
107
+ * corsair.list_operations({ plugin: 'slack', type: 'webhooks' })
108
+ * // ['slack.webhooks.messages.message', 'slack.webhooks.channels.created', ...]
109
+ *
110
+ * corsair.list_operations({ plugin: 'slack', type: 'db' })
111
+ * // ['slack.db.messages.search', 'slack.db.channels.search', 'slack.db.users.search', ...]
112
+ *
113
+ * corsair.list_operations({ plugin: 'unknown' })
114
+ * // "unknown isn't configured in the Corsair instance."
92
115
  */
93
- get_webhooks(plugin: string): string[];
116
+ list_operations(options?: ListOperationsOptions): Record<string, string[]> | string[] | string;
94
117
  /**
95
- * Returns a ready-to-copy usage example plus type information for a specific webhook.
96
- * Pass the dot-path from get_webhooks(): 'slack.messages.message'.
118
+ * Returns schema and metadata for a specific API endpoint, webhook, or database entity search.
119
+ * The path format determines which kind of schema is returned:
120
+ * - API path (`plugin.api.group.method`) → `EndpointSchemaResult`
121
+ * - Webhook path (`plugin.webhooks.group.event`) → `WebhookSchemaResult`
122
+ * - DB path (`plugin.db.entityType.search`) → `DbSearchSchemaResult`
123
+ *
97
124
  * Casing is ignored — the path is lowercased before lookup.
125
+ * If the path is not found, returns an object with available paths for self-correction.
126
+ *
127
+ * @example
128
+ * corsair.get_schema('slack.api.channels.list')
129
+ * // { description: '...', riskLevel: 'read', input: { type: 'object', ... }, output: { ... } }
98
130
  *
99
- * The `usage` field is a complete code snippet showing how to configure this webhook
100
- * inside the plugin options, with the response.data type embedded as an inline comment.
131
+ * corsair.get_schema('slack.webhooks.messages.message')
132
+ * // { description: '...', usage: '...', payload: { ... }, response: { ... } }
101
133
  *
102
- * If the webhook path is not found, returns `availableWebhooks` for self-correction.
134
+ * corsair.get_schema('slack.db.messages.search')
135
+ * // { description: '...', filters: { entity_id: { ... }, data: { text: { type: 'string', operators: [...] }, ... } } }
103
136
  *
104
- * @example
105
- * corsair.get_webhook_schema('slack.messages.message')
106
- * // {
107
- * // description: 'Fires when a message is posted',
108
- * // usage: `
109
- * // slack({
110
- * // webhookHooks: {
111
- * // messages: {
112
- * // message: {
113
- * // before(ctx, args) {
114
- * // return { ctx, args };
115
- * // },
116
- * // after(ctx, response) {
117
- * // // response.data:
118
- * // // { "type": "object", ... }
119
- * // },
120
- * // },
121
- * // },
122
- * // },
123
- * // })`,
124
- * // payload: { ... },
125
- * // response: { ... },
126
- * // }
137
+ * corsair.get_schema('slack.api.invalid')
138
+ * // { availableMethods: { slack: ['slack.api.channels.list', ...], ... } }
127
139
  */
128
- get_webhook_schema(webhook: string): WebhookSchemaResult;
140
+ get_schema(path: string): EndpointSchemaResult | WebhookSchemaResult | DbSearchSchemaResult;
129
141
  };
130
142
  /**
131
- * Creates the get_methods / get_schema / get_webhooks / get_webhook_schema functions
132
- * bound to a specific plugin list. Used by both single-tenant and multi-tenant client builders.
143
+ * Creates the list_operations / get_schema functions bound to a specific plugin list.
144
+ * Used by both single-tenant and multi-tenant client builders.
133
145
  */
134
146
  export declare function buildInspectMethods(plugins: readonly CorsairPlugin[]): CorsairInspectMethods;
147
+ export {};
135
148
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/inspect/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AAqFnE,MAAM,MAAM,oBAAoB,GAAG;IAClC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;IAC7C,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IACjC,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8FAA8F;IAC9F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iGAAiG;IACjG,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IACnC;;;;;;;OAOG;IACH,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC;;;;;;;OAOG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtC;;;;;;;;;;;;;;;OAeG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CAAC;IACjD;;;;;;;;;;;OAWG;IACH,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACzC;;;;;;OAMG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAAC;CACzD,CAAC;AAkUF;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,SAAS,aAAa,EAAE,GAC/B,qBAAqB,CAgBvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/inspect/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AA2FnE,KAAK,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAyF5D,MAAM,MAAM,oBAAoB,GAAG;IAClC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;IAC7C,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IACjC,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8FAA8F;IAC9F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iGAAiG;IACjG,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAClC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,OAAO,EAAE;QACR,6EAA6E;QAC7E,SAAS,EAAE;YAAE,IAAI,EAAE,QAAQ,CAAC;YAAC,SAAS,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QACnD;;;WAGG;QACH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,IAAI,EAAE,WAAW,CAAC;YAAC,SAAS,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAC;KACjE,CAAC;CACF,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IACnC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,KAAK,GAAG,UAAU,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IACnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,eAAe,CACd,OAAO,CAAC,EAAE,qBAAqB,GAC7B,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC;IAChD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,CACT,IAAI,EAAE,MAAM,GACV,oBAAoB,GAAG,mBAAmB,GAAG,oBAAoB,CAAC;CACrE,CAAC;AAmYF;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,SAAS,aAAa,EAAE,GAC/B,qBAAqB,CASvB"}
@@ -1,3 +1,4 @@
1
+ import { BaseProviders } from '../constants';
1
2
  // ─────────────────────────────────────────────────────────────────────────────
2
3
  // Zod → JSON Schema Converter
3
4
  // ─────────────────────────────────────────────────────────────────────────────
@@ -74,6 +75,89 @@ function zodToJsonSchema(schema) {
74
75
  }
75
76
  }
76
77
  // ─────────────────────────────────────────────────────────────────────────────
78
+ // DB Entity Helpers
79
+ // ─────────────────────────────────────────────────────────────────────────────
80
+ const STRING_OPERATORS = ['equals', 'contains', 'startsWith', 'endsWith', 'in'];
81
+ const NUMBER_OPERATORS = ['equals', 'gt', 'gte', 'lt', 'lte', 'in'];
82
+ const BOOLEAN_OPERATORS = ['equals'];
83
+ const DATE_OPERATORS = ['equals', 'before', 'after', 'between'];
84
+ /**
85
+ * Unwraps Optional/Nullable/Default/Effects wrappers to find the primitive leaf type.
86
+ * Returns null for complex types (objects, arrays, unions) that are not directly filterable.
87
+ */
88
+ function getSchemaLeafType(schema) {
89
+ const def = schema._def;
90
+ const typeName = def.typeName;
91
+ switch (typeName) {
92
+ case 'ZodOptional':
93
+ case 'ZodNullable':
94
+ case 'ZodDefault':
95
+ return getSchemaLeafType(def.innerType);
96
+ case 'ZodEffects':
97
+ // Covers z.coerce.date() and other transforms
98
+ return getSchemaLeafType(def.schema);
99
+ case 'ZodString':
100
+ return 'string';
101
+ case 'ZodNumber':
102
+ return 'number';
103
+ case 'ZodBoolean':
104
+ return 'boolean';
105
+ case 'ZodDate':
106
+ return 'date';
107
+ default:
108
+ return null;
109
+ }
110
+ }
111
+ /**
112
+ * Derives the filterable fields from a Zod object schema.
113
+ * Only flat primitive fields (string, number, boolean, date) are included.
114
+ * Nested objects and arrays are skipped — the ORM does not support filtering into them.
115
+ */
116
+ function buildFilterableFields(schema) {
117
+ const def = schema._def;
118
+ const typeName = def.typeName;
119
+ if (typeName === 'ZodOptional' ||
120
+ typeName === 'ZodNullable' ||
121
+ typeName === 'ZodDefault') {
122
+ return buildFilterableFields(def.innerType);
123
+ }
124
+ if (typeName === 'ZodEffects') {
125
+ return buildFilterableFields(def.schema);
126
+ }
127
+ if (typeName !== 'ZodObject')
128
+ return {};
129
+ const shape = def.shape();
130
+ const result = {};
131
+ for (const [key, fieldSchema] of Object.entries(shape)) {
132
+ const leafType = getSchemaLeafType(fieldSchema);
133
+ if (leafType === 'string') {
134
+ result[key] = { type: 'string', operators: STRING_OPERATORS };
135
+ }
136
+ else if (leafType === 'number') {
137
+ result[key] = { type: 'number', operators: NUMBER_OPERATORS };
138
+ }
139
+ else if (leafType === 'boolean') {
140
+ result[key] = { type: 'boolean', operators: BOOLEAN_OPERATORS };
141
+ }
142
+ else if (leafType === 'date') {
143
+ result[key] = { type: 'date', operators: DATE_OPERATORS };
144
+ }
145
+ // Nested objects, arrays, unions — not filterable via ORM, omit them
146
+ }
147
+ return result;
148
+ }
149
+ /**
150
+ * Case-insensitive lookup for an entity name in a schema's entities map.
151
+ * Entity names are camelCase (e.g. 'userGroups') but agent paths are lowercased.
152
+ */
153
+ function findEntityCaseInsensitive(entities, lowercasedName) {
154
+ for (const [key, schema] of Object.entries(entities)) {
155
+ if (key.toLowerCase() === lowercasedName)
156
+ return [key, schema];
157
+ }
158
+ return undefined;
159
+ }
160
+ // ─────────────────────────────────────────────────────────────────────────────
77
161
  // Endpoint Tree Walker
78
162
  // ─────────────────────────────────────────────────────────────────────────────
79
163
  function walkEndpointTree(tree, pathParts, result) {
@@ -190,43 +274,75 @@ function buildWebhookUsageExample(pluginId, pathParts, responseSchema) {
190
274
  return lines.join('\n');
191
275
  }
192
276
  // ─────────────────────────────────────────────────────────────────────────────
277
+ // Known Plugin Registry
278
+ // ─────────────────────────────────────────────────────────────────────────────
279
+ /**
280
+ * Set of all plugin IDs that ship with the corsair package.
281
+ * Derived from BaseProviders (core/constants.ts) — the single source of truth.
282
+ * Used to distinguish "valid but not configured" from "completely unknown" plugin strings.
283
+ */
284
+ const KNOWN_PLUGIN_IDS = new Set(BaseProviders);
285
+ // ─────────────────────────────────────────────────────────────────────────────
193
286
  // Core Functions
194
287
  // ─────────────────────────────────────────────────────────────────────────────
195
- function getMethods(plugins, plugin) {
196
- if (plugin !== undefined) {
197
- const found = plugins.find((p) => p.id === plugin);
198
- if (!found?.endpoints)
288
+ function listOperations(plugins, options) {
289
+ const type = options?.type ?? 'api';
290
+ const pluginId = options?.plugin;
291
+ if (pluginId !== undefined) {
292
+ const found = plugins.find((p) => p.id === pluginId);
293
+ if (!found) {
294
+ // Known plugin (exists in the package) but not added to this instance
295
+ if (KNOWN_PLUGIN_IDS.has(pluginId)) {
296
+ return `This plugin (${pluginId}) is not configured. Please add it to the Corsair instance to see its associated methods.`;
297
+ }
298
+ // Completely unknown string — fall through to return all API endpoints
299
+ return listOperations(plugins);
300
+ }
301
+ if (type === 'webhooks') {
302
+ if (!found.webhooks)
303
+ return [];
304
+ const paths = [];
305
+ walkWebhookTree(found.webhooks, [], paths);
306
+ return paths.map((path) => `${found.id}.webhooks.${path}`);
307
+ }
308
+ if (type === 'db') {
309
+ const entities = found.schema?.entities;
310
+ if (!entities)
311
+ return [];
312
+ return Object.keys(entities).map((entityName) => `${found.id}.db.${entityName}.search`);
313
+ }
314
+ if (!found.endpoints)
199
315
  return [];
200
316
  const paths = [];
201
317
  walkEndpointTree(found.endpoints, [], paths);
202
318
  return paths.map((path) => `${found.id}.api.${path.toLowerCase()}`);
203
319
  }
204
320
  const result = {};
205
- for (const p of plugins) {
206
- if (!p.endpoints)
207
- continue;
208
- const paths = [];
209
- walkEndpointTree(p.endpoints, [], paths);
210
- result[p.id] = paths.map((path) => `${p.id}.api.${path.toLowerCase()}`);
321
+ if (type === 'webhooks') {
322
+ for (const p of plugins) {
323
+ if (!p.webhooks)
324
+ continue;
325
+ const paths = [];
326
+ walkWebhookTree(p.webhooks, [], paths);
327
+ result[p.id] = paths.map((path) => `${p.id}.webhooks.${path}`);
328
+ }
211
329
  }
212
- return result;
213
- }
214
- function getWebhooks(plugins, plugin) {
215
- if (plugin !== undefined) {
216
- const found = plugins.find((p) => p.id === plugin);
217
- if (!found?.webhooks)
218
- return [];
219
- const paths = [];
220
- walkWebhookTree(found.webhooks, [], paths);
221
- return paths.map((path) => `${found.id}.${path}`);
330
+ else if (type === 'db') {
331
+ for (const p of plugins) {
332
+ const entities = p.schema?.entities;
333
+ if (!entities)
334
+ continue;
335
+ result[p.id] = Object.keys(entities).map((entityName) => `${p.id}.db.${entityName}.search`);
336
+ }
222
337
  }
223
- const result = {};
224
- for (const p of plugins) {
225
- if (!p.webhooks)
226
- continue;
227
- const paths = [];
228
- walkWebhookTree(p.webhooks, [], paths);
229
- result[p.id] = paths.map((path) => `${p.id}.${path}`);
338
+ else {
339
+ for (const p of plugins) {
340
+ if (!p.endpoints)
341
+ continue;
342
+ const paths = [];
343
+ walkEndpointTree(p.endpoints, [], paths);
344
+ result[p.id] = paths.map((path) => `${p.id}.api.${path.toLowerCase()}`);
345
+ }
230
346
  }
231
347
  return result;
232
348
  }
@@ -244,22 +360,82 @@ function findEndpointCaseInsensitive(record, lowercasedPath) {
244
360
  }
245
361
  return undefined;
246
362
  }
247
- function getSchema(plugins, method) {
363
+ function getSchema(plugins, path) {
248
364
  // Normalise casing so the agent can call with any capitalisation
249
- const normalised = method.toLowerCase();
365
+ const normalised = path.toLowerCase();
250
366
  const dotIndex = normalised.indexOf('.');
251
367
  if (dotIndex !== -1) {
252
368
  const pluginId = normalised.slice(0, dotIndex);
253
- let remainder = normalised.slice(dotIndex + 1);
254
- // Strip the optional 'api.' segment (present in the new full-form paths)
255
- if (remainder.startsWith('api.')) {
256
- remainder = remainder.slice(4);
257
- }
369
+ const remainder = normalised.slice(dotIndex + 1);
258
370
  const plugin = plugins.find((p) => p.id === pluginId);
259
371
  if (plugin) {
260
- const meta = findEndpointCaseInsensitive(plugin.endpointMeta, remainder);
261
- const schemas = findEndpointCaseInsensitive(plugin.endpointSchemas, remainder);
262
- // Valid entry meta or schemas found
372
+ // ── DB search path: plugin.db.entityType.search ────────────────────────
373
+ if (remainder.startsWith('db.')) {
374
+ const dbPath = remainder.slice(3); // strip 'db.'
375
+ const lastDot = dbPath.lastIndexOf('.');
376
+ if (lastDot !== -1) {
377
+ const entityNameLower = dbPath.slice(0, lastDot);
378
+ const method = dbPath.slice(lastDot + 1);
379
+ const entities = plugin.schema?.entities;
380
+ if (method === 'search' && entities) {
381
+ const entry = findEntityCaseInsensitive(entities, entityNameLower);
382
+ if (entry) {
383
+ const [entityName, entitySchema] = entry;
384
+ return {
385
+ description: `Search ${pluginId} ${entityName} stored in the local database. Returns an array of matching records. Pass limit and offset (numbers) for pagination.`,
386
+ filters: {
387
+ entity_id: {
388
+ type: 'string',
389
+ operators: STRING_OPERATORS,
390
+ },
391
+ data: buildFilterableFields(entitySchema),
392
+ },
393
+ };
394
+ }
395
+ }
396
+ }
397
+ // Invalid db path — return available db operations for self-correction
398
+ return {
399
+ availableMethods: listOperations(plugins, {
400
+ type: 'db',
401
+ }),
402
+ };
403
+ }
404
+ // ── Webhook path: plugin.webhooks.group.event ──────────────────────────
405
+ if (remainder.startsWith('webhooks.')) {
406
+ const webhookPathNormalised = remainder.slice(9); // strip 'webhooks.'
407
+ if (plugin.webhooks) {
408
+ const originalPathParts = resolveWebhookPathOriginalCase(plugin.webhooks, webhookPathNormalised.split('.'));
409
+ if (originalPathParts !== null) {
410
+ const originalPath = originalPathParts.join('.');
411
+ const schemas = findEndpointCaseInsensitive(plugin.webhookSchemas, originalPath.toLowerCase());
412
+ const responseSchema = schemas?.response
413
+ ? zodToJsonSchema(schemas.response)
414
+ : null;
415
+ return {
416
+ description: schemas?.description,
417
+ payload: schemas?.payload
418
+ ? zodToJsonSchema(schemas.payload)
419
+ : undefined,
420
+ response: responseSchema ?? undefined,
421
+ usage: buildWebhookUsageExample(pluginId, originalPathParts, responseSchema),
422
+ };
423
+ }
424
+ }
425
+ // Invalid webhook path — return available webhooks for self-correction
426
+ return {
427
+ availableWebhooks: listOperations(plugins, {
428
+ type: 'webhooks',
429
+ }),
430
+ };
431
+ }
432
+ // ── API endpoint path: plugin.api.group.method ─────────────────────────
433
+ let endpointPath = remainder;
434
+ if (endpointPath.startsWith('api.')) {
435
+ endpointPath = endpointPath.slice(4);
436
+ }
437
+ const meta = findEndpointCaseInsensitive(plugin.endpointMeta, endpointPath);
438
+ const schemas = findEndpointCaseInsensitive(plugin.endpointSchemas, endpointPath);
263
439
  if (meta || schemas) {
264
440
  return {
265
441
  description: meta?.description,
@@ -271,63 +447,25 @@ function getSchema(plugins, method) {
271
447
  }
272
448
  }
273
449
  }
274
- // Invalid or unknown method — return all available methods so the caller can self-correct
275
- return { availableMethods: getMethods(plugins) };
276
- }
277
- function getWebhookSchema(plugins, webhook) {
278
- // Normalise casing so the agent can call with any capitalisation
279
- const normalised = webhook.toLowerCase();
280
- const dotIndex = normalised.indexOf('.');
281
- if (dotIndex !== -1) {
282
- const pluginId = normalised.slice(0, dotIndex);
283
- const webhookPathNormalised = normalised.slice(dotIndex + 1);
284
- const plugin = plugins.find((p) => p.id === pluginId);
285
- if (plugin?.webhooks) {
286
- // Resolve original-cased key segments from the webhook tree
287
- const originalPathParts = resolveWebhookPathOriginalCase(plugin.webhooks, webhookPathNormalised.split('.'));
288
- if (originalPathParts !== null) {
289
- // Look up optional schemas using original-cased path (case-insensitive fallback)
290
- const originalPath = originalPathParts.join('.');
291
- const schemas = findEndpointCaseInsensitive(plugin.webhookSchemas, originalPath.toLowerCase());
292
- const responseSchema = schemas?.response
293
- ? zodToJsonSchema(schemas.response)
294
- : null;
295
- return {
296
- description: schemas?.description,
297
- payload: schemas?.payload
298
- ? zodToJsonSchema(schemas.payload)
299
- : undefined,
300
- response: responseSchema ?? undefined,
301
- usage: buildWebhookUsageExample(pluginId, originalPathParts, responseSchema),
302
- };
303
- }
304
- }
305
- }
306
- // Invalid or unknown webhook — return all available webhooks so the caller can self-correct
450
+ // Invalid or unknown path — return all available API methods for self-correction
307
451
  return {
308
- availableWebhooks: getWebhooks(plugins),
452
+ availableMethods: listOperations(plugins),
309
453
  };
310
454
  }
311
455
  // ─────────────────────────────────────────────────────────────────────────────
312
456
  // Factory — binds inspect methods to a fixed plugin list
313
457
  // ─────────────────────────────────────────────────────────────────────────────
314
458
  /**
315
- * Creates the get_methods / get_schema / get_webhooks / get_webhook_schema functions
316
- * bound to a specific plugin list. Used by both single-tenant and multi-tenant client builders.
459
+ * Creates the list_operations / get_schema functions bound to a specific plugin list.
460
+ * Used by both single-tenant and multi-tenant client builders.
317
461
  */
318
462
  export function buildInspectMethods(plugins) {
319
463
  return {
320
- get_methods(plugin) {
321
- return getMethods(plugins, plugin);
322
- },
323
- get_schema(method) {
324
- return getSchema(plugins, method);
325
- },
326
- get_webhooks(plugin) {
327
- return getWebhooks(plugins, plugin);
464
+ list_operations(options) {
465
+ return listOperations(plugins, options);
328
466
  },
329
- get_webhook_schema(webhook) {
330
- return getWebhookSchema(plugins, webhook);
467
+ get_schema(path) {
468
+ return getSchema(plugins, path);
331
469
  },
332
470
  };
333
471
  }
@@ -330,7 +330,7 @@ export type CorsairPlugin<Id extends AllProviders = AllProviders, Schema extends
330
330
  /**
331
331
  * Risk metadata for each endpoint in this plugin. Drives the permission system:
332
332
  * riskLevel against the active mode determines the policy (allow / deny / require_approval).
333
- * Also used by get_schema() to surface descriptions to the agent.
333
+ * Also used by list_operations() and get_schema() to surface descriptions to the agent.
334
334
  *
335
335
  * Keys are dot-notation paths derived from `Endpoints` — only valid paths compile.
336
336
  *
@@ -346,7 +346,7 @@ export type CorsairPlugin<Id extends AllProviders = AllProviders, Schema extends
346
346
  endpointMeta?: Endpoints extends EndpointTree ? PluginEndpointMeta<Endpoints> : never;
347
347
  /**
348
348
  * Zod input and output schemas for each endpoint, keyed by dot-notation path.
349
- * Used by get_schema() to expose structured type information to the agent.
349
+ * Used by get_schema() to expose structured endpoint type information to the agent.
350
350
  * Keys must match the endpoint dot-paths used in endpointMeta.
351
351
  *
352
352
  * @example
@@ -363,7 +363,7 @@ export type CorsairPlugin<Id extends AllProviders = AllProviders, Schema extends
363
363
  }>;
364
364
  /**
365
365
  * Zod schemas for each webhook, keyed by dot-notation path.
366
- * Used by get_webhook_schema() to expose structured type information to the agent.
366
+ * Used by get_schema() to expose structured webhook type information to the agent.
367
367
  * Keys must match the dot-paths of the webhook tree (e.g. 'messages.message').
368
368
  *
369
369
  * - `payload` — the type of `request.payload` in the before hook