Skip to content

fix(exo): allow viewport-free tool payloads [SPA-5371] - #480

Merged
Thomas Kellermeier (Chaoste) merged 3 commits into
mainfrom
fix/SPA-5371-allow-viewport-free-exo-tools
Sep 25, 2026
Merged

Thomas Kellermeier (Chaoste) merged 3 commits into
mainfrom
fix/SPA-5371-allow-viewport-free-exo-tools

Conversation

@Chaoste

@Chaoste Thomas Kellermeier (Chaoste) commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Allow ExO MCP tools to create and update payloads without viewport definitions.

Description

Component and Experience Template tool arguments now omit viewports when it is absent. Experience and Experience Fragment tool arguments and read-modify-write paths preserve the flattened design-property shape returned by the API alongside that omission. Focused coverage exercises new create and update payloads as well as legacy payload preservation.

Motivation and Context

Implements SPA-5371. The API will stop returning and accepting viewports; emitting viewports: [] would incorrectly retain the legacy value representation.

This PR is intentionally blocked on the published CMA type update from contentful-management.js#3149. The current package types still require viewports and dimensioned design-property values, so npm run typecheck fails rather than masking the contract mismatch with assertions.

PR Checklist

  • I have read the CONTRIBUTING.md file
  • All commits follow conventional commits
  • Documentation is updated (if necessary)
  • PR doesn't contain any sensitive information
  • There are no breaking changes

Note: This PR was created with the contentful-github-create-pull-request skill, powered by Agents Kit. To follow or use this workflow, see the Agents Kit CLI skill docs.

Summary by Bito

This PR updates ExO MCP tools to create and update Components, Experience Templates, Experiences, and Experience Fragments without viewport definitions. It also preserves the flattened design-property representation returned by the API while retaining compatibility with legacy dimensioned values during create and read-modify-write operations.

Detailed Changes
  • Create payload builders in createComponent.ts, createExperienceTemplate.ts, createExperience.ts, and createExperienceFragment.ts conditionally omit viewports when the argument is undefined, allowing viewport-free CMA requests.
  • Read-modify-write builders in upsertComponent.ts, upsertExperienceTemplate.ts, upsertExperience.ts, and updateExperienceFragment.ts preserve existing viewport data when present but do not restore the field when both arguments and fetched resources omit it.
  • Experience and Experience Fragment design-property payloads now accept flattened or dimensioned values through the shared cmaViewportCompatibility.ts type boundary, preserving the API's flattened representation.
  • Focused Vitest coverage in createComponent.test.ts, createExperienceTemplate.test.ts, createExperience.test.ts, and createExperienceFragment.test.ts exercises viewport-free create payloads and flattened design-property handling.

@bito-code-review

bito-code-review Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Changelist by Bito

This pull request implements the following key changes.

Key Change Files Impacted Summary
Feature Improvement - Support Optional Viewports for Components and Experience Templates
Component and Experience Template create and upsert tools now omit the viewports property when callers and existing resources do not provide viewport definitions. Tests verify viewport-free create payloads and prevent read-modify-write operations from reintroducing the legacy field.
Feature Improvement - Support Viewport-Free Experiences with Flattened Design Properties
Experience and Experience Fragment payloads support omitted viewports while accepting both flattened and legacy dimensioned design-property values. A localized CMA compatibility layer handles the mismatch with the currently consumed SDK types, and focused tests cover flattened-property preservation.

@bito-code-review

bito-code-review Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Functional Validation by Bito

