Objective
Update the code generator and domain map to support dynamic array searching, fixing the hardcoded index bug in Project.generate() that causes it to fail on subsequent calls when the response structure changes.
Code-Level Diagnosis
Code path: packages/sdk/scripts/ir-schema.ts, packages/sdk/scripts/generate-sdk.ts, and packages/sdk/generated/domain-map.json
Mechanism: The code generator relies on hardcoded indices (e.g., [1]) in ProjectionStep to extract screens from the outputComponents array. If the Stitch backend omits components (like designSystem) on subsequent calls, the index shifts, causing a StitchError.
Root cause: The projection schema and emission logic lack a way to express 'find the first element that matches the rest of the path' instead of 'pick the element at index N'.
Current Implementation
// In packages/sdk/generated/domain-map.json
"returns": {
"class": "Screen",
"projection": [
{
"prop": "outputComponents",
"index": 1
},
{
"prop": "design"
},
{
"prop": "screens",
"index": 0
}
]
}
Proposed Implementation
Files to modify: Add findFirst: z.boolean().optional() to ProjectionStep in ir-schema.ts. Add emitFindFirstProjection logic in generate-sdk.ts. Update domain-map.json to replace "index": 1 and "index": 0 with "findFirst": true for generate_screen_from_text and edit_screens.
Integration (Before -> After)
// In packages/sdk/scripts/ir-schema.ts
<<<<<<< SEARCH
index: z.number().int().min(0).optional(),
/** Flatten all items via flatMap (replaces [*] glob) */
each: z.boolean().optional(),
/** Alternate property name if primary is missing */
fallback: z.string().optional(),
}).refine(
data => !(data.index !== undefined && data.each),
{ message: "Cannot use both 'index' and 'each' on the same step" }
);
=======
index: z.number().int().min(0).optional(),
/** Flatten all items via flatMap (replaces [*] glob) */
each: z.boolean().optional(),
/** Find first matching item applying remaining steps */
findFirst: z.boolean().optional(),
/** Alternate property name if primary is missing */
fallback: z.string().optional(),
}).refine(
data => {
let count = 0;
if (data.index !== undefined) count++;
if (data.each) count++;
if (data.findFirst) count++;
return count <= 1;
},
{ message: "Cannot use more than one of 'index', 'each', or 'findFirst' on the same step" }
);
>>>>>>> REPLACE
Test Scenarios
- Run
bun scripts/generate-sdk.ts -> Verify Project.generate now uses (raw?.outputComponents || []).map((a: any) => a?.design?.screens?.[0]).find((x: any) => x).
- Run
npm run test -> Verify existing generation tests pass.
Target Files
- packages/sdk/scripts/ir-schema.ts
- packages/sdk/scripts/generate-sdk.ts
- packages/sdk/generated/domain-map.json
Boundary Rules
Restrict your modifications exclusively to the files listed in the Target Files section. Ensure your source changes are entirely backward-compatible if unowned tests outside your boundary fail. Retain all existing file names and locations outside your explicitly declared target list.
Fleet Context
Objective
Update the code generator and domain map to support dynamic array searching, fixing the hardcoded index bug in Project.generate() that causes it to fail on subsequent calls when the response structure changes.
Code-Level Diagnosis
Code path: packages/sdk/scripts/ir-schema.ts, packages/sdk/scripts/generate-sdk.ts, and packages/sdk/generated/domain-map.json
Mechanism: The code generator relies on hardcoded indices (e.g.,
[1]) inProjectionStepto extract screens from theoutputComponentsarray. If the Stitch backend omits components (likedesignSystem) on subsequent calls, the index shifts, causing aStitchError.Root cause: The projection schema and emission logic lack a way to express 'find the first element that matches the rest of the path' instead of 'pick the element at index N'.
Current Implementation
Proposed Implementation
Files to modify: Add
findFirst: z.boolean().optional()toProjectionStepinir-schema.ts. AddemitFindFirstProjectionlogic ingenerate-sdk.ts. Updatedomain-map.jsonto replace"index": 1and"index": 0with"findFirst": trueforgenerate_screen_from_textandedit_screens.Integration (Before -> After)
// In packages/sdk/scripts/ir-schema.ts <<<<<<< SEARCH index: z.number().int().min(0).optional(), /** Flatten all items via flatMap (replaces [*] glob) */ each: z.boolean().optional(), /** Alternate property name if primary is missing */ fallback: z.string().optional(), }).refine( data => !(data.index !== undefined && data.each), { message: "Cannot use both 'index' and 'each' on the same step" } ); ======= index: z.number().int().min(0).optional(), /** Flatten all items via flatMap (replaces [*] glob) */ each: z.boolean().optional(), /** Find first matching item applying remaining steps */ findFirst: z.boolean().optional(), /** Alternate property name if primary is missing */ fallback: z.string().optional(), }).refine( data => { let count = 0; if (data.index !== undefined) count++; if (data.each) count++; if (data.findFirst) count++; return count <= 1; }, { message: "Cannot use more than one of 'index', 'each', or 'findFirst' on the same step" } ); >>>>>>> REPLACETest Scenarios
bun scripts/generate-sdk.ts-> VerifyProject.generatenow uses(raw?.outputComponents || []).map((a: any) => a?.design?.screens?.[0]).find((x: any) => x).npm run test-> Verify existing generation tests pass.Target Files
Boundary Rules
Restrict your modifications exclusively to the files listed in the Target Files section. Ensure your source changes are entirely backward-compatible if unowned tests outside your boundary fail. Retain all existing file names and locations outside your explicitly declared target list.
Fleet Context
jules:session:6838834040449678025