Repository navigation
Rename saved OAuth connectors to integrations - #391
Conversation
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
📝 WalkthroughWalkthroughThis PR systematically refactors "connector" terminology to "integration" terminology throughout the codebase. It updates documentation guides, replaces connector-specific type definitions and handlers with integration-equivalents, migrates MCP capabilities from ChangesConnector-to-Integration Terminology Refactoring
Sequence Diagram(s)sequenceDiagram
participant Client
participant ExecuteSandbox
participant Codemode as "codemode.integration_get"
participant Refresh as "refreshAccessToken"
participant Fetch as "createAuthenticatedFetch"
participant Allow as "assertIntegrationHostAllowed"
Client->>ExecuteSandbox: run package requiring OAuth request
ExecuteSandbox->>Codemode: integration_get(name)
Codemode-->>ExecuteSandbox: IntegrationConfig
ExecuteSandbox->>Refresh: refreshAccessToken(integration)
Refresh-->>ExecuteSandbox: access_token
ExecuteSandbox->>Fetch: createAuthenticatedFetch(url)
Fetch->>Allow: assertIntegrationHostAllowed(integration, url)
Allow-->>Fetch: allowed / IntegrationHostNotAllowedError
Fetch-->>ExecuteSandbox: network request with Bearer token
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
|
🔎 Preview deployed: https://kody-pr-391.kentcdodds.workers.dev Worker: Mocks:
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/worker/src/mcp/capabilities/values/integration-save.ts (1)
64-78:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
integrationConfigSchema.parse()will throw an unhandledZodErrorwhen required fields are absent for new integrations.
integrationSaveSchema(the capability's input schema) markstokenUrl,flow,clientIdValueName, andaccessTokenSecretNameas.optional(). When an agent callsintegration_savefor the first time (no pre-existing record) and omits any of those fields, theintegrationConfigSchema.parse(...)on line 67 throws aZodErrorwith no catch in scope. The MCP framework would receive this as an unexpected exception rather than a structured capability error.Switching to
safeParseallows returning a clear error:🐛 Proposed fix
- const integration = existingIntegration - ? mergeIntegrationConfig(existingIntegration, args) - : normalizeIntegrationConfig( - integrationConfigSchema.parse({ - name: args.name, - tokenUrl: args.tokenUrl, - apiBaseUrl: args.apiBaseUrl ?? null, - flow: args.flow, - clientIdValueName: args.clientIdValueName, - clientSecretSecretName: args.clientSecretSecretName ?? null, - accessTokenSecretName: args.accessTokenSecretName, - refreshTokenSecretName: args.refreshTokenSecretName ?? null, - requiredHosts: args.requiredHosts, - }), - ) + let integration: ReturnType<typeof normalizeIntegrationConfig> + if (existingIntegration) { + integration = mergeIntegrationConfig(existingIntegration, args) + } else { + const newResult = integrationConfigSchema.safeParse({ + name: args.name, + tokenUrl: args.tokenUrl, + apiBaseUrl: args.apiBaseUrl ?? null, + flow: args.flow, + clientIdValueName: args.clientIdValueName, + clientSecretSecretName: args.clientSecretSecretName ?? null, + accessTokenSecretName: args.accessTokenSecretName, + refreshTokenSecretName: args.refreshTokenSecretName ?? null, + requiredHosts: args.requiredHosts, + }) + if (!newResult.success) { + throw new Error( + `Cannot create integration "${args.name}": missing required fields — ${newResult.error.issues.map((i) => i.path.join('.') + ': ' + i.message).join(', ')}`, + ) + } + integration = normalizeIntegrationConfig(newResult.data) + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/worker/src/mcp/capabilities/values/integration-save.ts` around lines 64 - 78, The code calls integrationConfigSchema.parse(...) when building the new integration which will throw an uncaught ZodError for missing optional fields; change this to use integrationConfigSchema.safeParse(...) and, when safeParse returns { success: false }, convert the validation errors into the capability's structured error response (instead of letting the exception bubble) so new integrations without required fields produce a clear, handled error; update the block that sets integration (the ternary using existingIntegration, mergeIntegrationConfig, and normalizeIntegrationConfig) to perform the safeParse check before calling normalizeIntegrationConfig and handle the failure path consistently with other MCP capability errors.
🧹 Nitpick comments (1)
packages/worker/src/mcp/capabilities/values/integration-save.node.test.ts (1)
119-168: ⚡ Quick winTest suite only covers the upsert (existing record) path — new-creation path is unexercised.
All three tests merge into an existing
_integration:spotifyentry. There are no tests for:
- Creating a brand-new integration (no pre-existing stored value) with all required fields.
- Attempting to create a new integration with missing required fields (exposes the
ZodErrorbug in the handler).Adding these two cases would catch the issue identified in
integration-save.tsand guard the new-creation path going forward.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/worker/src/mcp/capabilities/values/integration-save.node.test.ts` around lines 119 - 168, Add two tests for the "new-creation" path of integrationSaveCapability: one that calls integrationSaveCapability.handler with no pre-existing '_integration:spotify' in createValueTestDb and a full valid payload (assert result.integration matches the input and that testDb.entries.get('_integration:spotify') JSON contains the saved fields), and a second that calls the handler with no pre-existing entry but an invalid/missing required field (use the same Env and createMcpCallerContext setup) and assert that the handler throws a ZodError (or the appropriate validation error) rather than succeeding; place these tests alongside the existing ones in integration-save.node.test.ts so the new-creation branch in integration-save.ts and validation logic are exercised.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/worker/public/mcp-apps/kody-ui-utils.css`:
- Around line 10-13: Fix the Stylelint value-keyword-case violations in the
font-family declaration by normalizing casing and quoting where appropriate:
wrap custom font names with special characters/capital letters (e.g.,
SFMono-Regular) in quotes and ensure the generic family token is lowercase
(e.g., monospace) at the end of the list; update the font-family that currently
contains SFMono-Regular, Menlo, Monaco, Consolas to use quoted custom names and
a lowercase generic family to satisfy value-keyword-case.
---
Outside diff comments:
In `@packages/worker/src/mcp/capabilities/values/integration-save.ts`:
- Around line 64-78: The code calls integrationConfigSchema.parse(...) when
building the new integration which will throw an uncaught ZodError for missing
optional fields; change this to use integrationConfigSchema.safeParse(...) and,
when safeParse returns { success: false }, convert the validation errors into
the capability's structured error response (instead of letting the exception
bubble) so new integrations without required fields produce a clear, handled
error; update the block that sets integration (the ternary using
existingIntegration, mergeIntegrationConfig, and normalizeIntegrationConfig) to
perform the safeParse check before calling normalizeIntegrationConfig and handle
the failure path consistently with other MCP capability errors.
---
Nitpick comments:
In `@packages/worker/src/mcp/capabilities/values/integration-save.node.test.ts`:
- Around line 119-168: Add two tests for the "new-creation" path of
integrationSaveCapability: one that calls integrationSaveCapability.handler with
no pre-existing '_integration:spotify' in createValueTestDb and a full valid
payload (assert result.integration matches the input and that
testDb.entries.get('_integration:spotify') JSON contains the saved fields), and
a second that calls the handler with no pre-existing entry but an
invalid/missing required field (use the same Env and createMcpCallerContext
setup) and assert that the handler throws a ZodError (or the appropriate
validation error) rather than succeeding; place these tests alongside the
existing ones in integration-save.node.test.ts so the new-creation branch in
integration-save.ts and validation logic are exercised.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: c675a2ce-f20d-48d0-b859-106bb525526a
📒 Files selected for processing (40)
docs/contributing/architecture/index.mddocs/contributing/packages-and-manifests.mddocs/guides/connect-secret.mddocs/guides/generated-ui-oauth.mddocs/guides/integration-backed-app-happy-path.mddocs/guides/integration-bootstrap.mddocs/guides/oauth.mddocs/guides/secret-backed-integration.mddocs/use/execute.mddocs/use/first-steps.mddocs/use/search.mddocs/use/secrets-and-values.mdpackages/worker/client/routes/connect-oauth.node.test.tspackages/worker/client/routes/connect-oauth.tsxpackages/worker/client/routes/connect-secret-errors.tspackages/worker/client/routes/connect-secret.tsxpackages/worker/public/mcp-apps/kody-ui-utils.csspackages/worker/src/agent-turn/tools.tspackages/worker/src/app/handlers/account-secrets.node.test.tspackages/worker/src/app/handlers/account-secrets.tspackages/worker/src/app/handlers/connect-secret.node.test.tspackages/worker/src/app/handlers/connect-secret.tspackages/worker/src/mcp/capabilities/coding/kody-official-guide.tspackages/worker/src/mcp/capabilities/values/domain.tspackages/worker/src/mcp/capabilities/values/integration-delete.tspackages/worker/src/mcp/capabilities/values/integration-get.tspackages/worker/src/mcp/capabilities/values/integration-list.tspackages/worker/src/mcp/capabilities/values/integration-save.node.test.tspackages/worker/src/mcp/capabilities/values/integration-save.tspackages/worker/src/mcp/capabilities/values/integration-shared.tspackages/worker/src/mcp/execute-modules/authenticated-fetch.node.test.tspackages/worker/src/mcp/execute-modules/codemode-utils.node.test.tspackages/worker/src/mcp/execute-modules/codemode-utils.tspackages/worker/src/mcp/execute-modules/integration-host-allowlist.tspackages/worker/src/mcp/server-instructions.tspackages/worker/src/mcp/tools/execute.tspackages/worker/src/mcp/tools/search-format.node.test.tspackages/worker/src/mcp/tools/search-format.tspackages/worker/src/mcp/tools/search.node.test.tspackages/worker/src/mcp/tools/search.ts
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Summary
integration_get/list/save/delete,_integration:*,:integration)./connect/oauthand/connect/secretUI/API flows to use integration wording andintegrationsecret-binding metadata.Tests
npx vitest run --project node-unit packages/worker/src/mcp/capabilities/values/integration-save.node.test.ts packages/worker/src/mcp/tools/search.node.test.ts packages/worker/src/mcp/tools/search-format.node.test.ts packages/worker/src/app/handlers/connect-secret.node.test.ts packages/worker/src/app/handlers/account-secrets.node.test.ts packages/worker/client/routes/connect-oauth.node.test.ts packages/worker/src/mcp/execute-modules/codemode-utils.node.test.ts packages/worker/src/mcp/execute-modules/authenticated-fetch.node.test.tsnpm run typechecknpm run lint/connect/oauthand/connect/secret?...&integration=linear:Summary by CodeRabbit
Documentation
New Features
Bug Fixes