SourceRequirement / Code AreaStatusNotes
SPA-5371, SPA-5269, Viewport-Removal-ClientAllow ExO tool payloads to omit viewport definitions when no viewports are present.✅ MetTool schemas now make viewport definitions optional, and payload construction omits viewports when no viewport definitions are supplied across ExO component, experience fragment, experience template, and experience tools. This is implemented in packages/mcp-tools/src/tools/exo/components/createComponent.ts, packages/mcp-tools/src/tools/exo/experience-fragments/createExperienceFragment.ts, packages/mcp-tools/src/tools/exo/experience-templates/createExperienceTemplate.ts, and packages/mcp-tools/src/tools/exo/experiences/createExperience.ts.
SPA-5371, Viewport-Removal-ClientPreserve the shape of ExO payloads when reading and writing entities: retain the legacy viewport-based representation before the migration phase, and preserve omitted viewports together with flattened design-property values after the API transition.✅ MetThe update paths preserve omitted viewports instead of restoring them, while viewport-free Experiences and Experience Fragments accept and preserve flattened design-property values. The compatibility types and payload adapters in packages/mcp-tools/src/types/cmaViewportCompatibility.ts are used by updateExperienceFragmentTool, upsertExperienceTool, upsertComponentTool, and upsertExperienceTemplateTool.
SPA-5371, Viewport-Removal-ClientDo not convert an absent viewport definition into an empty viewport array when constructing or updating ExO payloads.✅ MetPayload construction uses conditional spreads so an absent viewport definition is omitted rather than converted to an empty array. Regression tests verify this behavior for create and update/upsert operations, including packages/mcp-tools/src/tools/exo/components/createComponent.test.ts, packages/mcp-tools/src/tools/exo/components/upsertComponent.test.ts, packages/mcp-tools/src/tools/exo/experiences/createExperience.test.ts, and packages/mcp-tools/src/tools/exo/experiences/upsertExperience.test.ts.
SPA-5371, Viewport-Removal-ClientUse a published API or SDK contract in which ExO viewport definitions are optional wherever the client relies on that contract for payload validation or typing.🟡 PartialThe implementation supports optional viewports and flattened design properties at the SDK boundary through asViewportOptionalCmaPayload and asViewportOptionalCmaPayloadWithFlattenedDesignProperties in packages/mcp-tools/src/types/cmaViewportCompatibility.ts. However, the diff indicates that the consumed contentful-management SDK still declares viewports as required and uses a local compatibility type assertion rather than updating or adopting a published API/SDK contract with optional viewport definitions.

@bito-code-review

bito-code-review Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Impact Analysis by Bito

Interaction Diagram
sequenceDiagram
participant Agent as Agent Client
participant Server as MCP Server<br/>🔄 Updated | ●●● High
participant Tools as ExO Tools<br/>🔄 Updated | ●●● High
participant Compat as cmaViewportCompatibility<br/>🟩 Added | ●●● High
participant CMA as Contentful Management API
participant Consumer as 🔗 agents-api
Agent->>Server: Connect over stdio MCP transport
Server->>Server: Register ExO tools when entitlement and feature flag pass
Server-->>Agent: Expose create and upsert ExO tool schemas
Agent->>Consumer: Invoke ExO workflow through agent tooling
Consumer->>Server: Call create_component or create_experience
Server->>Tools: Validate arguments and protected environment
Tools->>Compat: Build viewport-optional payload
Compat-->>Tools: Return CMA-compatible transformed payload
Tools->>CMA: POST create request without undefined viewports
CMA-->>Tools: Return created ExO resource
Tools-->>Server: Create success response
Server-->>Consumer: Return structured MCP result
Consumer-->>Agent: Present created resource
alt Existing resource update
Consumer->>Server: Call upsert tool with resource version
Server->>Tools: Read current resource before write
Tools->>CMA: GET current resource and validate version
CMA-->>Tools: Return current state or version conflict
Tools->>Compat: Preserve optional viewports and flatten design properties
Compat-->>Tools: Return update payload without undefined fields
Tools->>CMA: PUT upsert request with validated version
CMA-->>Tools: Return updated resource
    end
Loading

This MR modifies the ExO component, experience, experience template, and experience fragment tools so viewport-free resources are accepted without reintroducing undefined viewports, while flattened design properties are supported. It adds the cmaViewportCompatibility transformation layer at the Contentful Management API boundary and preserves read-before-write version checks for updates. The MCP Server remains the registration and transport entrypoint, while the cross-repository agents-api consumer can invoke the updated ExO tool contracts.

