| 1 | import type { Provider } from "./integrations"; |
| 2 | |
| 3 | /** |
| 4 | * The connector catalog: every tool g1t connects to, or will, in one list. |
| 5 | * The workspace's Integrations page and your own Integrations settings are |
| 6 | * both drawn from it, so a new connector is added here, once. |
| 7 | * |
| 8 | * A connector is `available` when g1t can set it up today (its `href` is |
| 9 | * where), and `soon` while it is planned. `scopes` says who connects it: |
| 10 | * |
| 11 | * - `workspace`: an owner connects it once, for everyone in the workspace. |
| 12 | * - `personal`: each person connects their own account, and it follows them |
| 13 | * into every workspace they belong to (a calendar, a personal sign-in). |
| 14 | * |
| 15 | * A connector with both scopes can say something different for each, in |
| 16 | * `personal`: its own description, status, capabilities or setup page. |
| 17 | * `connectorView` resolves that into what one context shows. |
| 18 | * |
| 19 | * Paths in `href` are g1t's own pages. `:workspace` stands for the |
| 20 | * workspace's slug. |
| 21 | */ |
| 22 | |
| 23 | export type ConnectorScope = "workspace" | "personal"; |
| 24 | export type ConnectorStatus = "available" | "soon"; |
| 25 | |
| 26 | export type ConnectorCategory = |
| 27 | | "code" |
| 28 | | "issues" |
| 29 | | "chat" |
| 30 | | "calendar" |
| 31 | | "docs" |
| 32 | | "monitoring" |
| 33 | | "cloud" |
| 34 | | "ai" |
| 35 | | "data" |
| 36 | | "crm" |
| 37 | | "design" |
| 38 | | "security" |
| 39 | | "files"; |
| 40 | |
| 41 | /** What a connector lets g1t do, as the small tags on its card. */ |
| 42 | export type ConnectorCapability = |
| 43 | | "Agents can read" |
| 44 | | "Agents can act" |
| 45 | | "Opens issues" |
| 46 | | "Writes back" |
| 47 | | "Imports repositories" |
| 48 | | "Mirrors repositories" |
| 49 | | "Signs you in" |
| 50 | | "Sends events" |
| 51 | | "Alerts into chat" |
| 52 | | "Sets your status" |
| 53 | | "Finds a time" |
| 54 | | "Runs models" |
| 55 | | "Deploys" |
| 56 | | "Syncs people"; |
| 57 | |
| 58 | export type Connector = { |
| 59 | /** Stable and unique: used in links and requests. */ |
| 60 | id: string; |
| 61 | name: string; |
| 62 | category: ConnectorCategory; |
| 63 | /** One plain line of what it does in g1t, for a workspace (or for you, when it is only personal). */ |
| 64 | description: string; |
| 65 | scopes: ConnectorScope[]; |
| 66 | status: ConnectorStatus; |
| 67 | /** Where an available connector is set up, for each scope it has. */ |
| 68 | href?: Partial<Record<ConnectorScope, string>>; |
| 69 | capabilities?: ConnectorCapability[]; |
| 70 | /** The integration provider behind it, whose connections show it as connected. */ |
| 71 | provider?: Provider; |
| 72 | /** What differs when you connect it for yourself. */ |
| 73 | personal?: { description?: string; status?: ConnectorStatus; capabilities?: ConnectorCapability[] }; |
| 74 | /** More words search should find it by. */ |
| 75 | keywords?: string[]; |
| 76 | }; |
| 77 | |
| 78 | /** A connector as one context (a workspace, or you) shows it. */ |
| 79 | export type ConnectorView = { |
| 80 | id: string; |
| 81 | name: string; |
| 82 | category: ConnectorCategory; |
| 83 | description: string; |
| 84 | status: ConnectorStatus; |
| 85 | href: string | null; |
| 86 | capabilities: ConnectorCapability[]; |
| 87 | provider: Provider | null; |
| 88 | keywords: string[]; |
| 89 | /** The other scope it can also be connected in. */ |
| 90 | alsoIn: ConnectorScope | null; |
| 91 | }; |
| 92 | |
| 93 | /** The categories, in the order the directory lists them. */ |
| 94 | export const CONNECTOR_CATEGORIES: { id: ConnectorCategory; title: string }[] = [ |
| 95 | { id: "code", title: "Code & CI" }, |
| 96 | { id: "issues", title: "Issues & projects" }, |
| 97 | { id: "chat", title: "Chat & meetings" }, |
| 98 | { id: "calendar", title: "Calendar & email" }, |
| 99 | { id: "docs", title: "Docs & knowledge" }, |
| 100 | { id: "monitoring", title: "Monitoring & incidents" }, |
| 101 | { id: "cloud", title: "Cloud & deploy" }, |
| 102 | { id: "ai", title: "AI models" }, |
| 103 | { id: "data", title: "Data & analytics" }, |
| 104 | { id: "crm", title: "CRM & support" }, |
| 105 | { id: "design", title: "Design" }, |
| 106 | { id: "security", title: "Security & identity" }, |
| 107 | { id: "files", title: "Files & storage" }, |
| 108 | ]; |
| 109 | |
| 110 | const W: ConnectorScope[] = ["workspace"]; |
| 111 | const P: ConnectorScope[] = ["personal"]; |
| 112 | const BOTH: ConnectorScope[] = ["workspace", "personal"]; |
| 113 | |
| 114 | /** A model provider: set up on the workspace's model providers page. */ |
| 115 | function model(provider: Provider, name: string, description: string, keywords: string[] = []): Connector { |
| 116 | return { |
| 117 | id: provider.replace(/_/g, "-"), |
| 118 | name, |
| 119 | category: "ai", |
| 120 | description, |
| 121 | scopes: W, |
| 122 | status: "available", |
| 123 | href: { workspace: `/:workspace/-/integrations/models?add=${provider}#add` }, |
| 124 | capabilities: ["Runs models"], |
| 125 | provider, |
| 126 | keywords: ["model", "llm", ...keywords], |
| 127 | }; |
| 128 | } |
| 129 | |
| 130 | /** A planned connector. */ |
| 131 | function soon( |
| 132 | id: string, |
| 133 | name: string, |
| 134 | category: ConnectorCategory, |
| 135 | scopes: ConnectorScope[], |
| 136 | description: string, |
| 137 | capabilities: ConnectorCapability[] = [], |
| 138 | personal?: Connector["personal"], |
| 139 | ): Connector { |
| 140 | return { id, name, category, description, scopes, status: "soon", capabilities, ...(personal ? { personal } : {}) }; |
| 141 | } |
| 142 | |
| 143 | export const CONNECTORS: Connector[] = [ |
| 144 | // Code & CI ------------------------------------------------------------- |
| 145 | { |
| 146 | id: "github", |
| 147 | name: "GitHub", |
| 148 | category: "code", |
| 149 | description: "Import repositories, or mirror them both ways while your team moves over.", |
| 150 | scopes: BOTH, |
| 151 | status: "available", |
| 152 | href: { workspace: "/new/github?workspace=:workspace", personal: "/settings/github" }, |
| 153 | capabilities: ["Imports repositories", "Mirrors repositories"], |
| 154 | personal: { |
| 155 | description: "Sign in with your GitHub account, and reach the repositories you can see there to import them.", |
| 156 | capabilities: ["Signs you in", "Imports repositories"], |
| 157 | }, |
| 158 | keywords: ["git", "import", "mirror", "sign in"], |
| 159 | }, |
| 160 | { |
| 161 | id: "webhooks", |
| 162 | name: "Webhooks", |
| 163 | category: "code", |
| 164 | description: "Every repository's events, sent to your own addresses as they happen, signed.", |
| 165 | scopes: W, |
| 166 | status: "available", |
| 167 | href: { workspace: "/:workspace/-/webhooks" }, |
| 168 | capabilities: ["Sends events"], |
| 169 | keywords: ["http", "events", "outgoing"], |
| 170 | }, |
| 171 | soon("gitlab", "GitLab", "code", BOTH, "Import projects and keep them mirrored, merge requests included.", ["Imports repositories", "Mirrors repositories"], { |
| 172 | description: "Sign in with GitLab, and reach your own projects to import them.", |
| 173 | capabilities: ["Signs you in", "Imports repositories"], |
| 174 | }), |
| 175 | soon("bitbucket", "Bitbucket", "code", BOTH, "Import repositories and keep them mirrored while you move.", ["Imports repositories", "Mirrors repositories"], { |
| 176 | description: "Reach your own Bitbucket repositories to import them.", |
| 177 | capabilities: ["Imports repositories"], |
| 178 | }), |
| 179 | soon("circleci", "CircleCI", "code", W, "Pipeline results as checks on pull requests, which agents read when a build fails.", ["Agents can read"]), |
| 180 | soon("buildkite", "Buildkite", "code", W, "Build results as checks on pull requests, with the failing step for agents to fix.", ["Agents can read"]), |
| 181 | soon("docker-hub", "Docker Hub", "code", W, "Push images your workflows build, and pull private base images.", ["Deploys"]), |
| 182 | |
| 183 | // Issues & projects ----------------------------------------------------- |
| 184 | { |
| 185 | id: "linear", |
| 186 | name: "Linear", |
| 187 | category: "issues", |
| 188 | description: "Agents read ENG-42 when work mentions it; import issues, and they hear back when the work lands.", |
| 189 | scopes: BOTH, |
| 190 | status: "available", |
| 191 | href: { workspace: "/:workspace/-/integrations/trackers?add=linear#add" }, |
| 192 | capabilities: ["Agents can read", "Writes back"], |
| 193 | provider: "linear", |
| 194 | personal: { |
| 195 | description: "Issues assigned to you in Linear, in your g1t inbox beside everything else.", |
| 196 | status: "soon", |
| 197 | capabilities: ["Agents can read"], |
| 198 | }, |
| 199 | keywords: ["tracker", "tickets"], |
| 200 | }, |
| 201 | { |
| 202 | id: "jira", |
| 203 | name: "Jira", |
| 204 | category: "issues", |
| 205 | description: "Agents read TECH-1234 when work mentions it; import tickets, and they hear back when the work lands.", |
| 206 | scopes: W, |
| 207 | status: "available", |
| 208 | href: { workspace: "/:workspace/-/integrations/trackers?add=jira#add" }, |
| 209 | capabilities: ["Agents can read", "Writes back"], |
| 210 | provider: "jira", |
| 211 | keywords: ["atlassian", "tracker", "tickets"], |
| 212 | }, |
| 213 | soon("asana", "Asana", "issues", BOTH, "Tasks agents can read, import as issues, and close when the work merges.", ["Agents can read", "Writes back"], { |
| 214 | description: "Tasks assigned to you in Asana, in your g1t inbox.", |
| 215 | capabilities: ["Agents can read"], |
| 216 | }), |
| 217 | soon("shortcut", "Shortcut", "issues", W, "Stories agents read when work mentions them, updated when the work lands.", ["Agents can read", "Writes back"]), |
| 218 | soon("clickup", "ClickUp", "issues", W, "Tasks agents can read and import, kept in step with their pull requests.", ["Agents can read", "Writes back"]), |
| 219 | soon("trello", "Trello", "issues", W, "Cards become issues, and move along their board as the work does.", ["Opens issues", "Writes back"]), |
| 220 | |
| 221 | // Chat & meetings ------------------------------------------------------- |
| 222 | soon("slack", "Slack", "chat", BOTH, "Alerts and agent updates in the channels your team already reads, and agents to talk to there.", ["Alerts into chat", "Agents can act"], { |
| 223 | description: "Your status in g1t follows the one you set in Slack, and the other way round.", |
| 224 | capabilities: ["Sets your status"], |
| 225 | }), |
| 226 | soon("microsoft-teams", "Microsoft Teams", "chat", BOTH, "Alerts and agent updates posted to Teams channels, with agents to talk to there.", ["Alerts into chat", "Agents can act"], { |
| 227 | description: "Your status in g1t follows your Teams presence.", |
| 228 | capabilities: ["Sets your status"], |
| 229 | }), |
| 230 | soon("discord", "Discord", "chat", W, "Releases, alerts and agent updates posted to a Discord server.", ["Alerts into chat"]), |
| 231 | soon("zoom", "Zoom", "chat", BOTH, "Meeting notes and recordings agents can read when work refers to them.", ["Agents can read"], { |
| 232 | description: "Sets your status to On a call while you are in a Zoom meeting.", |
| 233 | capabilities: ["Sets your status"], |
| 234 | }), |
| 235 | soon("google-meet", "Google Meet", "chat", P, "Sets your status to On a call while you are in a meeting, and starts a call from any channel.", ["Sets your status"]), |
| 236 | |
| 237 | // Calendar & email ------------------------------------------------------ |
| 238 | soon("google-calendar", "Google Calendar", "calendar", P, "Sets your status to In a meeting while you are in one; agents can find a time that suits everyone.", ["Sets your status", "Finds a time"]), |
| 239 | soon("outlook-calendar", "Outlook Calendar", "calendar", P, "Sets your status to In a meeting while you are in one; agents can find a time that suits everyone.", ["Sets your status", "Finds a time"]), |
| 240 | soon("gmail", "Gmail", "calendar", P, "Forward a thread to an agent, or turn an email into an issue, from your own inbox.", ["Opens issues", "Agents can read"]), |
| 241 | soon("outlook-mail", "Outlook Mail", "calendar", P, "Forward a thread to an agent, or turn an email into an issue, from your own inbox.", ["Opens issues", "Agents can read"]), |
| 242 | |
| 243 | // Docs & knowledge ------------------------------------------------------ |
| 244 | soon("notion", "Notion", "docs", BOTH, "Import pages into Docs, and let agents read the ones work refers to.", ["Agents can read"], { |
| 245 | description: "Reach your own Notion pages, to bring them into Docs.", |
| 246 | capabilities: ["Agents can read"], |
| 247 | }), |
| 248 | soon("confluence", "Confluence", "docs", W, "Import spaces into Docs, and let agents read pages work refers to.", ["Agents can read"]), |
| 249 | soon("google-docs", "Google Docs", "docs", BOTH, "Agents read the specs and plans linked from issues and chat.", ["Agents can read"], { |
| 250 | description: "Docs you share in chat open for agents as well as people.", |
| 251 | capabilities: ["Agents can read"], |
| 252 | }), |
| 253 | soon("coda", "Coda", "docs", W, "Agents read the docs and tables linked from issues and chat.", ["Agents can read"]), |
| 254 | |
| 255 | // Monitoring & incidents ------------------------------------------------ |
| 256 | { |
| 257 | id: "sentry", |
| 258 | name: "Sentry", |
| 259 | category: "monitoring", |
| 260 | description: "New errors open issues with the stack trace, and resolve in Sentry when the fix merges.", |
| 261 | scopes: W, |
| 262 | status: "available", |
| 263 | href: { workspace: "/:workspace/-/integrations/alerts?add=sentry#add" }, |
| 264 | capabilities: ["Opens issues", "Agents can read", "Writes back"], |
| 265 | provider: "sentry", |
| 266 | keywords: ["errors", "alerts", "exceptions"], |
| 267 | }, |
| 268 | { |
| 269 | id: "datadog", |
| 270 | name: "Datadog", |
| 271 | category: "monitoring", |
| 272 | description: "Monitors that trigger open issues, and recoveries are noted on them.", |
| 273 | scopes: W, |
| 274 | status: "available", |
| 275 | href: { workspace: "/:workspace/-/integrations/alerts?add=datadog#add" }, |
| 276 | capabilities: ["Opens issues"], |
| 277 | provider: "datadog", |
| 278 | keywords: ["monitors", "alerts", "apm"], |
| 279 | }, |
| 280 | { |
| 281 | id: "alerts-webhook", |
| 282 | name: "Alerts webhook", |
| 283 | category: "monitoring", |
| 284 | description: "Anything that can send signed JSON opens issues: your own scripts, or any monitoring tool.", |
| 285 | scopes: W, |
| 286 | status: "available", |
| 287 | href: { workspace: "/:workspace/-/integrations/alerts?add=webhook#add" }, |
| 288 | capabilities: ["Opens issues"], |
| 289 | provider: "webhook", |
| 290 | keywords: ["incoming", "http", "alerts", "pagerduty", "grafana"], |
| 291 | }, |
| 292 | soon("pagerduty", "PagerDuty", "monitoring", BOTH, "Incidents open issues an agent can start on, and resolve when the fix lands.", ["Opens issues", "Writes back"], { |
| 293 | description: "Sets your status to On call while you are on call.", |
| 294 | capabilities: ["Sets your status"], |
| 295 | }), |
| 296 | soon("opsgenie", "Opsgenie", "monitoring", W, "Alerts open issues, and close when the fix lands.", ["Opens issues", "Writes back"]), |
| 297 | soon("incident-io", "incident.io", "monitoring", W, "Incidents get a channel in g1t, with agents to dig through what changed.", ["Opens issues", "Alerts into chat"]), |
| 298 | soon("grafana", "Grafana", "monitoring", W, "Alert rules open issues, and agents read the dashboards they link to.", ["Opens issues", "Agents can read"]), |
| 299 | soon("new-relic", "New Relic", "monitoring", W, "Alerts open issues, with the traces agents need to find the cause.", ["Opens issues", "Agents can read"]), |
| 300 | soon("honeycomb", "Honeycomb", "monitoring", W, "Triggers open issues, and agents query traces while they work.", ["Opens issues", "Agents can read"]), |
| 301 | soon("better-stack", "Better Stack", "monitoring", W, "Uptime incidents and log alerts open issues.", ["Opens issues"]), |
| 302 | |
| 303 | // Cloud & deploy -------------------------------------------------------- |
| 304 | soon("cloudflare", "Cloudflare", "cloud", W, "Deploy projects to your own Cloudflare account, and manage their domains.", ["Deploys"]), |
| 305 | soon("aws", "Amazon Web Services", "cloud", W, "Workflows and deployments reach AWS with short-lived credentials, no stored keys.", ["Deploys"]), |
| 306 | soon("google-cloud", "Google Cloud", "cloud", W, "Workflows and deployments reach Google Cloud with short-lived credentials.", ["Deploys"]), |
| 307 | soon("azure", "Microsoft Azure", "cloud", W, "Workflows and deployments reach Azure with short-lived credentials.", ["Deploys"]), |
| 308 | soon("vercel", "Vercel", "cloud", W, "Preview and production deployments as checks on pull requests.", ["Deploys", "Agents can read"]), |
| 309 | soon("netlify", "Netlify", "cloud", W, "Deploy previews as checks on pull requests.", ["Deploys", "Agents can read"]), |
| 310 | soon("fly-io", "Fly.io", "cloud", W, "Deploy apps from workflows, and roll back from the deployment's page.", ["Deploys"]), |
| 311 | soon("kubernetes", "Kubernetes", "cloud", W, "Roll out to your own clusters from workflows, with each rollout's status on g1t.", ["Deploys"]), |
| 312 | |
| 313 | // AI models ------------------------------------------------------------- |
| 314 | model("anthropic", "Anthropic", "Claude models on your own Anthropic account, billed there.", ["claude"]), |
| 315 | model("openai", "OpenAI", "GPT models on your own OpenAI account, billed there.", ["gpt"]), |
| 316 | model("gemini", "Google Gemini", "Gemini models on your own Google AI account, billed there.", ["google"]), |
| 317 | model("xai", "xAI", "Grok models on your own xAI account, billed there.", ["grok"]), |
| 318 | model("mistral", "Mistral", "Mistral models on your own account, billed there."), |
| 319 | model("deepseek", "DeepSeek", "DeepSeek models on your own account, billed there."), |
| 320 | model("azure_openai", "Azure OpenAI", "Your Azure OpenAI deployments, in your own subscription.", ["microsoft"]), |
| 321 | model("openrouter", "OpenRouter", "Many labs' models through one OpenRouter key."), |
| 322 | model("groq", "Groq", "Fast open models on your own Groq account."), |
| 323 | model("together", "Together AI", "Open models on your own Together AI account."), |
| 324 | model("fireworks", "Fireworks AI", "Open models on your own Fireworks AI account."), |
| 325 | model("cerebras", "Cerebras", "Fast open models on your own Cerebras account."), |
| 326 | model("anthropic_endpoint", "Anthropic-compatible endpoint", "Any server that speaks the Anthropic API, such as your own gateway.", ["self-hosted", "proxy"]), |
| 327 | model("openai_endpoint", "OpenAI-compatible endpoint", "Any server that speaks the OpenAI API, such as a model you host yourself.", ["self-hosted", "proxy", "ollama", "vllm"]), |
| 328 | { |
| 329 | id: "ai-gateway", |
| 330 | name: "AI Gateway", |
| 331 | category: "ai", |
| 332 | description: "Your own code's model requests through g1t, with the workspace's access tokens, logged and costed.", |
| 333 | scopes: W, |
| 334 | status: "available", |
| 335 | href: { workspace: "/:workspace/-/gateway" }, |
| 336 | capabilities: ["Runs models"], |
| 337 | keywords: ["proxy", "api", "tokens"], |
| 338 | }, |
| 339 | { |
| 340 | id: "mcp", |
| 341 | name: "MCP clients", |
| 342 | category: "ai", |
| 343 | description: "Your own agent, connected to g1t's MCP server, works in g1t as you.", |
| 344 | scopes: P, |
| 345 | status: "available", |
| 346 | href: { personal: "/settings/applications" }, |
| 347 | capabilities: ["Agents can act"], |
| 348 | keywords: ["model context protocol", "agent", "applications", "oauth"], |
| 349 | }, |
| 350 | soon("amazon-bedrock", "Amazon Bedrock", "ai", W, "Models in your own AWS account, billed there.", ["Runs models"]), |
| 351 | soon("vertex-ai", "Google Vertex AI", "ai", W, "Models in your own Google Cloud project, billed there.", ["Runs models"]), |
| 352 | soon("hugging-face", "Hugging Face", "ai", W, "Inference endpoints you run on Hugging Face, for any kind of work.", ["Runs models"]), |
| 353 | |
| 354 | // Data & analytics ------------------------------------------------------ |
| 355 | soon("postgresql", "PostgreSQL", "data", W, "Agents read your schema, and run read-only queries while they investigate.", ["Agents can read"]), |
| 356 | soon("snowflake", "Snowflake", "data", W, "Agents answer questions from your warehouse with read-only queries.", ["Agents can read"]), |
| 357 | soon("bigquery", "BigQuery", "data", W, "Agents answer questions from your datasets with read-only queries.", ["Agents can read"]), |
| 358 | soon("posthog", "PostHog", "data", W, "Agents read product analytics and feature flags while they plan a change.", ["Agents can read"]), |
| 359 | soon("amplitude", "Amplitude", "data", W, "Agents read the charts that work refers to.", ["Agents can read"]), |
| 360 | soon("segment", "Segment", "data", W, "Agents read your tracking plan, and check new events against it.", ["Agents can read"]), |
| 361 | |
| 362 | // CRM & support --------------------------------------------------------- |
| 363 | soon("zendesk", "Zendesk", "crm", W, "Turn a ticket into an issue, and tell the customer when the fix ships.", ["Opens issues", "Writes back"]), |
| 364 | soon("intercom", "Intercom", "crm", W, "Conversations become issues, and hear back when the fix ships.", ["Opens issues", "Writes back"]), |
| 365 | soon("hubspot", "HubSpot", "crm", W, "Agents read the account behind a request when work mentions it.", ["Agents can read"]), |
| 366 | soon("salesforce", "Salesforce", "crm", W, "Agents read the account and case behind a request.", ["Agents can read"]), |
| 367 | soon("stripe", "Stripe", "crm", W, "Agents read customers and payments while they work on billing.", ["Agents can read"]), |
| 368 | |
| 369 | // Design ---------------------------------------------------------------- |
| 370 | soon("figma", "Figma", "design", BOTH, "Agents read the frames linked from an issue, and build to them.", ["Agents can read"], { |
| 371 | description: "Reach your own Figma files, to link and preview them in chat and issues.", |
| 372 | capabilities: ["Agents can read"], |
| 373 | }), |
| 374 | soon("miro", "Miro", "design", W, "Agents read the boards linked from issues and chat.", ["Agents can read"]), |
| 375 | soon("storybook", "Storybook", "design", W, "Each pull request's stories as a check, with what changed.", ["Agents can read"]), |
| 376 | |
| 377 | // Security & identity --------------------------------------------------- |
| 378 | soon("okta", "Okta", "security", W, "Single sign-on, and people added and removed with your directory.", ["Signs you in", "Syncs people"]), |
| 379 | soon("entra-id", "Microsoft Entra ID", "security", W, "Single sign-on, and people added and removed with your directory.", ["Signs you in", "Syncs people"]), |
| 380 | soon("google-workspace", "Google Workspace", "security", BOTH, "Single sign-on, and people added and removed with your directory.", ["Signs you in", "Syncs people"], { |
| 381 | description: "Sign in to g1t with your Google account.", |
| 382 | capabilities: ["Signs you in"], |
| 383 | }), |
| 384 | soon("1password", "1Password", "security", W, "Secrets from a vault, read by workflows and deployments when they run.", ["Deploys"]), |
| 385 | soon("snyk", "Snyk", "security", W, "Findings open issues, and an agent opens the fix.", ["Opens issues"]), |
| 386 | |
| 387 | // Files & storage ------------------------------------------------------- |
| 388 | soon("google-drive", "Google Drive", "files", BOTH, "Agents read the files linked from issues and chat.", ["Agents can read"], { |
| 389 | description: "Attach files from your Drive in chat, without downloading them first.", |
| 390 | capabilities: ["Agents can read"], |
| 391 | }), |
| 392 | soon("dropbox", "Dropbox", "files", BOTH, "Agents read the files linked from issues and chat.", ["Agents can read"], { |
| 393 | description: "Attach files from your Dropbox in chat.", |
| 394 | capabilities: ["Agents can read"], |
| 395 | }), |
| 396 | soon("onedrive", "OneDrive and SharePoint", "files", BOTH, "Agents read the files linked from issues and chat.", ["Agents can read"], { |
| 397 | description: "Attach files from your OneDrive in chat.", |
| 398 | capabilities: ["Agents can read"], |
| 399 | }), |
| 400 | soon("box", "Box", "files", W, "Agents read the files linked from issues and chat.", ["Agents can read"]), |
| 401 | ]; |
| 402 | |
| 403 | /** The connector by its id. */ |
| 404 | export function connectorById(id: string): Connector | undefined { |
| 405 | return CONNECTORS.find((connector) => connector.id === id); |
| 406 | } |
| 407 | |
| 408 | /** A connector as `scope` shows it, or null when it cannot be connected there. */ |
| 409 | export function connectorView(connector: Connector, scope: ConnectorScope): ConnectorView | null { |
| 410 | if (!connector.scopes.includes(scope)) return null; |
| 411 | const own = scope === "personal" ? connector.personal : undefined; |
| 412 | const status = own?.status ?? connector.status; |
| 413 | const other: ConnectorScope = scope === "workspace" ? "personal" : "workspace"; |
| 414 | return { |
| 415 | id: connector.id, |
| 416 | name: connector.name, |
| 417 | category: connector.category, |
| 418 | description: own?.description ?? connector.description, |
| 419 | status, |
| 420 | href: status === "available" ? (connector.href?.[scope] ?? null) : null, |
| 421 | capabilities: own?.capabilities ?? connector.capabilities ?? [], |
| 422 | provider: connector.provider ?? null, |
| 423 | keywords: connector.keywords ?? [], |
| 424 | alsoIn: connector.scopes.includes(other) ? other : null, |
| 425 | }; |
| 426 | } |
| 427 | |
| 428 | /** Every connector `scope` can show, in catalog order. */ |
| 429 | export function connectorsFor(scope: ConnectorScope): ConnectorView[] { |
| 430 | return CONNECTORS.map((connector) => connectorView(connector, scope)).filter((view): view is ConnectorView => view != null); |
| 431 | } |
| 432 | |
| 433 | /** A setup path with its `:workspace` filled in. */ |
| 434 | export function connectorPath(path: string, workspace: string): string { |
| 435 | return path.replace(/:workspace\b/g, encodeURIComponent(workspace)); |
| 436 | } |