@executor-js/sdk 1.5.17 → 1.5.18
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/{chunk-5Q35SELN.js → chunk-UWBP7WLB.js} +125 -9
- package/dist/chunk-UWBP7WLB.js.map +1 -0
- package/dist/client.d.ts +13 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js.map +1 -1
- package/dist/core-tools.d.ts +3 -0
- package/dist/core-tools.d.ts.map +1 -1
- package/dist/core.js +1 -1
- package/dist/executor.d.ts +1 -0
- package/dist/executor.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/testing.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-5Q35SELN.js.map +0 -1
|
@@ -3167,7 +3167,14 @@ var ConnectionCreateInput = Schema2.Struct({
|
|
|
3167
3167
|
}).check(
|
|
3168
3168
|
Schema2.makeFilter((payload) => {
|
|
3169
3169
|
const originCount = (payload.from === void 0 ? 0 : 1) + (payload.inputs === void 0 ? 0 : 1);
|
|
3170
|
-
|
|
3170
|
+
const isNoAuth = String(payload.template) === String(NO_AUTH_TEMPLATE);
|
|
3171
|
+
if (isNoAuth) {
|
|
3172
|
+
if (originCount > 0) {
|
|
3173
|
+
return 'A no-auth connection (template "none") takes no provider credential origin';
|
|
3174
|
+
}
|
|
3175
|
+
} else if (originCount !== 1) {
|
|
3176
|
+
return "Expected exactly one provider credential origin";
|
|
3177
|
+
}
|
|
3171
3178
|
if (payload.inputs !== void 0 && Object.keys(payload.inputs).length === 0) {
|
|
3172
3179
|
return "Expected at least one provider credential input";
|
|
3173
3180
|
}
|
|
@@ -3251,9 +3258,23 @@ var OAuthCreateClientInput = Schema2.Struct({
|
|
|
3251
3258
|
tokenUrl: Schema2.String,
|
|
3252
3259
|
grant: OAuthGrantSchema,
|
|
3253
3260
|
clientId: Schema2.String,
|
|
3254
|
-
clientSecret: Schema2.String,
|
|
3255
3261
|
resource: Schema2.optional(Schema2.NullOr(Schema2.String))
|
|
3256
3262
|
});
|
|
3263
|
+
var OAuthCreateClientHandoffInput = Schema2.Struct({
|
|
3264
|
+
integration: Schema2.String,
|
|
3265
|
+
owner: Schema2.optional(OwnerSchema),
|
|
3266
|
+
slug: Schema2.optional(Schema2.String),
|
|
3267
|
+
grant: Schema2.optional(OAuthGrantSchema),
|
|
3268
|
+
clientId: Schema2.optional(Schema2.String),
|
|
3269
|
+
authorizationUrl: Schema2.optional(Schema2.String),
|
|
3270
|
+
tokenUrl: Schema2.optional(Schema2.String),
|
|
3271
|
+
resource: Schema2.optional(Schema2.NullOr(Schema2.String)),
|
|
3272
|
+
label: Schema2.optional(Schema2.String)
|
|
3273
|
+
});
|
|
3274
|
+
var OAuthCreateClientHandoffOutput = Schema2.Struct({
|
|
3275
|
+
url: Schema2.String,
|
|
3276
|
+
instructions: Schema2.String
|
|
3277
|
+
});
|
|
3257
3278
|
var OAuthClientOutputRef = Schema2.Struct({
|
|
3258
3279
|
client: Schema2.String
|
|
3259
3280
|
});
|
|
@@ -3332,6 +3353,8 @@ var PolicyUpdateInputStd = schemaToStandard(PolicyUpdateInput);
|
|
|
3332
3353
|
var PolicyRemoveInputStd = schemaToStandard(PolicyRemoveInput);
|
|
3333
3354
|
var OAuthClientsListOutputStd = schemaToStandard(OAuthClientsListOutput);
|
|
3334
3355
|
var OAuthCreateClientInputStd = schemaToStandard(OAuthCreateClientInput);
|
|
3356
|
+
var OAuthCreateClientHandoffInputStd = schemaToStandard(OAuthCreateClientHandoffInput);
|
|
3357
|
+
var OAuthCreateClientHandoffOutputStd = schemaToStandard(OAuthCreateClientHandoffOutput);
|
|
3335
3358
|
var OAuthClientOutputRefStd = schemaToStandard(OAuthClientOutputRef);
|
|
3336
3359
|
var OAuthRegisterDynamicInputStd = schemaToStandard(OAuthRegisterDynamicInput);
|
|
3337
3360
|
var OAuthRemoveClientInputStd = schemaToStandard(OAuthRemoveClientInput);
|
|
@@ -3417,12 +3440,28 @@ var createConnectionInputFromTool = (input) => {
|
|
|
3417
3440
|
)
|
|
3418
3441
|
};
|
|
3419
3442
|
};
|
|
3420
|
-
var connectionCreateHandoffUrl = (webBaseUrl, input) => {
|
|
3443
|
+
var connectionCreateHandoffUrl = (webBaseUrl, orgSlug, input) => {
|
|
3421
3444
|
const search = new URLSearchParams({ addAccount: "1" });
|
|
3422
3445
|
if (input.owner !== void 0) search.set("owner", input.owner);
|
|
3423
3446
|
if (input.template !== void 0) search.set("template", input.template);
|
|
3424
3447
|
if (input.label !== void 0) search.set("label", input.label);
|
|
3425
|
-
const
|
|
3448
|
+
const orgPrefix = orgSlug !== void 0 && orgSlug.length > 0 ? `/${orgSlug}` : "";
|
|
3449
|
+
const path = `${orgPrefix}/integrations/${encodeURIComponent(input.integration)}?${search.toString()}`;
|
|
3450
|
+
if (webBaseUrl === void 0 || webBaseUrl.length === 0) return path;
|
|
3451
|
+
return new URL(path, webBaseUrl.endsWith("/") ? webBaseUrl : `${webBaseUrl}/`).toString();
|
|
3452
|
+
};
|
|
3453
|
+
var oauthClientCreateHandoffUrl = (webBaseUrl, orgSlug, input) => {
|
|
3454
|
+
const search = new URLSearchParams({ addAccount: "1", oauthClient: "1" });
|
|
3455
|
+
if (input.owner !== void 0) search.set("owner", input.owner);
|
|
3456
|
+
if (input.slug !== void 0) search.set("clientSlug", input.slug);
|
|
3457
|
+
if (input.grant !== void 0) search.set("grant", input.grant);
|
|
3458
|
+
if (input.clientId !== void 0) search.set("clientId", input.clientId);
|
|
3459
|
+
if (input.authorizationUrl !== void 0) search.set("authorizationUrl", input.authorizationUrl);
|
|
3460
|
+
if (input.tokenUrl !== void 0) search.set("tokenUrl", input.tokenUrl);
|
|
3461
|
+
if (input.resource != null && input.resource.length > 0) search.set("resource", input.resource);
|
|
3462
|
+
if (input.label !== void 0) search.set("label", input.label);
|
|
3463
|
+
const orgPrefix = orgSlug !== void 0 && orgSlug.length > 0 ? `/${orgSlug}` : "";
|
|
3464
|
+
const path = `${orgPrefix}/integrations/${encodeURIComponent(input.integration)}?${search.toString()}`;
|
|
3426
3465
|
if (webBaseUrl === void 0 || webBaseUrl.length === 0) return path;
|
|
3427
3466
|
return new URL(path, webBaseUrl.endsWith("/") ? webBaseUrl : `${webBaseUrl}/`).toString();
|
|
3428
3467
|
};
|
|
@@ -3485,9 +3524,16 @@ var coreToolsPlugin = definePlugin((options = {}) => ({
|
|
|
3485
3524
|
}),
|
|
3486
3525
|
tool({
|
|
3487
3526
|
name: "connections.create",
|
|
3488
|
-
description:
|
|
3527
|
+
description: 'Low-level create or replace for a saved connection from provider item references. For a no-auth integration (public MCP server, public REST API), pass `template: "none"` with no `from`/`inputs` to wire it up directly. For normal API keys/tokens, use `connections.createHandoff` so the user enters the credential in the web UI. OAuth credentials should use `oauth.start`.',
|
|
3489
3528
|
inputSchema: ConnectionCreateInputStd,
|
|
3490
3529
|
outputSchema: ConnectionOutputStd,
|
|
3530
|
+
// Creating a connection binds a credential reference and roots a new
|
|
3531
|
+
// tool catalog: every tool that connection produces then becomes
|
|
3532
|
+
// callable. Even the no-auth (`template: "none"`) path pulls tools
|
|
3533
|
+
// from an arbitrary endpoint. Prompt-injected code could silently
|
|
3534
|
+
// wire an attacker-chosen integration or credential, so this is
|
|
3535
|
+
// approval-gated (the v1 `sources.configure` carried the same guard).
|
|
3536
|
+
annotations: { requiresApproval: true },
|
|
3491
3537
|
execute: (input, { ctx }) => Effect5.map(
|
|
3492
3538
|
ctx.connections.create(createConnectionInputFromTool(input)),
|
|
3493
3539
|
connectionToOutput
|
|
@@ -3499,7 +3545,7 @@ var coreToolsPlugin = definePlugin((options = {}) => ({
|
|
|
3499
3545
|
inputSchema: ConnectionCreateHandoffInputStd,
|
|
3500
3546
|
outputSchema: ConnectionCreateHandoffOutputStd,
|
|
3501
3547
|
execute: (input) => {
|
|
3502
|
-
const url = connectionCreateHandoffUrl(options.webBaseUrl, input);
|
|
3548
|
+
const url = connectionCreateHandoffUrl(options.webBaseUrl, options.orgSlug, input);
|
|
3503
3549
|
return Effect5.succeed({
|
|
3504
3550
|
url,
|
|
3505
3551
|
instructions: "Ask the user to open this URL and add the account in the Executor web UI. Do not ask them to paste the credential value into chat. After they finish, call connections.list for the integration to discover the created connection."
|
|
@@ -3511,6 +3557,10 @@ var coreToolsPlugin = definePlugin((options = {}) => ({
|
|
|
3511
3557
|
description: "Remove a saved connection and its produced tools by owner, integration, and connection name.",
|
|
3512
3558
|
inputSchema: ConnectionRefInputStd,
|
|
3513
3559
|
outputSchema: RemovedOutputStd,
|
|
3560
|
+
// Deleting a connection drops it and every tool it produced, which
|
|
3561
|
+
// prompt-injected code could use to disrupt an integration or force a
|
|
3562
|
+
// re-add flow. Approval-gated, matching v1 `sources.remove`.
|
|
3563
|
+
annotations: { requiresApproval: true },
|
|
3514
3564
|
execute: (input, { ctx }) => Effect5.map(ctx.connections.remove(connectionRefFromInput(input)), () => ({
|
|
3515
3565
|
removed: true
|
|
3516
3566
|
}))
|
|
@@ -3520,6 +3570,11 @@ var coreToolsPlugin = definePlugin((options = {}) => ({
|
|
|
3520
3570
|
description: "Re-run an integration's tool production for a saved connection, replacing that connection's persisted tools.",
|
|
3521
3571
|
inputSchema: ConnectionRefInputStd,
|
|
3522
3572
|
outputSchema: ConnectionsRefreshOutputStd,
|
|
3573
|
+
// Refresh replaces a connection's persisted tool set; for a mutable
|
|
3574
|
+
// upstream (an MCP server whose catalog can change) this can swap in
|
|
3575
|
+
// different tools without confirmation. Approval-gated, matching v1
|
|
3576
|
+
// `sources.refresh`.
|
|
3577
|
+
annotations: { requiresApproval: true },
|
|
3523
3578
|
execute: (input, { ctx }) => Effect5.map(ctx.connections.refresh(connectionRefFromInput(input)), (tools) => ({
|
|
3524
3579
|
tools: tools.map(toolToOutput)
|
|
3525
3580
|
}))
|
|
@@ -3563,9 +3618,20 @@ var coreToolsPlugin = definePlugin((options = {}) => ({
|
|
|
3563
3618
|
}),
|
|
3564
3619
|
tool({
|
|
3565
3620
|
name: "oauth.clients.create",
|
|
3566
|
-
description: "Register or replace an owner-scoped OAuth client
|
|
3621
|
+
description: "Register or replace an owner-scoped OAuth client WITHOUT a client secret: a PUBLIC client (PKCE / authorization_code) or a discovery-prefill placeholder. To register a CONFIDENTIAL client that has a secret, call `oauth.clients.createHandoff` instead so the human enters the secret in the web UI; never pass a client secret through this tool.",
|
|
3567
3622
|
inputSchema: OAuthCreateClientInputStd,
|
|
3568
3623
|
outputSchema: OAuthClientOutputRefStd,
|
|
3624
|
+
// This persists an OAuth client and REPLACES on slug collision. It
|
|
3625
|
+
// takes NO client secret: a secret would have to travel through the
|
|
3626
|
+
// agent's context window, so a confidential app is registered by the
|
|
3627
|
+
// human via `oauth.clients.createHandoff`. An empty secret registers a
|
|
3628
|
+
// PUBLIC client. The remaining risk is the write itself: prompt-injected
|
|
3629
|
+
// code could register a client with an attacker-controlled
|
|
3630
|
+
// authorizationUrl/tokenUrl, then drive `oauth.start` to mint a
|
|
3631
|
+
// connection and route the user's tokens to the attacker. The
|
|
3632
|
+
// highest-value gate here; matches v1 `sources.bindings.set`, which
|
|
3633
|
+
// guarded credential writes.
|
|
3634
|
+
annotations: { requiresApproval: true },
|
|
3569
3635
|
execute: (input, { ctx }) => Effect5.map(
|
|
3570
3636
|
ctx.oauth.createClient({
|
|
3571
3637
|
owner: input.owner,
|
|
@@ -3574,17 +3640,40 @@ var coreToolsPlugin = definePlugin((options = {}) => ({
|
|
|
3574
3640
|
tokenUrl: input.tokenUrl,
|
|
3575
3641
|
grant: input.grant,
|
|
3576
3642
|
clientId: input.clientId,
|
|
3577
|
-
|
|
3643
|
+
// No secret crosses the agent boundary; an empty secret registers
|
|
3644
|
+
// a public client. Confidential clients go through
|
|
3645
|
+
// `oauth.clients.createHandoff`.
|
|
3646
|
+
clientSecret: "",
|
|
3578
3647
|
resource: input.resource ?? null
|
|
3579
3648
|
}),
|
|
3580
3649
|
(client) => ({ client: String(client) })
|
|
3581
3650
|
)
|
|
3582
3651
|
}),
|
|
3652
|
+
tool({
|
|
3653
|
+
name: "oauth.clients.createHandoff",
|
|
3654
|
+
description: "Return a browser URL that opens the Register-OAuth-app form for one integration, pre-filled with the non-secret fields (client id, endpoints, grant). Use this for any CONFIDENTIAL OAuth app: the user types the client secret directly in the web UI instead of sending it through the agent. After they register the app, call `oauth.clients.list` to discover its owner and slug, then `oauth.start`.",
|
|
3655
|
+
inputSchema: OAuthCreateClientHandoffInputStd,
|
|
3656
|
+
outputSchema: OAuthCreateClientHandoffOutputStd,
|
|
3657
|
+
// Pure URL builder: no DB write, no token, no secret. This is the SAFE
|
|
3658
|
+
// path (it routes the secret to the human in the browser), so it is
|
|
3659
|
+
// deliberately NOT approval-gated, mirroring `connections.createHandoff`.
|
|
3660
|
+
execute: (input) => {
|
|
3661
|
+
const url = oauthClientCreateHandoffUrl(options.webBaseUrl, options.orgSlug, input);
|
|
3662
|
+
return Effect5.succeed({
|
|
3663
|
+
url,
|
|
3664
|
+
instructions: "Ask the user to open this URL and register the OAuth app in the Executor web UI, entering the client secret there. Do not ask them to paste the client secret into chat. After they finish, call oauth.clients.list to find the registered client (owner + slug), then oauth.start."
|
|
3665
|
+
});
|
|
3666
|
+
}
|
|
3667
|
+
}),
|
|
3583
3668
|
tool({
|
|
3584
3669
|
name: "oauth.clients.registerDynamic",
|
|
3585
3670
|
description: "Register an OAuth client through RFC 7591 Dynamic Client Registration and save the minted client for later `oauth.start` calls.",
|
|
3586
3671
|
inputSchema: OAuthRegisterDynamicInputStd,
|
|
3587
3672
|
outputSchema: OAuthClientOutputRefStd,
|
|
3673
|
+
// Same risk class as `oauth.clients.create`: registers a client at a
|
|
3674
|
+
// caller-supplied endpoint and persists the minted credentials for
|
|
3675
|
+
// later `oauth.start` abuse. Approval-gated. See `oauth.clients.create`.
|
|
3676
|
+
annotations: { requiresApproval: true },
|
|
3588
3677
|
execute: (input, { ctx }) => Effect5.map(
|
|
3589
3678
|
ctx.oauth.registerDynamicClient({
|
|
3590
3679
|
owner: input.owner,
|
|
@@ -3607,6 +3696,11 @@ var coreToolsPlugin = definePlugin((options = {}) => ({
|
|
|
3607
3696
|
description: "Remove an owner-scoped OAuth client by owner and slug. Existing connections are not cascaded.",
|
|
3608
3697
|
inputSchema: OAuthRemoveClientInputStd,
|
|
3609
3698
|
outputSchema: RemovedOutputStd,
|
|
3699
|
+
// Removing a client breaks token refresh for every connection that
|
|
3700
|
+
// depends on it (a silent DoS) and can force re-auth through an
|
|
3701
|
+
// attacker-supplied replacement. Approval-gated, matching v1
|
|
3702
|
+
// `sources.bindings.remove`.
|
|
3703
|
+
annotations: { requiresApproval: true },
|
|
3610
3704
|
execute: (input, { ctx }) => Effect5.map(
|
|
3611
3705
|
ctx.oauth.removeClient(input.owner, OAuthClientSlug.make(input.slug)),
|
|
3612
3706
|
() => ({ removed: true })
|
|
@@ -3631,6 +3725,14 @@ var coreToolsPlugin = definePlugin((options = {}) => ({
|
|
|
3631
3725
|
description: "Start OAuth through a registered client to mint a connection for an integration. `client_credentials` clients return `connected`; authorization-code clients return an authorization URL and state.",
|
|
3632
3726
|
inputSchema: OAuthStartInputStd,
|
|
3633
3727
|
outputSchema: OAuthStartOutputStd,
|
|
3728
|
+
// This is the materialization step that turns a registered client
|
|
3729
|
+
// into a live connection. For `client_credentials` it completes
|
|
3730
|
+
// synchronously (status `connected`) with no browser step, so a
|
|
3731
|
+
// prompt-injected call against an attacker-registered client mints a
|
|
3732
|
+
// credentialed connection with no human in the loop. The
|
|
3733
|
+
// authorization-code path already returns a URL the user must visit,
|
|
3734
|
+
// but one gate on the whole tool covers the silent path cleanly.
|
|
3735
|
+
annotations: { requiresApproval: true },
|
|
3634
3736
|
execute: (input, { ctx }) => Effect5.map(
|
|
3635
3737
|
ctx.oauth.start({
|
|
3636
3738
|
client: OAuthClientSlug.make(input.client),
|
|
@@ -3678,6 +3780,11 @@ var coreToolsPlugin = definePlugin((options = {}) => ({
|
|
|
3678
3780
|
description: "Create a tool policy. `pattern` matches a tool address tail (`integration.connection.tool`, `integration.*`, `*`); `action` is approve/require_approval/block. `owner` is org (workspace guardrail) or user (personal).",
|
|
3679
3781
|
inputSchema: PolicyCreateInputStd,
|
|
3680
3782
|
outputSchema: PolicyOutputStd,
|
|
3783
|
+
// A policy decides which tools run without confirmation, so creating
|
|
3784
|
+
// one can silence every other approval gate (e.g. `approve *`). It
|
|
3785
|
+
// must itself require approval, otherwise prompt-injected code could
|
|
3786
|
+
// disable approvals by writing its own bypass policy.
|
|
3787
|
+
annotations: { requiresApproval: true },
|
|
3681
3788
|
execute: (input, { ctx }) => Effect5.map(
|
|
3682
3789
|
ctx.core.policies.create({
|
|
3683
3790
|
owner: input.owner,
|
|
@@ -3698,6 +3805,10 @@ var coreToolsPlugin = definePlugin((options = {}) => ({
|
|
|
3698
3805
|
description: "Update a tool policy's pattern and/or action by id + owner.",
|
|
3699
3806
|
inputSchema: PolicyUpdateInputStd,
|
|
3700
3807
|
outputSchema: PolicyOutputStd,
|
|
3808
|
+
// Editing a policy can broaden a pattern or flip an action to
|
|
3809
|
+
// `approve`, weakening an approval gate just as creation can, so it
|
|
3810
|
+
// requires approval too. See `policies.create`.
|
|
3811
|
+
annotations: { requiresApproval: true },
|
|
3701
3812
|
execute: (input, { ctx }) => Effect5.map(
|
|
3702
3813
|
ctx.core.policies.update({
|
|
3703
3814
|
id: input.id,
|
|
@@ -3719,6 +3830,10 @@ var coreToolsPlugin = definePlugin((options = {}) => ({
|
|
|
3719
3830
|
description: "Remove a tool policy by id + owner.",
|
|
3720
3831
|
inputSchema: PolicyRemoveInputStd,
|
|
3721
3832
|
outputSchema: RemovedOutputStd,
|
|
3833
|
+
// Removing a policy can drop a `block` or `require_approval`
|
|
3834
|
+
// guardrail, so deletion is also approval-gated. See
|
|
3835
|
+
// `policies.create`.
|
|
3836
|
+
annotations: { requiresApproval: true },
|
|
3722
3837
|
execute: (input, { ctx }) => Effect5.map(
|
|
3723
3838
|
ctx.core.policies.remove({
|
|
3724
3839
|
id: input.id,
|
|
@@ -5178,6 +5293,7 @@ var createExecutor = (config) => Effect8.gen(function* () {
|
|
|
5178
5293
|
const plugins = config.coreTools ? [
|
|
5179
5294
|
coreToolsPlugin({
|
|
5180
5295
|
webBaseUrl: config.coreTools.webBaseUrl,
|
|
5296
|
+
orgSlug: config.coreTools.orgSlug,
|
|
5181
5297
|
includeProviders: config.coreTools.includeProviders
|
|
5182
5298
|
}),
|
|
5183
5299
|
...userPlugins
|
|
@@ -6739,4 +6855,4 @@ export {
|
|
|
6739
6855
|
collectTables,
|
|
6740
6856
|
createExecutor
|
|
6741
6857
|
};
|
|
6742
|
-
//# sourceMappingURL=chunk-
|
|
6858
|
+
//# sourceMappingURL=chunk-UWBP7WLB.js.map
|