Cross-Repository Impact Analysis
What Changed Impact of Change Suggested Review Actions
The ExO MCP tool input contracts now allow viewport-free components, experience fragments, experience templates, and experiences; experience and fragment design properties also accept flattened values. - verify-needed: external consumers of createComponent, createExperienceFragment, createExperienceTemplate, and createExperience tool schemas: The MCP tool schemas changed from required viewport arrays to optional arrays. Existing clients should remain valid, but generated clients, validators, or documentation may need to account for viewport-free payloads.
- verify-needed: external consumers of createExperienceFragment.designProperties, updateExperienceFragment.designProperties, createExperience.designProperties, and upsertExperience.designProperties: The accepted design-property shape is broadened from dimensioned maps to either direct or dimensioned values. Consumers relying on the old schema may need regenerated types or updated validation.
- Search organization-wide MCP clients and generated tool schemas for the affected tool names before merge.
- Confirm that clients distinguish an omitted viewports property from an explicitly empty viewport array.
- Regenerate or update any published MCP tool descriptions and client-side validators.
Create and update operations now omit viewports instead of serializing an undefined viewport field, and use local compatibility casts at the contentful-management SDK boundary. - verify-needed: consumers of the Contentful Management API ExO create/upsert requests: The wire payload changes for viewport-free resources: viewports is absent rather than present with an undefined value. This is intended to support CMA entities without viewports but should be validated against the live API contract. - Run integration tests against a CMA environment for viewport-free Component, ExperienceFragment, ExperienceTemplate, and Experience resources.
- Verify that update/upsert operations do not accidentally clear existing viewports when the caller omits viewports.
- Confirm the SDK cast remains isolated and does not mask unrelated payload type errors.
A new shared compatibility module was added to bridge the CMA-supported payload shape and the currently consumed contentful-management 12.14.0 TypeScript definitions. - intra-repo: packages/mcp-tools/src/types/cmaViewportCompatibility.ts and all eight modified ExO tool implementations: The helper types and casts centralize the SDK type exception while preserving structural validation through satisfies.
- verify-needed: downstream packages importing @contentful/mcp-tools: The new module exports public types and functions, but the package export map and generated declarations should be checked to ensure the new file is included or intentionally private.
- Run the package build and declaration generation to confirm the new module compiles and is included as intended.
- Decide whether the compatibility helpers should remain exported from the package surface or be made internal.
- Recheck the helper constraints after upgrading contentful-management.
Code Paths Analyzed

Impact:
This change enables viewport-free ExO resources and flattened design-property values while preserving the existing dimensioned format. Tool schemas are broadened, payload construction conditionally omits undefined viewports, and a compatibility layer isolates mismatches between CMA behavior and contentful-management TypeScript definitions.

Flow:
MCP tool invocation → Zod validation of optional viewports and design-property unions → resource payload construction → compatibility helper cast → contentful-management create/upsert API call → success response. Update and upsert paths first read the current entity, merge supplied and existing fields, then apply the same conditional payload handling.

