@zackbart/connecta 0.28.1 → 0.30.0
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/CHANGELOG.md +855 -5
- package/README.md +125 -116
- package/bin/connecta.mjs +121 -139
- package/bin/meta-tool-names.d.mts +2 -0
- package/bin/meta-tool-names.mjs +9 -0
- package/bin/version.mjs +3 -0
- package/dist/access-tokens.js +53 -63
- package/dist/activity-request.js +8 -0
- package/dist/activity.d.ts +76 -42
- package/dist/activity.js +110 -42
- package/dist/argument-redaction.js +230 -0
- package/dist/auth/clerk-sdk/client.d.ts +65 -0
- package/dist/auth/clerk-sdk/client.js +5 -0
- package/dist/auth/clerk-sdk/generated.js +1845 -0
- package/dist/auth/clerk-transport.js +19 -0
- package/dist/auth/clerk.d.ts +17 -7
- package/dist/auth/clerk.js +189 -107
- package/dist/auth/cloudflare-access.js +25 -26
- package/dist/auth/downstream-client-metadata.d.ts +29 -0
- package/dist/auth/downstream-client-metadata.js +133 -0
- package/dist/auth/downstream-oauth.js +1584 -1580
- package/dist/auth/downstream-revocation.js +106 -0
- package/dist/auth/oauth-token-response.js +231 -0
- package/dist/auth/oauth-v2-migration.js +116 -0
- package/dist/auth/static-oauth.js +93 -71
- package/dist/auth-elicitation.js +288 -0
- package/dist/authorization-handoff.js +111 -0
- package/dist/branding.d.ts +8 -16
- package/dist/branding.js +26 -59
- package/dist/byte-read-response.js +39 -0
- package/dist/call-admission.js +12 -16
- package/dist/catalog-cache.js +739 -0
- package/dist/catalog-drift.d.ts +50 -15
- package/dist/catalog-drift.js +365 -128
- package/dist/catalog-fingerprint.js +2 -4
- package/dist/catalog-freshness.js +13 -0
- package/dist/catalog-limits.js +2 -2
- package/dist/catalog-service.js +409 -225
- package/dist/catalog.js +43 -84
- package/dist/concurrency.js +3 -4
- package/dist/config-defaults.d.ts +39 -0
- package/dist/config-defaults.js +46 -0
- package/dist/config-schema.d.ts +181 -0
- package/dist/config-schema.js +435 -0
- package/dist/config-value-sources.js +102 -0
- package/dist/config.d.ts +633 -0
- package/dist/config.js +508 -0
- package/dist/connector-access.d.ts +1 -0
- package/dist/connector-access.js +13 -15
- package/dist/connector-caller.d.ts +8 -0
- package/dist/connector-caller.js +15 -6
- package/dist/connector-scope.js +1 -1
- package/dist/connectors/api-connector.d.ts +59 -7
- package/dist/connectors/api-connector.js +106 -19
- package/dist/connectors/api.js +4 -1
- package/dist/connectors/guarded-fetch.d.ts +144 -0
- package/dist/connectors/guarded-fetch.js +87 -38
- package/dist/connectors/negotiation-cache.js +46 -0
- package/dist/connectors/option-shapes.js +27 -0
- package/dist/connectors/remote-mcp.d.ts +30 -4
- package/dist/connectors/remote-mcp.js +1774 -320
- package/dist/connectors/resource-uri.js +335 -0
- package/dist/credential-contract.d.ts +10 -0
- package/dist/credential-rules.js +1 -3
- package/dist/credential-url.js +108 -0
- package/dist/credentials.d.ts +6 -1
- package/dist/credentials.js +27 -18
- package/dist/d1.d.ts +130 -0
- package/dist/d1.js +290 -0
- package/dist/describe-config.d.ts +165 -0
- package/dist/describe-config.js +315 -0
- package/dist/described.js +106 -0
- package/dist/downstream-input-context.js +128 -0
- package/dist/downstream-input.js +325 -0
- package/dist/errors.d.ts +132 -31
- package/dist/errors.js +175 -87
- package/dist/execute.js +798 -318
- package/dist/executor-admission.d.ts +1 -0
- package/dist/executor-admission.js +11 -15
- package/dist/executor-contract.d.ts +20 -0
- package/dist/executor-contract.js +48 -0
- package/dist/executor-result.js +30 -13
- package/dist/executors/quickjs-child.js +15 -9
- package/dist/executors/quickjs-protocol.js +5 -6
- package/dist/executors/quickjs-runtime.js +152 -59
- package/dist/executors/quickjs.js +49 -39
- package/dist/favicon.js +1 -2
- package/dist/fix-prompt.js +1 -3
- package/dist/guest-runtime.js +238 -0
- package/dist/guest-types.d.ts +218 -0
- package/dist/guest-types.js +1 -0
- package/dist/html-security.js +24 -0
- package/dist/identity.js +1 -3
- package/dist/inbound-credential.js +52 -0
- package/dist/index.d.ts +24 -256
- package/dist/index.js +65 -478
- package/dist/invocation-auth.js +69 -0
- package/dist/invocation.js +262 -79
- package/dist/json-schema.d.ts +1 -1
- package/dist/mcp-client-context.js +35 -0
- package/dist/mcp-result.js +11 -7
- package/dist/meta-output.js +61 -0
- package/dist/meta-tool-names.d.ts +2 -0
- package/dist/meta-tool-names.js +3 -0
- package/dist/meta-tools.js +419 -272
- package/dist/module-contracts.d.ts +8 -23
- package/dist/node.d.ts +0 -2
- package/dist/node.js +2 -2
- package/dist/oauth-callback-outcome.js +1 -3
- package/dist/oauth-handoff.js +194 -0
- package/dist/oauth-sealing.js +20 -0
- package/dist/operator-record.d.ts +137 -0
- package/dist/operator-record.js +420 -0
- package/dist/operator-ui/assets.js +31 -0
- package/dist/operator-ui/contract.d.ts +72 -0
- package/dist/operator-ui/contract.js +1 -0
- package/dist/operator-ui/fix-prompts.d.ts +18 -0
- package/dist/operator-ui/generated.js +5 -4
- package/dist/operator-ui/model.d.ts +12 -87
- package/dist/operator-ui/model.js +2 -9
- package/dist/operator-ui/setup-commands.js +1 -3
- package/dist/operator-ui/view.d.ts +323 -0
- package/dist/operator-ui/view.js +62 -189
- package/dist/page-styles.js +2 -3
- package/dist/program-result.js +5 -0
- package/dist/program-source.js +14 -2
- package/dist/{exempt-writes.js → program-writes.js} +60 -19
- package/dist/provider.d.ts +142 -0
- package/dist/provider.js +187 -0
- package/dist/providers/_shared/google/result-size.js +57 -0
- package/dist/providers/_shared/google/service-account.d.ts +58 -0
- package/dist/providers/_shared/google/service-account.js +500 -0
- package/dist/providers/_shared/google/workspace.d.ts +276 -0
- package/dist/providers/_shared/google/workspace.js +518 -0
- package/dist/providers/_shared/request-token.js +83 -0
- package/dist/providers/{basecamp.d.ts → basecamp/index.d.ts} +6 -28
- package/dist/providers/basecamp/index.js +997 -0
- package/dist/providers/basecamp/skill.generated.js +9 -0
- package/dist/providers/{breeze.d.ts → breeze/index.d.ts} +2 -2
- package/dist/providers/{breeze.js → breeze/index.js} +184 -140
- package/dist/providers/breeze/skill.generated.js +9 -0
- package/dist/providers/{ccb.d.ts → ccb/index.d.ts} +2 -2
- package/dist/providers/{ccb.js → ccb/index.js} +271 -116
- package/dist/providers/ccb/skill.generated.js +9 -0
- package/dist/providers/{cloudflare.d.ts → cloudflare/index.d.ts} +8 -7
- package/dist/providers/{cloudflare.js → cloudflare/index.js} +171 -738
- package/dist/providers/cloudflare/skill.generated.js +10 -0
- package/dist/providers/docs/index.d.ts +54 -0
- package/dist/providers/docs/index.js +1237 -0
- package/dist/providers/docs/skill.generated.js +9 -0
- package/dist/providers/drive/index.d.ts +53 -0
- package/dist/providers/drive/index.js +1523 -0
- package/dist/providers/drive/skill.generated.js +9 -0
- package/dist/providers/forms/index.d.ts +54 -0
- package/dist/providers/forms/index.js +1217 -0
- package/dist/providers/forms/skill.generated.js +11 -0
- package/dist/providers/github/auth.d.ts +32 -0
- package/dist/providers/github/auth.js +361 -0
- package/dist/providers/github/hosted.js +218 -0
- package/dist/providers/github/index.d.ts +13 -0
- package/dist/providers/github/index.js +140 -0
- package/dist/providers/github/key.js +100 -0
- package/dist/providers/github/rest.js +321 -0
- package/dist/providers/github/scope.d.ts +29 -0
- package/dist/providers/github/scope.js +124 -0
- package/dist/providers/github/skill.generated.js +8 -0
- package/dist/providers/gmail/index.d.ts +51 -0
- package/dist/providers/gmail/index.js +1436 -0
- package/dist/providers/gmail/skill.generated.js +9 -0
- package/dist/providers/infisical/index.d.ts +7 -0
- package/dist/providers/infisical/index.js +713 -0
- package/dist/providers/infisical/skill.generated.js +8 -0
- package/dist/providers/{linear.d.ts → linear/index.d.ts} +11 -14
- package/dist/providers/linear/index.js +352 -0
- package/dist/providers/linear/skill.generated.js +8 -0
- package/dist/providers/{mixpanel.d.ts → mixpanel/index.d.ts} +5 -10
- package/dist/providers/mixpanel/index.js +416 -0
- package/dist/providers/mixpanel/skill.generated.js +9 -0
- package/dist/providers/{notion.d.ts → notion/index.d.ts} +8 -8
- package/dist/providers/{notion.js → notion/index.js} +226 -239
- package/dist/providers/notion/skill.generated.js +10 -0
- package/dist/providers/{overflow.d.ts → overflow/index.d.ts} +2 -2
- package/dist/providers/{overflow.js → overflow/index.js} +74 -111
- package/dist/providers/overflow/skill.generated.js +8 -0
- package/dist/providers/{planning-center.d.ts → planning-center/index.d.ts} +2 -2
- package/dist/providers/{planning-center.js → planning-center/index.js} +264 -104
- package/dist/providers/planning-center/skill.generated.js +10 -0
- package/dist/providers/{revenuecat.d.ts → revenuecat/index.d.ts} +5 -10
- package/dist/providers/revenuecat/index.js +557 -0
- package/dist/providers/revenuecat/skill.generated.js +11 -0
- package/dist/providers/sheets/index.d.ts +54 -0
- package/dist/providers/sheets/index.js +1237 -0
- package/dist/providers/sheets/skill.generated.js +10 -0
- package/dist/providers/slides/index.d.ts +53 -0
- package/dist/providers/slides/index.js +2645 -0
- package/dist/providers/slides/skill.generated.js +9 -0
- package/dist/providers/{stripe.d.ts → stripe/index.d.ts} +5 -12
- package/dist/providers/stripe/index.js +266 -0
- package/dist/providers/stripe/skill.generated.js +11 -0
- package/dist/providers/{tithely.d.ts → tithely/index.d.ts} +2 -2
- package/dist/providers/{tithely.js → tithely/index.js} +60 -91
- package/dist/providers/tithely/skill.generated.js +8 -0
- package/dist/providers/{vercel.d.ts → vercel/index.d.ts} +8 -8
- package/dist/providers/vercel/index.js +1038 -0
- package/dist/providers/vercel/mcp-ownership.js +212 -0
- package/dist/providers/vercel/skill.generated.js +11 -0
- package/dist/registry.d.ts +110 -171
- package/dist/registry.js +588 -927
- package/dist/request-state.js +21 -0
- package/dist/resource-read.js +103 -0
- package/dist/result-shapes.js +17 -49
- package/dist/retired-toolkits.js +1 -1
- package/dist/routes/access-tokens.js +3 -6
- package/dist/routes/activity-context.js +21 -0
- package/dist/routes/activity-disclosure.js +40 -0
- package/dist/routes/activity.js +59 -21
- package/dist/routes/actor-labels.js +3 -50
- package/dist/routes/connect.js +221 -0
- package/dist/routes/credentials.js +15 -27
- package/dist/routes/mcp.js +365 -130
- package/dist/routes/oauth-client-metadata.js +15 -0
- package/dist/routes/oauth-management.js +45 -107
- package/dist/routes/oauth.js +110 -57
- package/dist/routes/operator.js +3 -3
- package/dist/routes/shared.d.ts +25 -64
- package/dist/routes/shared.js +160 -80
- package/dist/routes/skills.js +30 -0
- package/dist/routes/ui-config.js +225 -0
- package/dist/routes/ui-data.js +40 -35
- package/dist/routes/ui.js +66 -56
- package/dist/runtime/admission.js +4 -2
- package/dist/runtime/call-admission.js +3 -1
- package/dist/runtime/connector-scope.js +1 -4
- package/dist/runtime/run.js +10 -39
- package/dist/runtime/services.js +12 -117
- package/dist/runtime/shared-read.js +1 -3
- package/dist/runtime/storage.js +8 -1
- package/dist/sent-secrets.d.ts +93 -0
- package/dist/sent-secrets.js +1013 -0
- package/dist/server.js +28 -71
- package/dist/skills.js +416 -174
- package/dist/sqlite.d.ts +48 -0
- package/dist/sqlite.js +181 -0
- package/dist/storage/keys.js +443 -0
- package/dist/storage/memory.js +16 -4
- package/dist/storage/sql.d.ts +66 -0
- package/dist/storage/sql.js +543 -0
- package/dist/timeout.js +4 -2
- package/dist/tool-name.js +17 -0
- package/dist/tool-safety.d.ts +9 -35
- package/dist/tool-safety.js +20 -40
- package/dist/types.d.ts +336 -56
- package/dist/types.js +0 -1
- package/dist/ui.d.ts +7 -19
- package/dist/ui.js +76 -90
- package/dist/url-safety.js +3 -6
- package/dist/usage-guide.js +146 -0
- package/dist/validate.d.ts +7 -0
- package/dist/validate.js +309 -47
- package/dist/version.d.ts +1 -7
- package/dist/version.js +3 -7
- package/dist/worker.d.ts +11 -0
- package/dist/worker.js +435 -0
- package/documentation/README.md +63 -0
- package/documentation/architecture.md +696 -231
- package/documentation/auth.md +1069 -546
- package/documentation/code-mode.md +662 -356
- package/documentation/deploying.md +146 -0
- package/documentation/integrating.md +159 -0
- package/documentation/meta-tools.md +570 -216
- package/documentation/operating.md +135 -0
- package/documentation/operator-tests.md +97 -0
- package/documentation/operator-ui.md +132 -0
- package/documentation/provider-migration-0.29.md +65 -0
- package/examples/worker/AGENTS.md +34 -12
- package/examples/worker/README.md +293 -255
- package/examples/worker/kv-to-d1.wrangler.jsonc +26 -0
- package/examples/worker/scripts/copy-kv-to-d1.mjs +162 -0
- package/examples/worker/src/connecta.config.ts +151 -0
- package/examples/worker/src/index.ts +14 -197
- package/examples/worker/wrangler.jsonc +15 -35
- package/package.json +126 -54
- package/templates/node/.dockerignore +1 -2
- package/templates/node/.env.example +20 -21
- package/templates/node/AGENTS.md +21 -17
- package/templates/node/Dockerfile +3 -5
- package/templates/node/README.md +140 -58
- package/templates/node/docker-compose.yml +11 -12
- package/templates/node/package.json +4 -2
- package/templates/node/src/connecta.config.ts +119 -0
- package/templates/node/src/index.ts +9 -154
- package/templates/node/src/provision-token.ts +17 -0
- package/AGENTS.md +0 -170
- package/dist/artifacts/connector.d.ts +0 -58
- package/dist/artifacts/connector.js +0 -730
- package/dist/artifacts/document.js +0 -86
- package/dist/artifacts/guide.js +0 -140
- package/dist/artifacts/html-scan.js +0 -329
- package/dist/artifacts/json.js +0 -78
- package/dist/artifacts/kv-store.d.ts +0 -20
- package/dist/artifacts/kv-store.js +0 -140
- package/dist/artifacts/markdown.js +0 -478
- package/dist/artifacts/module.d.ts +0 -37
- package/dist/artifacts/module.js +0 -66
- package/dist/artifacts/operations.d.ts +0 -197
- package/dist/artifacts/operations.js +0 -1002
- package/dist/artifacts/refresh.d.ts +0 -55
- package/dist/artifacts/refresh.js +0 -236
- package/dist/artifacts/routes.js +0 -206
- package/dist/artifacts/types.d.ts +0 -214
- package/dist/artifacts/types.js +0 -22
- package/dist/artifacts/validate.d.ts +0 -62
- package/dist/artifacts/validate.js +0 -651
- package/dist/artifacts.d.ts +0 -6
- package/dist/artifacts.js +0 -9
- package/dist/auth/bearer.d.ts +0 -11
- package/dist/auth/bearer.js +0 -50
- package/dist/providers/basecamp.js +0 -445
- package/dist/providers/linear.js +0 -217
- package/dist/providers/mixpanel.js +0 -247
- package/dist/providers/revenuecat.js +0 -317
- package/dist/providers/stripe.js +0 -253
- package/dist/providers/vercel.js +0 -1253
- package/dist/storage/file.d.ts +0 -15
- package/dist/storage/file.js +0 -455
- package/ethos.md +0 -93
- package/examples/worker/src/cloudflare-kv.ts +0 -43
- package/examples/worker/src/d1-activity-row.ts +0 -155
- package/examples/worker/src/d1-activity.ts +0 -147
- package/examples/worker/src/d1-storage.ts +0 -138
- package/examples/worker/src/r2-artifact-blobs.ts +0 -29
- package/templates/node/src/file-activity.ts +0 -182
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { ConnectorCallError } from "../../errors.js";
|
|
2
|
+
const OWNER = /^[a-z0-9](?:[a-z0-9-]{0,37}[a-z0-9])?$/i;
|
|
3
|
+
const REPO = /^[a-z0-9_.-]{1,100}$/i;
|
|
4
|
+
export function target(owner, repo) {
|
|
5
|
+
if (typeof owner !== "string" ||
|
|
6
|
+
!OWNER.test(owner) ||
|
|
7
|
+
typeof repo !== "string" ||
|
|
8
|
+
!REPO.test(repo) ||
|
|
9
|
+
repo === "." ||
|
|
10
|
+
repo === "..") {
|
|
11
|
+
throw new ConnectorCallError("invalid_args", "Supply an explicit GitHub owner and repository name, without URLs or path separators.");
|
|
12
|
+
}
|
|
13
|
+
return { owner: owner.toLowerCase(), repo: repo.toLowerCase() };
|
|
14
|
+
}
|
|
15
|
+
export function parseScopes(input) {
|
|
16
|
+
if (!Array.isArray(input) || input.length === 0 || input.length > 100) {
|
|
17
|
+
throw new Error("scopes to contain between 1 and 100 org or repo entries with explicit access.");
|
|
18
|
+
}
|
|
19
|
+
const seen = new Set();
|
|
20
|
+
const scopes = input.map((scope) => {
|
|
21
|
+
if (!scope ||
|
|
22
|
+
(scope.org === undefined) === (scope.repo === undefined) ||
|
|
23
|
+
!["read", "read-write"].includes(scope.access) ||
|
|
24
|
+
(scope.workflows !== undefined && scope.workflows !== "write") ||
|
|
25
|
+
(scope.workflows === "write" && scope.access !== "read-write")) {
|
|
26
|
+
throw new Error("each scope to name either org or repo, explicit access, and workflows write only with read-write access.");
|
|
27
|
+
}
|
|
28
|
+
let normalized;
|
|
29
|
+
if (scope.org !== undefined) {
|
|
30
|
+
if (typeof scope.org !== "string" || !OWNER.test(scope.org))
|
|
31
|
+
throw new Error("scope org to be a GitHub organization login.");
|
|
32
|
+
normalized = {
|
|
33
|
+
org: scope.org.toLowerCase(),
|
|
34
|
+
access: scope.access,
|
|
35
|
+
...(scope.workflows ? { workflows: scope.workflows } : {}),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const parts = typeof scope.repo === "string" ? scope.repo.split("/") : [];
|
|
40
|
+
const parsed = target(parts[0], parts.length === 2 ? parts[1] : undefined);
|
|
41
|
+
normalized = {
|
|
42
|
+
repo: `${parsed.owner}/${parsed.repo}`,
|
|
43
|
+
access: scope.access,
|
|
44
|
+
...(scope.workflows ? { workflows: scope.workflows } : {}),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const key = normalized.org ?? normalized.repo;
|
|
48
|
+
if (seen.has(key))
|
|
49
|
+
throw new Error("scopes without duplicate org or repo entries.");
|
|
50
|
+
seen.add(key);
|
|
51
|
+
return Object.freeze(normalized);
|
|
52
|
+
});
|
|
53
|
+
for (const scope of scopes) {
|
|
54
|
+
if (!scope.repo)
|
|
55
|
+
continue;
|
|
56
|
+
const parent = scopes.find((candidate) => candidate.org === scope.repo.split("/")[0]);
|
|
57
|
+
if (parent &&
|
|
58
|
+
((parent.access === "read" && scope.access === "read-write") ||
|
|
59
|
+
(parent.workflows !== "write" && scope.workflows === "write"))) {
|
|
60
|
+
throw new Error("repo scopes to narrow their org grant rather than widen it.");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return Object.freeze(scopes);
|
|
64
|
+
}
|
|
65
|
+
export class ScopePolicy {
|
|
66
|
+
scopes;
|
|
67
|
+
aliases = new Map();
|
|
68
|
+
constructor(scopes) {
|
|
69
|
+
this.scopes = scopes;
|
|
70
|
+
}
|
|
71
|
+
scope(t, write = false, workflows = false) {
|
|
72
|
+
const grant = this.aliases.get(`${t.owner}/${t.repo}`) ??
|
|
73
|
+
this.scopes.find((scope) => scope.repo === `${t.owner}/${t.repo}`) ??
|
|
74
|
+
this.scopes.find((scope) => scope.org === t.owner);
|
|
75
|
+
if (!grant || (write && grant.access !== "read-write") || (workflows && grant.workflows !== "write")) {
|
|
76
|
+
throw new ConnectorCallError("invalid_args", `GitHub target or operation is outside configured scope. Allowed: ${this.summary()}. Workflow-file writes require workflows: "write" on the effective scope.`);
|
|
77
|
+
}
|
|
78
|
+
return grant;
|
|
79
|
+
}
|
|
80
|
+
bindAlias(t, grant) {
|
|
81
|
+
const name = `${t.owner}/${t.repo}`;
|
|
82
|
+
// Only authenticated installation metadata can introduce an alias. Keep
|
|
83
|
+
// the stricter grant when multiple configured names bind the same ID.
|
|
84
|
+
const previous = this.aliases.get(name);
|
|
85
|
+
if (!previous || grant.access === "read" || (previous.access === grant.access && grant.workflows !== "write")) {
|
|
86
|
+
if (this.aliases.size >= 256 && !this.aliases.has(name))
|
|
87
|
+
this.aliases.delete(this.aliases.keys().next().value);
|
|
88
|
+
this.aliases.set(name, grant);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
summary() {
|
|
92
|
+
return this.scopes
|
|
93
|
+
.map((scope) => `${scope.org ? `org ${scope.org}` : `repo ${scope.repo}`} (${scope.access}${scope.workflows ? ", workflows write" : ""})`)
|
|
94
|
+
.join(", ");
|
|
95
|
+
}
|
|
96
|
+
owner(owner) {
|
|
97
|
+
if (typeof owner !== "string" ||
|
|
98
|
+
!OWNER.test(owner) ||
|
|
99
|
+
!this.scopes.some((scope) => scope.org === owner.toLowerCase() || scope.repo?.split("/")[0] === owner.toLowerCase())) {
|
|
100
|
+
throw new ConnectorCallError("invalid_args", `Choose a configured owner. Allowed: ${this.summary()}.`);
|
|
101
|
+
}
|
|
102
|
+
return owner.toLowerCase();
|
|
103
|
+
}
|
|
104
|
+
repositories(owner) {
|
|
105
|
+
if (this.scopes.some((scope) => scope.org === owner))
|
|
106
|
+
return undefined;
|
|
107
|
+
return this.scopes
|
|
108
|
+
.filter((scope) => scope.repo?.split("/")[0] === owner)
|
|
109
|
+
.map((scope) => scope.repo.split("/")[1]);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/** Git paths are literal, canonical paths. Reject aliases before authentication. */
|
|
113
|
+
export function workflowPath(path) {
|
|
114
|
+
if (typeof path !== "string" ||
|
|
115
|
+
!path ||
|
|
116
|
+
path.startsWith("/") ||
|
|
117
|
+
/[\\%]/.test(path) ||
|
|
118
|
+
Array.from(path).some((char) => char.charCodeAt(0) < 32 || char.charCodeAt(0) === 127) ||
|
|
119
|
+
path.split("/").some((part) => !part || part === "." || part === "..")) {
|
|
120
|
+
throw new ConnectorCallError("invalid_args", "File paths must be canonical relative Git paths without escapes or dot segments.");
|
|
121
|
+
}
|
|
122
|
+
const normalized = path.toLowerCase();
|
|
123
|
+
return normalized === ".github" || normalized === ".github/workflows" || normalized.startsWith(".github/workflows/");
|
|
124
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Generated by scripts/generate-providers.mjs; do not edit.
|
|
2
|
+
export const skill = {
|
|
3
|
+
"content": "## Setup\n\nCreate a GitHub App, generate its RSA private key, and install it on every\nconfigured owner. Org grants require **All repositories**, including future\nrepositories. Exact repo grants work with selected-repository installations.\nRead-only grants request read permissions; read-write grants request only the\npermissions needed by each operation. The App needs repository Metadata,\nContents, Issues, Pull requests, Actions, Checks and Commit statuses for the\nreviewed read tools. Grant Contents, Issues, Pull requests and Actions write\nonly for the operations the deployment needs. Workflow-file edits also need\nthe App's Workflows write permission and `workflows: \"write\"` on the effective\nscope. Org grants authorize repository operations, not organization administration.\n\nPass `app: { appId, privateKey }` with the key from an environment secret, or\nomit privateKey and populate the connector's encrypted `privateKey` vault field.\nNever put private keys or installation tokens in agent instructions. Tokens\nstay in bounded runtime memory, refresh a minute before expiry, and are never\npersisted. Key rotation partitions the caches by the key's fingerprint.\nConfigured repository names bind to repository IDs on first use. Bindings last\nfor the provider instance; name lookups expire after five minutes. A rename\nkeeps its grant, while a replacement repository at the old name does not.\nReconfigure to authorize a replacement. Transfers leave the original\ninstallation and cannot use its tokens. Org grants bind to installation IDs.\n\n## Choose the target first\n\n`list_scopes({})` returns configured org/repo grants without network access.\n`list_scopes({ owner })` resolves that owner's installation and pages reachable\nrepositories. Carry its `next_page`. The connection context lists configured\nscopes and access. A repo entry overrides and may narrow its parent org entry.\nAn org grant covers current and future repositories, as long as the installation\nkeeps All repositories selected.\n\nEvery hosted call requires explicit `owner` and `repo`. Connecta checks scope\nand write access before reading the key or minting a token, and narrows each\nrepo call's token with `repository_ids` and the reviewed permissions.\nAn internal metadata-only installation token resolves names through GitHub's\ninstallation repository list; it never authenticates hosted calls or search.\nExpiry and misses refresh the name lookup without rebinding configured grants.\nUse discovery or the configured name to refresh a rename before using its new\nname; names that cannot map to a configured grant fail before operation tokens\nare minted. Cross-owner\nPR heads, cross-repository issue parents, opaque comment/review-thread IDs and\nsymlink writes are refused. The first release acts as the App; personal OAuth\nattribution is planned separately. Classification describes behavior; scope\nchecks authorize targets regardless of the pool's trust.\n\n## Tools and paging\n\nHosted schemas and results come from GitHub. Reviewed reads cover files,\ncommits, branches, tags, releases, issues, labels, PR details/diffs/reviews,\nand Actions workflows/runs/jobs. Reviewed writes cover issues, comments, PR\ncreation/updates/reviews, branches, file edits and Actions dispatch/rerun/cancel.\nCompound `issue_write` is always a write, including update/close. Review methods\nare limited to create/submit_pending/delete_pending; resolve/unresolve by opaque thread ID are\nnot exposed. Scope-changing tools, repo creation/forks, deletion/transfer,\nadministration, secrets and Copilot delegation are absent. Unknown upstream\ntools, arguments and methods require review before use.\n\nUse `search_scoped` for repositories, issues, PRs or code across installations.\nSupply literal words and an optional subset of configured org/repo selectors.\nScope qualifiers and Boolean operators are refused. Results have a partition\nID, next page, and an incomplete-results flag. Pass pages keyed by those exact\npartition IDs. Each call makes at most 20 partition requests; select fewer\nscopes when needed. Search pages stop at 10 and retain incompleteness. Returned\nrepositories are checked by ID against both deployment scopes and selected\npartitions. Issue and PR results resolve their repository URL to an ID before\nany result is returned.\nInstallation tokens do not override GitHub's own code-search access restrictions.\n\nREST complements own `create_release`, `update_release`, `delete_release` and\n`merge_pull_request`. Publishing a draft is `update_release({ draft: false })`.\nMerge requires an expected head SHA, a same-repository head/base and explicit\nworkflow-write access on the effective scope. GitHub atomically guards only the\nhead SHA, so a concurrent base retarget can introduce workflow changes despite\nan earlier file comparison. Merge is therefore disabled by default.\nRead current state before updates. A dispatched write is attempted once;\nGitHub errors never trigger an automatic write retry. Honor retry timing on\nrate limits; an ambiguous 404 may mean absence or an installation permission\ngap. Fix the App installation/key/permissions for auth errors; the App has no\ninteractive OAuth reconnect flow.\n",
|
|
4
|
+
"instructionsHeading": "Repository instructions",
|
|
5
|
+
"fragments": {
|
|
6
|
+
"guide": "## Setup\n\nCreate a GitHub App, generate its RSA private key, and install it on every\nconfigured owner. Org grants require **All repositories**, including future\nrepositories. Exact repo grants work with selected-repository installations.\nRead-only grants request read permissions; read-write grants request only the\npermissions needed by each operation. The App needs repository Metadata,\nContents, Issues, Pull requests, Actions, Checks and Commit statuses for the\nreviewed read tools. Grant Contents, Issues, Pull requests and Actions write\nonly for the operations the deployment needs. Workflow-file edits also need\nthe App's Workflows write permission and `workflows: \"write\"` on the effective\nscope. Org grants authorize repository operations, not organization administration.\n\nPass `app: { appId, privateKey }` with the key from an environment secret, or\nomit privateKey and populate the connector's encrypted `privateKey` vault field.\nNever put private keys or installation tokens in agent instructions. Tokens\nstay in bounded runtime memory, refresh a minute before expiry, and are never\npersisted. Key rotation partitions the caches by the key's fingerprint.\nConfigured repository names bind to repository IDs on first use. Bindings last\nfor the provider instance; name lookups expire after five minutes. A rename\nkeeps its grant, while a replacement repository at the old name does not.\nReconfigure to authorize a replacement. Transfers leave the original\ninstallation and cannot use its tokens. Org grants bind to installation IDs.\n\n## Choose the target first\n\n`list_scopes({})` returns configured org/repo grants without network access.\n`list_scopes({ owner })` resolves that owner's installation and pages reachable\nrepositories. Carry its `next_page`. The connection context lists configured\nscopes and access. A repo entry overrides and may narrow its parent org entry.\nAn org grant covers current and future repositories, as long as the installation\nkeeps All repositories selected.\n\nEvery hosted call requires explicit `owner` and `repo`. Connecta checks scope\nand write access before reading the key or minting a token, and narrows each\nrepo call's token with `repository_ids` and the reviewed permissions.\nAn internal metadata-only installation token resolves names through GitHub's\ninstallation repository list; it never authenticates hosted calls or search.\nExpiry and misses refresh the name lookup without rebinding configured grants.\nUse discovery or the configured name to refresh a rename before using its new\nname; names that cannot map to a configured grant fail before operation tokens\nare minted. Cross-owner\nPR heads, cross-repository issue parents, opaque comment/review-thread IDs and\nsymlink writes are refused. The first release acts as the App; personal OAuth\nattribution is planned separately. Classification describes behavior; scope\nchecks authorize targets regardless of the pool's trust.\n\n## Tools and paging\n\nHosted schemas and results come from GitHub. Reviewed reads cover files,\ncommits, branches, tags, releases, issues, labels, PR details/diffs/reviews,\nand Actions workflows/runs/jobs. Reviewed writes cover issues, comments, PR\ncreation/updates/reviews, branches, file edits and Actions dispatch/rerun/cancel.\nCompound `issue_write` is always a write, including update/close. Review methods\nare limited to create/submit_pending/delete_pending; resolve/unresolve by opaque thread ID are\nnot exposed. Scope-changing tools, repo creation/forks, deletion/transfer,\nadministration, secrets and Copilot delegation are absent. Unknown upstream\ntools, arguments and methods require review before use.\n\nUse `search_scoped` for repositories, issues, PRs or code across installations.\nSupply literal words and an optional subset of configured org/repo selectors.\nScope qualifiers and Boolean operators are refused. Results have a partition\nID, next page, and an incomplete-results flag. Pass pages keyed by those exact\npartition IDs. Each call makes at most 20 partition requests; select fewer\nscopes when needed. Search pages stop at 10 and retain incompleteness. Returned\nrepositories are checked by ID against both deployment scopes and selected\npartitions. Issue and PR results resolve their repository URL to an ID before\nany result is returned.\nInstallation tokens do not override GitHub's own code-search access restrictions.\n\nREST complements own `create_release`, `update_release`, `delete_release` and\n`merge_pull_request`. Publishing a draft is `update_release({ draft: false })`.\nMerge requires an expected head SHA, a same-repository head/base and explicit\nworkflow-write access on the effective scope. GitHub atomically guards only the\nhead SHA, so a concurrent base retarget can introduce workflow changes despite\nan earlier file comparison. Merge is therefore disabled by default.\nRead current state before updates. A dispatched write is attempted once;\nGitHub errors never trigger an automatic write retry. Honor retry timing on\nrate limits; an ambiguous 404 may mean absence or an installation permission\ngap. Fix the App installation/key/permissions for auth errors; the App has no\ninteractive OAuth reconnect flow.\n"
|
|
7
|
+
}
|
|
8
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type GoogleWorkspaceOptions } from "../_shared/google/workspace.js";
|
|
2
|
+
export type { GoogleServiceAccount, GoogleSubjectContext, GoogleWorkspaceOptions, GoogleWorkspaceSubject, } from "../_shared/google/workspace.js";
|
|
3
|
+
/**
|
|
4
|
+
* Gmail's API root, confined to the delegated user's own mailbox: `me` is the
|
|
5
|
+
* token's subject, and no path can climb out of it.
|
|
6
|
+
*/
|
|
7
|
+
export declare const GMAIL_API_BASE_URL = "https://gmail.googleapis.com/gmail/v1/users/me";
|
|
8
|
+
/**
|
|
9
|
+
* Exactly the scopes this connection requests, and exactly what the Admin
|
|
10
|
+
* console's domain-wide delegation entry must list (comma-separated there).
|
|
11
|
+
* `gmail.compose` technically permits sending; the tool surface does not.
|
|
12
|
+
*/
|
|
13
|
+
export declare const GMAIL_SCOPES: readonly ["https://www.googleapis.com/auth/gmail.readonly", "https://www.googleapis.com/auth/gmail.compose"];
|
|
14
|
+
/** Options for {@link gmail}: the shared Workspace delegation options. */
|
|
15
|
+
export type GmailOptions = GoogleWorkspaceOptions;
|
|
16
|
+
/**
|
|
17
|
+
* A maintained, draft-only Gmail connection acting as each signed-in
|
|
18
|
+
* Workspace user through a delegated service account.
|
|
19
|
+
*
|
|
20
|
+
* Setup, once per Workspace (shared with every Workspace provider):
|
|
21
|
+
*
|
|
22
|
+
* 1. In a Google Cloud project, enable the **Gmail API**.
|
|
23
|
+
* 2. Create a service account. Grant it no IAM roles: delegation, not project
|
|
24
|
+
* permission, is what reaches mailboxes.
|
|
25
|
+
* 3. Create a JSON key for it. If key creation is refused, the organization
|
|
26
|
+
* policy `iam.disableServiceAccountKeyCreation` is enforced; an org policy
|
|
27
|
+
* administrator can override it for this project alone.
|
|
28
|
+
* 4. Copy the service account's numeric **client ID** (the key's `client_id`).
|
|
29
|
+
* 5. As a Workspace super admin: Admin console → Security → Access and data
|
|
30
|
+
* control → API controls → Manage Domain Wide Delegation → Add new. Paste
|
|
31
|
+
* the client ID and exactly these scopes, comma-separated
|
|
32
|
+
* ({@link GMAIL_SCOPES}):
|
|
33
|
+
* `https://www.googleapis.com/auth/gmail.readonly,https://www.googleapis.com/auth/gmail.compose`.
|
|
34
|
+
* A new grant can take up to 24 hours to apply.
|
|
35
|
+
* 6. Configure inbound auth: a `subject` function is never asked about an
|
|
36
|
+
* open deployment's anonymous requests, which fail `auth_required`.
|
|
37
|
+
* Then give the deployment the key as a secret and map callers to mailboxes:
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* gmail("mail", {
|
|
41
|
+
* purpose: "Staff email triage and reply drafting",
|
|
42
|
+
* serviceAccount: env.GOOGLE_SERVICE_ACCOUNT_JSON,
|
|
43
|
+
* subject: (identity) => mailboxes[identity.principal?.id ?? ""],
|
|
44
|
+
* });
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* `gmail.compose` technically allows sending; this connection never does,
|
|
48
|
+
* because no tool reaches a send method. Drafts are additive writes the host
|
|
49
|
+
* approves through call_destructive_tool or a trusted program.
|
|
50
|
+
*/
|
|
51
|
+
export declare const gmail: import("../../provider.js").ProviderFactory<GoogleWorkspaceOptions>;
|