Skip to content

fix: add find projection step to IR for resilient outputComponents extraction#146

Closed
sushil-kamble wants to merge 1 commit intogoogle-labs-code:mainfrom
sushil-kamble:fix/projection-find-semantics
Closed

fix: add find projection step to IR for resilient outputComponents extraction#146
sushil-kamble wants to merge 1 commit intogoogle-labs-code:mainfrom
sushil-kamble:fix/projection-find-semantics

Conversation

@sushil-kamble
Copy link

Fixes #143

Problem

Project.generate() and Screen.edit() crash with:

TypeError: Cannot read properties of undefined (reading 'screens')

The root cause is that both methods hardcode outputComponents[0] to locate the design component, but the Stitch API now returns a designSystem component at index 0 and the actual design component at index 1:

outputComponents[0] → { designSystem: { ... } }       // no .design
outputComponents[1] → { design: { screens: [...] } }   // actual screen
outputComponents[2] → { text: "..." }
outputComponents[3+] → { suggestion: "..." }

SessionOutputComponent is a polymorphic union type with no ordering guarantee — hardcoding any index is fragile.

Solution

This PR takes the approach suggested in #143 (comment): instead of patching the index from 0 to 1 (as in PR #145), it adds proper find semantics to the ProjectionStep IR so the code generator emits .find((c: any) => c.design) — making extraction resilient to future API response ordering changes.

Changes

scripts/ir-schema.ts

  • Adds find: z.string().optional() to ProjectionStep
  • Updates refine() to forbid combining find with index or each

scripts/generate-sdk.ts

  • emitProjection(): emits .find((c: any) => c.X) for find steps
  • validateProjection(): treats find like index when unwrapping array item schemas

packages/sdk/generated/domain-map.json

  • Changes outputComponents projection step in generate_screen_from_text and edit_screens from { "index": 0 } to { "find": "design" }

Generated files

  • Regenerated via bun run generateproject.ts now emits:
    raw.outputComponents.find((c: any) => c.design).design.screens[0]

Tests

  • scripts/test/ir-schema.test.ts: 3 new tests (accepts find, rejects find+index, rejects find+each)
  • scripts/test/generate-sdk.test.ts: asserts correct .find(...) expression output
  • packages/sdk/test/unit/sdk.test.ts: updates mocks to reflect the real API shape (designSystem at [0], design at [1]) for generate and edit

Test plan

  • All 77 SDK unit tests pass (npm run test)
  • All 61 script tests pass (npm run test:scripts)
  • Full smoke check passes (npm run test:smoke)
  • Formatted with Prettier (npx prettier --write .)
  • bun run generate produces clean output with correct .find(...) expression

Why find over index: 1

PR #145 changes index: 0index: 1, which fixes the immediate crash but remains fragile — the next time the API adds or reorders a component, the index breaks again. The find approach queries by presence of a property, which is semantically stable regardless of array ordering.

🤖 Generated with Claude Code

…traction

The Stitch API returns outputComponents as a mixed, polymorphic array
(designSystem, design, text, suggestion) with no guaranteed ordering.
The SDK's generated generate() and edit() methods previously hardcoded
index 0 to locate the design component, causing a TypeError when the
API began returning a designSystem component at index 0.

This commit introduces a `find` step type to the ProjectionStep IR that
emits `.find((c: any) => c.<property>)` instead of a hardcoded array
index — making the extraction resilient to future API response ordering
changes.

Changes:
- scripts/ir-schema.ts: add `find: string` to ProjectionStep schema;
  update refine() to forbid combining find with index or each
- scripts/generate-sdk.ts: emit .find((c: any) => c.X) in
  emitProjection(); treat find like index in validateProjection()
  for schema unwrapping
- domain-map.json: change outputComponents step in generate_screen_from_text
  and edit_screens bindings from { index: 0 } to { find: "design" }
- Regenerate generated/src/{project,screen,stitch,index,tool-definitions}.ts
  and stitch-sdk.lock via `bun run generate`
- Add IR schema tests for find acceptance and mutual-exclusion rules
- Add emitProjection test asserting correct find expression output
- Update sdk.test.ts mocks to reflect actual API shape (designSystem at
  index 0, design at index 1) for generate and edit

Fixes google-labs-code#143

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@google-cla
Copy link

google-cla bot commented Mar 22, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@sushil-kamble sushil-kamble marked this pull request as draft March 22, 2026 10:20
@sushil-kamble
Copy link
Author

Removing 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.

generate() and edit() crash: outputComponents[0] is now designSystem, not screen data

1 participant