Direct Changes (Diff Files):
• packages/mcp-tools/src/tools/exo/components/createComponent.test.ts [3-18] — Adds coverage that viewport-free component creation omits viewports.
• packages/mcp-tools/src/tools/exo/components/createComponent.ts [26-72] — Makes viewports optional and conditionally includes it in the create payload.
• packages/mcp-tools/src/tools/exo/components/upsertComponent.test.ts [94-106] — Adds coverage that upserting a viewport-free component does not send viewports.
• packages/mcp-tools/src/tools/exo/components/upsertComponent.ts [86-159] — Builds an intermediate payload and conditionally omits undefined viewports before upsert.
• packages/mcp-tools/src/tools/exo/experience-fragments/createExperienceFragment.test.ts [168-191] — Tests viewport-free fragment creation with flattened design properties.
• packages/mcp-tools/src/tools/exo/experience-fragments/createExperienceFragment.ts [201-268] — Accepts direct design-property values, optional viewports, and uses the flattened compatibility helper.
• packages/mcp-tools/src/tools/exo/experience-fragments/updateExperienceFragment.test.ts [276-297] — Tests preservation of flattened design properties without reintroducing viewports.
• packages/mcp-tools/src/tools/exo/experience-fragments/updateExperienceFragment.ts [305-392] — Broadens design-property validation and applies compatibility payload handling during update.
• packages/mcp-tools/src/tools/exo/experience-templates/createExperienceTemplate.test.ts [400-413] — Tests creation of a viewport-free experience template.
• packages/mcp-tools/src/tools/exo/experience-templates/createExperienceTemplate.ts [421-472] — Makes template viewports optional and conditionally builds the create payload.
• packages/mcp-tools/src/tools/exo/experience-templates/upsertExperienceTemplate.test.ts [480-496] — Tests that upsert does not reintroduce viewports for a viewport-free template.
• packages/mcp-tools/src/tools/exo/experience-templates/upsertExperienceTemplate.ts [504-576] — Conditionally carries forward viewports and routes the payload through the compatibility helper.
• packages/mcp-tools/src/tools/exo/experiences/createExperience.test.ts [583-608] — Tests viewport-free experience creation with flattened design properties.
• packages/mcp-tools/src/tools/exo/experiences/createExperience.ts [616-688] — Broadens the experience schema and conditionally omits viewports in the create request.
• packages/mcp-tools/src/tools/exo/experiences/upsertExperience.test.ts [694-740] — Adds coverage for preserving flattened properties and omitting viewports during upsert.
• packages/mcp-tools/src/tools/exo/experiences/upsertExperience.ts [748-813] — Broadens design-property validation and conditionally preserves viewports during upsert.
• packages/mcp-tools/src/types/cmaViewportCompatibility.ts [820-875] — Adds shared payload types and SDK-boundary cast helpers for optional viewports and flattened design properties.

Repository Impact:
• MCP tool schemas: Viewport arrays become optional for create operations, and experience/fragment design properties accept both flattened and dimensioned forms.
• CMA request construction: Undefined viewports are omitted, preventing an invalid or misleading field from reaching the SDK/API.
• Read-before-write update paths: Upsert/update payloads now preserve viewport-free resources without reintroducing the property.
• Type declarations and package build: A new TypeScript module imports contentful-management and Zod types and is used by all affected tools.

Cross-Repository Dependencies:
• Contentful Management API and contentful-management 12.14.0: The implementation intentionally bypasses SDK-required TypeScript fields for CMA-supported viewport-free payloads.
• MCP clients and downstream TypeScript consumers of @contentful/mcp-tools: Published tool schemas and generated declarations may expose changed optionality and design-property unions.

Database/Caching Impact:
• None

API Contract Violations:
• The SDK type definitions require viewports for some ExO payloads while the CMA contract supports omitting them; the new cast intentionally suppresses that mismatch and therefore requires CMA integration verification.
• Clients or generated schemas that assume viewports is always present may need updates.
• Flattened design-property values are now accepted for experiences and experience fragments; response and persistence behavior should be checked for round-trip consistency.

Infrastructure Dependencies:
• No CI, deployment, environment-variable, database migration, queue, or infrastructure file changes are present in the diff.
• The package continues to target Node.js >=22.0.0 and contentful-management 12.14.0; no dependency version change is shown.

Additional Insights:
• Backward compatibility: Existing dimensioned design-property payloads remain accepted through the union, and existing viewport-bearing payloads remain included.
• Payload semantics: An omitted viewports field is distinct from an empty array; tests currently cover omission but should also verify explicit empty-array behavior.
• Type-safety boundary: The compatibility casts are localized, but callers must continue using satisfies so unrelated fields remain statically checked.

Testing Recommendations

Frontend Impact:
• If MCP clients generate forms or schemas from tool definitions, verify that viewports is optional for createComponent, createExperienceFragment, createExperienceTemplate, and createExperience.
• Verify generated clients can submit flattened designProperties such as { color: { type: 'ManualDesignValue', value: 'red' } } for experiences and experience fragments.

Service Integration:
• Run CMA integration tests creating and updating viewport-free Component, ExperienceFragment, ExperienceTemplate, and Experience resources.
• Verify read-before-write update paths preserve omitted viewports and do not clear or recreate them unexpectedly.
• Run the complete mcp-tools test suite and typecheck/build commands.

Data Serialization:
• Assert that omitted viewports is absent from the serialized request body, while an explicitly supplied empty viewports array remains present.
• Round-trip flattened and dimensioned designProperties through create, get, and upsert operations.
• Test malformed design-property values are rejected by the union schemas.

Privacy Compliance:
• None.

Backward Compatibility:
• Run existing dimensioned design-property fixtures through createExperience, upsertExperience, createExperienceFragment, and updateExperienceFragment.
• Verify existing viewport-bearing payloads remain byte-for-byte equivalent apart from the new compatibility construction.
• Compile downstream TypeScript usage against generated declarations to detect unintended public type changes.

OAuth Functionality:
• None

Cross-Service Communication:
• Validate request bodies against the CMA contract using both viewport-bearing and viewport-free resources.
• Test CMA error handling when a resource type rejects flattened properties or an omitted viewports field.

Reliability Testing:
• None

Additional Insights:
• Build the package with declaration emit and confirm cmaViewportCompatibility.ts is handled correctly by the package export/build configuration.
• Add direct unit tests for asViewportOptionalCmaPayload and asViewportOptionalCmaPayloadWithFlattenedDesignProperties if these helpers remain public.
• After any contentful-management upgrade, remove or reassess the casts if the SDK types gain native support.

Analysis based on known dependency patterns and edges. Actual impact may vary.

@bito-code-review bito-code-review Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Agent Run #ba199d

Actionable Suggestions - 8
  • packages/mcp-tools/src/tools/exo/components/createComponent.ts - 1
  • packages/mcp-tools/src/tools/exo/experiences/createExperience.ts - 1
  • packages/mcp-tools/src/tools/exo/experience-fragments/createExperienceFragment.ts - 1
    • Viewports optional may mismatch API · Line 30-30
  • packages/mcp-tools/src/tools/exo/components/upsertComponent.ts - 1
  • packages/mcp-tools/src/tools/exo/experience-templates/upsertExperienceTemplate.ts - 1
  • packages/mcp-tools/src/tools/exo/experience-templates/createExperienceTemplate.ts - 1
    • Viewports optional may break API contract · Line 26-26
  • packages/mcp-tools/src/tools/exo/experience-fragments/updateExperienceFragment.ts - 1
  • packages/mcp-tools/src/tools/exo/experience-fragments/updateExperienceFragment.test.ts - 1
Additional Suggestions - 1
  • packages/mcp-tools/src/tools/exo/experience-fragments/updateExperienceFragment.ts - 1
    • Redundant union arm in record · Line 43-49
      `DesignPropertyValueSchema` (exoSchemas.ts:322) is a union of object schemas; `DimensionedDesignPropertyValueSchema` (exoSchemas.ts:338) is `z.record(z.string(), DesignPropertyValueSchema)`, which already accepts any such object as a value. The first union arm is subsumed — possibly `DesignPropertyPointerValueSchema` was intended. Resolve the duplication or add the missing arm.
Review Details
  • Files reviewed - 16 · Commit Range: 6e92617..6e92617
    • packages/mcp-tools/src/tools/exo/components/createComponent.test.ts
    • packages/mcp-tools/src/tools/exo/components/createComponent.ts
    • packages/mcp-tools/src/tools/exo/components/upsertComponent.test.ts
    • packages/mcp-tools/src/tools/exo/components/upsertComponent.ts
    • packages/mcp-tools/src/tools/exo/experience-fragments/createExperienceFragment.test.ts
    • packages/mcp-tools/src/tools/exo/experience-fragments/createExperienceFragment.ts
    • packages/mcp-tools/src/tools/exo/experience-fragments/updateExperienceFragment.test.ts
    • packages/mcp-tools/src/tools/exo/experience-fragments/updateExperienceFragment.ts
    • packages/mcp-tools/src/tools/exo/experience-templates/createExperienceTemplate.test.ts
    • packages/mcp-tools/src/tools/exo/experience-templates/createExperienceTemplate.ts
    • packages/mcp-tools/src/tools/exo/experience-templates/upsertExperienceTemplate.test.ts
    • packages/mcp-tools/src/tools/exo/experience-templates/upsertExperienceTemplate.ts
    • packages/mcp-tools/src/tools/exo/experiences/createExperience.test.ts
    • packages/mcp-tools/src/tools/exo/experiences/createExperience.ts
    • packages/mcp-tools/src/tools/exo/experiences/upsertExperience.test.ts
    • packages/mcp-tools/src/tools/exo/experiences/upsertExperience.ts
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers an incremental AI Review.

  • /review full - Manually triggers a full AI Review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Default Agent You can customize the agent settings here or contact your Bito workspace admin at jared.jolton@contentful.com.

Documentation & Help

AI Code Review powered by Bito Logo

Comment thread packages/mcp-tools/src/tools/exo/components/createComponent.ts
Comment thread packages/mcp-tools/src/tools/exo/experiences/createExperience.ts
Comment thread packages/mcp-tools/src/tools/exo/components/upsertComponent.ts Outdated
Comment thread packages/mcp-tools/src/tools/exo/experience-templates/upsertExperienceTemplate.ts Outdated
Comment thread packages/mcp-tools/src/tools/exo/experience-fragments/updateExperienceFragment.ts Outdated
@bito-code-review

Copy link
Copy Markdown

✅ Review Settings Overridden

Status: Overridden Successfully

Guidelines:

  • Accepted:

    • General : Review Posture, Repo Truth And Alignment, Domain Invariants

Note: Extra guidelines beyond 3 general purpose guidelines and 1 language specific guideline per language are not processed. Guidelines are fetched from the source branch.

@Chaoste
Thomas Kellermeier (Chaoste) marked this pull request as ready for review September 25, 2026 14:23
@Chaoste
Thomas Kellermeier (Chaoste) merged commit e5ff2bc into main Sep 25, 2026
15 checks passed
@Chaoste
Thomas Kellermeier (Chaoste) deleted the fix/SPA-5371-allow-viewport-free-exo-tools branch September 25, 2026 14:41

@bito-code-review bito-code-review Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Agent Run #609b4f

Actionable Suggestions - 3
  • packages/mcp-tools/src/tools/exo/components/createComponent.ts - 1
    • Redundant generic, duplicated conversion · Line 90-92
  • packages/mcp-tools/src/tools/exo/experiences/upsertExperience.ts - 1
  • packages/mcp-tools/src/types/cmaViewportCompatibility.ts - 1
Additional Suggestions - 2
  • packages/mcp-tools/src/tools/exo/experiences/createExperience.test.ts - 1
    • undefined key not omitted · Line 43-43
      `{ ...createArgs, viewports: undefined }` keeps an own `viewports` key with value `undefined`, unlike the removed rest-destructure which omitted the key. Harmless today: `createExperience.ts` gates on `args.viewports !== undefined` and the mock ignores args, so `not.toHaveProperty('viewports')` still passes. But the assertion checks `mock.calls[0][1]` while the key lives on the input object, so the test no longer proves the CMA payload omits `viewports`. Prefer key omission over `undefined` to keep the fixture honest.
  • packages/mcp-tools/src/tools/exo/experiences/upsertExperience.ts - 1
    • Duplicated SDK cast pattern · Line 123-123
      This `satisfies` + `asViewportOptionalCmaPayload*` idiom duplicates `upsertComponent.ts:124` (`asViewportOptionalCmaPayload(componentData)`). Both encode 'current CMA SDK requires viewports/designProperties that the API does not'; when the SDK relaxes those types, one site can be updated while the other silently keeps a stale cast. Consider a shared helper or cross-linking comments between the sites.
Review Details
  • Files reviewed - 13 · Commit Range: 6e92617..5020d7d
    • packages/mcp-tools/src/tools/exo/components/createComponent.test.ts
    • packages/mcp-tools/src/tools/exo/components/createComponent.ts
    • packages/mcp-tools/src/tools/exo/components/upsertComponent.ts
    • packages/mcp-tools/src/tools/exo/experience-fragments/createExperienceFragment.test.ts
    • packages/mcp-tools/src/tools/exo/experience-fragments/createExperienceFragment.ts
    • packages/mcp-tools/src/tools/exo/experience-fragments/updateExperienceFragment.ts
    • packages/mcp-tools/src/tools/exo/experience-templates/createExperienceTemplate.test.ts
    • packages/mcp-tools/src/tools/exo/experience-templates/createExperienceTemplate.ts
    • packages/mcp-tools/src/tools/exo/experience-templates/upsertExperienceTemplate.ts
    • packages/mcp-tools/src/tools/exo/experiences/createExperience.test.ts
    • packages/mcp-tools/src/tools/exo/experiences/createExperience.ts
    • packages/mcp-tools/src/tools/exo/experiences/upsertExperience.ts
    • packages/mcp-tools/src/types/cmaViewportCompatibility.ts
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers an incremental AI Review.

  • /review full - Manually triggers a full AI Review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Default Agent You can customize the agent settings here or contact your Bito workspace admin at jared.jolton@contentful.com.

Documentation & Help

AI Code Review powered by Bito Logo

Comment on lines 90 to +92
componentId: args.componentId,
},
{
asViewportOptionalCmaPayload<

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant generic, duplicated conversion

The upsert branch re-wraps the already-validated componentData with an explicit generic that type inference supplies anyway — the same helper is called without type arguments at line 99 and in upsertComponent.ts (line 124), which also passes a sys-bearing payload. Keeping one conversion style avoids divergence between the create and upsert paths.

Code Review Run #609b4f


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

Comment on lines +117 to +124
} satisfies ViewportOptionalPayloadWithFlattenedDesignProperties<
Parameters<typeof contentfulClient.experience.upsert>[1]
>;

const experience = await contentfulClient.experience.upsert(
params,
asViewportOptionalCmaPayloadWithFlattenedDesignProperties(experienceData),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cast bypasses payload type check

asViewportOptionalCmaPayloadWithFlattenedDesignProperties is a pure as Payload cast (cmaViewportCompatibility.ts:50-51), with no runtime transformation. The satisfies at line 117 validates experienceData against the widened type where flattened designProperties are legal, but contentfulClient.experience.upsert (contentful-management 12.14.0) still types them as the legacy dimensioned shape, so flattened values reach the CMA with no compile-time or runtime check.

Code Review Run #609b4f


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

* `satisfies`.
*/
export type ViewportOptionalPayload<Payload> = Omit<Payload, 'viewports'> & {
viewports?: ComponentTypeViewport[];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated viewports member

Lines 20 and 30 re-declare the same viewports?: ComponentTypeViewport[] member in the two sibling compatibility types. Extracting a shared base (e.g. type WithOptionalViewports = { viewports?: ComponentTypeViewport[] }) keeps both SDK-boundary shims in sync as the CMA viewports contract evolves; divergence would silently loosen one call boundary but not the other.

Code Review Run #609b4f


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

@bito-code-review

Copy link
Copy Markdown

Bito Automatic Review Skipped – PR Already Merged

Bito scheduled an automatic review for this pull request, but the review was skipped because this PR was merged before the review could be run.
No action is needed if you didn't intend to review it. To get a review, you can type /review in a comment and save it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants