[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-vercel-migrating-to-workflow-sdk":3,"mdc-rs7jrn-key":31,"related-org-vercel-migrating-to-workflow-sdk":1804,"related-repo-vercel-migrating-to-workflow-sdk":1983},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":20,"repoUrl":21,"updatedAt":22,"license":23,"forks":24,"topics":25,"repo":26,"sourceUrl":29,"mdContent":30},"migrating-to-workflow-sdk","migrate workflows to Vercel Workflow SDK","Migrates Temporal, Inngest, Trigger.dev, and AWS Step Functions workflows to the Workflow SDK. Use when porting Activities, Workers, Signals, step.run(), step.waitForEvent(), Trigger.dev tasks \u002F wait.forToken \u002F triggerAndWait, ASL JSON state machines, Task\u002FChoice\u002FWait\u002FParallel states, task tokens, or child workflows.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"vercel","Vercel","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fvercel.png",[12,14,17],{"name":9,"slug":8,"type":13},"tag",{"name":15,"slug":16,"type":13},"Migration","migration",{"name":18,"slug":19,"type":13},"Workflow Automation","workflow-automation",2228,"https:\u002F\u002Fgithub.com\u002Fvercel\u002Fworkflow","2026-04-13T05:21:00.819323",null,307,[],{"repoUrl":21,"stars":20,"forks":24,"topics":27,"description":28},[],"Workflow SDK: Build durable, reliable, and observable apps and AI Agents in TypeScript","https:\u002F\u002Fgithub.com\u002Fvercel\u002Fworkflow\u002Ftree\u002FHEAD\u002Fskills\u002Fmigrating-to-workflow-sdk","---\nname: migrating-to-workflow-sdk\ndescription: Migrates Temporal, Inngest, Trigger.dev, and AWS Step Functions workflows to the Workflow SDK. Use when porting Activities, Workers, Signals, step.run(), step.waitForEvent(), Trigger.dev tasks \u002F wait.forToken \u002F triggerAndWait, ASL JSON state machines, Task\u002FChoice\u002FWait\u002FParallel states, task tokens, or child workflows.\nmetadata:\n  author: Vercel Inc.\n  version: '0.2.0'\n---\n\n# Migrating to the Workflow SDK\n\nUse this skill when converting an existing orchestration system to the Workflow SDK.\n\n## Intake\n\n1. Identify the source system:\n   - Temporal\n   - Inngest\n   - Trigger.dev\n   - AWS Step Functions\n2. Identify the target runtime:\n   - Managed hosting -> keep examples focused on `start()`, `getRun()`, hooks\u002Fwebhooks, and route handlers.\n   - Self-hosted -> also read `references\u002Fruntime-targets.md` and explicitly say the workflow\u002Fstep code can stay the same, but deployment still needs a `World` implementation and startup bootstrap.\n3. Extract the source constructs:\n   - entrypoint\n   - waits \u002F timers\n   - external callbacks \u002F approvals\n   - retries \u002F failure handling\n   - child workflows \u002F fan-out\n   - progress streaming\n   - external side effects\n\n## Default migration rules\n\n- Put orchestration in `\"use workflow\"` functions.\n- Put side effects, SDK calls, DB calls, HTTP calls, and stream I\u002FO in `\"use step\"` functions.\n- Use `sleep()` only in workflow context.\n- For Signals, `step.waitForEvent()`, and `.waitForTaskToken`, choose exactly one resume surface:\n  - `resume\u002Finternal` -> `createHook()` + `resumeHook()` when the app resumes from server-side code with a deterministic business token.\n  - `resume\u002Furl\u002Fdefault` -> `createWebhook()` when the external system needs a generated callback URL and the default `202 Accepted` response is fine.\n  - `resume\u002Furl\u002Fmanual` -> `createWebhook({ respondWith: 'manual' })` only when the prompt explicitly requires a custom response body, status, or headers.\n  - If a callback-URL prompt does not specify response semantics, default to `resume\u002Furl\u002Fdefault` and make the assumption explicit in `## Open Questions`.\n- Never pair `createWebhook()` with `resumeHook()`, and never pass `token:` to `createWebhook()`.\n- Wrap `start()` and `getRun()` inside `\"use step\"` functions for child runs.\n- Use `getStepMetadata().stepId` as the idempotency key for external writes.\n- Use `getWritable()` in workflow context to obtain the stream, but interact with it (write, close) only inside `\"use step\"` functions.\n- Prefer rollback stacks for multi-step compensation.\n- Choose app-boundary syntax in this order:\n  1. If the prompt explicitly asks for framework-agnostic app-boundary code, use plain `Request` \u002F `Response` even when a framework like Hono is named.\n  2. Otherwise, if the target framework is named, shape app-boundary examples to that framework.\n  3. Otherwise, keep examples framework-agnostic with `Request` \u002F `Response`. Do not default to Next.js-only route signatures unless Next.js is explicitly named.\n\n> Fast memory aid:\n> - Callback URL + default ack -> `createWebhook()`\n> - Callback URL + custom ack -> `createWebhook({ respondWith: 'manual' })`\n> - Deterministic server-side resume -> `createHook()` + `resumeHook()`\n\n## Fast-path router\n\nLoad `references\u002Fresume-routing.md` when the source pauses for Signals, `step.waitForEvent()`, or `.waitForTaskToken`.\n\nFast defaults:\n\n- callback URL only -> `resume\u002Furl\u002Fdefault`\n- callback URL + explicit custom response -> `resume\u002Furl\u002Fmanual`\n- deterministic server-side resume -> `resume\u002Finternal`\n- self-hosted -> add `runtime\u002Fself-hosted`\n- named framework -> add `boundary\u002Fnamed-framework`\n- explicit framework-agnostic request -> add `boundary\u002Fframework-agnostic`\n\nBefore drafting `## Migrated Code`, write the selected route keys in `## Migration Plan`.\n\n## Source references\n\n- Temporal -> `references\u002Ftemporal.md`\n- Inngest -> `references\u002Finngest.md`\n- Trigger.dev -> `references\u002Ftrigger-dev.md`\n- AWS Step Functions -> `references\u002Faws-step-functions.md`\n\n## Shared references\n\n- `references\u002Fshared-patterns.md` — reusable code templates for hooks, child workflows, idempotency, streaming, and rollback.\n- `references\u002Fruntime-targets.md` — Managed vs custom `World` guidance.\n- `references\u002Fresume-routing.md` — route-key selection, obligations, and exact `## Migration Plan` shape.\n- `references\u002Fretries.md` — canonical retry mechanics: `stepFn.maxRetries`, `RetryableError({ retryAfter })`, `FatalError`.\n\n## Required output shape\n\nReturn the migration in this structure:\n\n```md\n## Migration Plan\n## Source -> Target Mapping\n## Migrated Code\n## App Boundary \u002F Resume Endpoints\n## Verification Checklist\n## Open Questions\n```\n\n## Verification checklist\n\nFail the draft if any of these are true:\n\n- [ ] `## Migration Plan` omits `Route keys`\n- [ ] `## Migration Plan` omits `Why these route keys`\n- [ ] `## Migration Plan` lists route keys that do not match the prompt\n- [ ] `## Migration Plan` lists required code obligations that do not match the selected route keys\n- [ ] Source-framework primitives remain in the migrated code\n- [ ] Side effects remain in workflow context\n- [ ] `sleep()` appears inside a step\n- [ ] Stream interaction (`getWriter()`, `write()`, `close()`) appears inside a workflow function\n- [ ] Child workflows call `start()` \u002F `getRun()` directly from workflow context\n- [ ] External writes omit idempotency keys\n- [ ] Hooks\u002Fwebhooks are missing where the source used signals, waitForEvent, or task tokens\n- [ ] A callback-URL flow uses `createHook()` + `resumeHook()` instead of `createWebhook()`\n- [ ] A `resume\u002Furl\u002Fdefault` or `resume\u002Furl\u002Fmanual` migration invents a user-authored callback route or `resumeWebhook()` wrapper when `webhook.url` should be the only resume surface\n- [ ] `createWebhook()` is given a custom `token` or paired with `resumeHook()`\n\nValidation note:\n\n- Reading webhook request data in workflow context is allowed. Only `request.respondWith()` is step-only.\n\nAdditional fail conditions:\n\n- `resume\u002Finternal` output omits `resumeHook()` in app-boundary code\n- `resume\u002Finternal` output omits a deterministic business token\n- `resume\u002Finternal` output emits `createWebhook()` or `webhook.url`\n- `resume\u002Furl\u002Fdefault` output does not pass `webhook.url` to the external system\n- `resume\u002Furl\u002Fdefault` output emits `resumeHook()`, `respondWith: 'manual'`, or `RequestWithResponse` without a custom-response requirement in the prompt\n- `resume\u002Furl\u002Fdefault` output invents a user-authored callback route or `resumeWebhook()` wrapper when `webhook.url` is the intended resume surface\n- `resume\u002Furl\u002Fmanual` output does not pass `webhook.url` to the external system\n- `resume\u002Furl\u002Fmanual` output omits `RequestWithResponse` or `await request.respondWith(...)`\n- `resume\u002Furl\u002Fmanual` output calls `request.respondWith(...)` outside a `\"use step\"` function\n- `resume\u002Furl\u002Fmanual` output invents a user-authored callback route or `resumeWebhook()` wrapper when `webhook.url` is the intended resume surface\n- `createWebhook()` is paired with `resumeHook()`\n- self-hosted output omits `World extends Queue, Streamer, Storage`, `startWorkflowWorld()`, or the explicit note that the workflow and step code can stay the same while the app still needs a custom `World`\n- named-framework output mixes framework syntax with plain `Request` \u002F `Response` app-boundary code without a framework-agnostic override\n\nFor concrete passing code, load:\n\n- `references\u002Fshared-patterns.md` -> `## Generated callback URL (default response)`\n- `references\u002Fshared-patterns.md` -> `## Generated callback URL (manual response)`\n- `references\u002Fruntime-targets.md` -> `## Self-hosted output block`\n- `references\u002Faws-step-functions.md` -> `## Combined recipe: callback URL on self-hosted Hono`\n\n## Sample prompt\n\n```\nMigrate this Inngest workflow to the Workflow SDK.\nIt uses step.waitForEvent() with a timeout and step.realtime.publish().\n```\n\nExpected response shape:\n\n```md\n## Migration Plan\n## Source -> Target Mapping\n## Migrated Code\n## App Boundary \u002F Resume Endpoints\n## Verification Checklist\n## Open Questions\n```\n\n## Example references\n\nLoad a worked example only when the prompt needs concrete code:\n\n- `references\u002Fshared-patterns.md` -> `## Named-framework internal resume example (Hono)`\n- `references\u002Fshared-patterns.md` -> `## Generated callback URL (default response)`\n- `references\u002Fshared-patterns.md` -> `## Generated callback URL (manual response)`\n- `references\u002Fruntime-targets.md` -> `## Self-hosted output block`\n- `references\u002Faws-step-functions.md` -> `## Combined recipe: callback URL on self-hosted Hono`\n\nReject these counterexamples:\n\n- `resume\u002Furl\u002Fdefault` or `resume\u002Furl\u002Fmanual` + user-authored callback route when `webhook.url` is the intended resume surface\n- `createWebhook()` paired with `resumeHook()`\n- named-framework app-boundary output mixed with plain `Request` \u002F `Response` without a framework-agnostic override\n",{"data":32,"body":36},{"name":4,"description":6,"metadata":33},{"author":34,"version":35},"Vercel Inc.","0.2.0",{"type":37,"children":38},"root",[39,48,54,61,189,195,497,545,551,577,582,648,668,674,721,727,807,813,818,912,918,923,1202,1207,1223,1228,1489,1494,1557,1563,1573,1578,1650,1656,1661,1735,1740,1798],{"type":40,"tag":41,"props":42,"children":44},"element","h1",{"id":43},"migrating-to-the-workflow-sdk",[45],{"type":46,"value":47},"text","Migrating to the Workflow SDK",{"type":40,"tag":49,"props":50,"children":51},"p",{},[52],{"type":46,"value":53},"Use this skill when converting an existing orchestration system to the Workflow SDK.",{"type":40,"tag":55,"props":56,"children":58},"h2",{"id":57},"intake",[59],{"type":46,"value":60},"Intake",{"type":40,"tag":62,"props":63,"children":64},"ol",{},[65,95,146],{"type":40,"tag":66,"props":67,"children":68},"li",{},[69,71],{"type":46,"value":70},"Identify the source system:\n",{"type":40,"tag":72,"props":73,"children":74},"ul",{},[75,80,85,90],{"type":40,"tag":66,"props":76,"children":77},{},[78],{"type":46,"value":79},"Temporal",{"type":40,"tag":66,"props":81,"children":82},{},[83],{"type":46,"value":84},"Inngest",{"type":40,"tag":66,"props":86,"children":87},{},[88],{"type":46,"value":89},"Trigger.dev",{"type":40,"tag":66,"props":91,"children":92},{},[93],{"type":46,"value":94},"AWS Step Functions",{"type":40,"tag":66,"props":96,"children":97},{},[98,100],{"type":46,"value":99},"Identify the target runtime:\n",{"type":40,"tag":72,"props":101,"children":102},{},[103,125],{"type":40,"tag":66,"props":104,"children":105},{},[106,108,115,117,123],{"type":46,"value":107},"Managed hosting -> keep examples focused on ",{"type":40,"tag":109,"props":110,"children":112},"code",{"className":111},[],[113],{"type":46,"value":114},"start()",{"type":46,"value":116},", ",{"type":40,"tag":109,"props":118,"children":120},{"className":119},[],[121],{"type":46,"value":122},"getRun()",{"type":46,"value":124},", hooks\u002Fwebhooks, and route handlers.",{"type":40,"tag":66,"props":126,"children":127},{},[128,130,136,138,144],{"type":46,"value":129},"Self-hosted -> also read ",{"type":40,"tag":109,"props":131,"children":133},{"className":132},[],[134],{"type":46,"value":135},"references\u002Fruntime-targets.md",{"type":46,"value":137}," and explicitly say the workflow\u002Fstep code can stay the same, but deployment still needs a ",{"type":40,"tag":109,"props":139,"children":141},{"className":140},[],[142],{"type":46,"value":143},"World",{"type":46,"value":145}," implementation and startup bootstrap.",{"type":40,"tag":66,"props":147,"children":148},{},[149,151],{"type":46,"value":150},"Extract the source constructs:\n",{"type":40,"tag":72,"props":152,"children":153},{},[154,159,164,169,174,179,184],{"type":40,"tag":66,"props":155,"children":156},{},[157],{"type":46,"value":158},"entrypoint",{"type":40,"tag":66,"props":160,"children":161},{},[162],{"type":46,"value":163},"waits \u002F timers",{"type":40,"tag":66,"props":165,"children":166},{},[167],{"type":46,"value":168},"external callbacks \u002F approvals",{"type":40,"tag":66,"props":170,"children":171},{},[172],{"type":46,"value":173},"retries \u002F failure handling",{"type":40,"tag":66,"props":175,"children":176},{},[177],{"type":46,"value":178},"child workflows \u002F fan-out",{"type":40,"tag":66,"props":180,"children":181},{},[182],{"type":46,"value":183},"progress streaming",{"type":40,"tag":66,"props":185,"children":186},{},[187],{"type":46,"value":188},"external side effects",{"type":40,"tag":55,"props":190,"children":192},{"id":191},"default-migration-rules",[193],{"type":46,"value":194},"Default migration rules",{"type":40,"tag":72,"props":196,"children":197},{},[198,211,223,236,351,384,410,422,440,445],{"type":40,"tag":66,"props":199,"children":200},{},[201,203,209],{"type":46,"value":202},"Put orchestration in ",{"type":40,"tag":109,"props":204,"children":206},{"className":205},[],[207],{"type":46,"value":208},"\"use workflow\"",{"type":46,"value":210}," functions.",{"type":40,"tag":66,"props":212,"children":213},{},[214,216,222],{"type":46,"value":215},"Put side effects, SDK calls, DB calls, HTTP calls, and stream I\u002FO in ",{"type":40,"tag":109,"props":217,"children":219},{"className":218},[],[220],{"type":46,"value":221},"\"use step\"",{"type":46,"value":210},{"type":40,"tag":66,"props":224,"children":225},{},[226,228,234],{"type":46,"value":227},"Use ",{"type":40,"tag":109,"props":229,"children":231},{"className":230},[],[232],{"type":46,"value":233},"sleep()",{"type":46,"value":235}," only in workflow context.",{"type":40,"tag":66,"props":237,"children":238},{},[239,241,247,249,255,257],{"type":46,"value":240},"For Signals, ",{"type":40,"tag":109,"props":242,"children":244},{"className":243},[],[245],{"type":46,"value":246},"step.waitForEvent()",{"type":46,"value":248},", and ",{"type":40,"tag":109,"props":250,"children":252},{"className":251},[],[253],{"type":46,"value":254},".waitForTaskToken",{"type":46,"value":256},", choose exactly one resume surface:\n",{"type":40,"tag":72,"props":258,"children":259},{},[260,287,313,331],{"type":40,"tag":66,"props":261,"children":262},{},[263,269,271,277,279,285],{"type":40,"tag":109,"props":264,"children":266},{"className":265},[],[267],{"type":46,"value":268},"resume\u002Finternal",{"type":46,"value":270}," -> ",{"type":40,"tag":109,"props":272,"children":274},{"className":273},[],[275],{"type":46,"value":276},"createHook()",{"type":46,"value":278}," + ",{"type":40,"tag":109,"props":280,"children":282},{"className":281},[],[283],{"type":46,"value":284},"resumeHook()",{"type":46,"value":286}," when the app resumes from server-side code with a deterministic business token.",{"type":40,"tag":66,"props":288,"children":289},{},[290,296,297,303,305,311],{"type":40,"tag":109,"props":291,"children":293},{"className":292},[],[294],{"type":46,"value":295},"resume\u002Furl\u002Fdefault",{"type":46,"value":270},{"type":40,"tag":109,"props":298,"children":300},{"className":299},[],[301],{"type":46,"value":302},"createWebhook()",{"type":46,"value":304}," when the external system needs a generated callback URL and the default ",{"type":40,"tag":109,"props":306,"children":308},{"className":307},[],[309],{"type":46,"value":310},"202 Accepted",{"type":46,"value":312}," response is fine.",{"type":40,"tag":66,"props":314,"children":315},{},[316,322,323,329],{"type":40,"tag":109,"props":317,"children":319},{"className":318},[],[320],{"type":46,"value":321},"resume\u002Furl\u002Fmanual",{"type":46,"value":270},{"type":40,"tag":109,"props":324,"children":326},{"className":325},[],[327],{"type":46,"value":328},"createWebhook({ respondWith: 'manual' })",{"type":46,"value":330}," only when the prompt explicitly requires a custom response body, status, or headers.",{"type":40,"tag":66,"props":332,"children":333},{},[334,336,341,343,349],{"type":46,"value":335},"If a callback-URL prompt does not specify response semantics, default to ",{"type":40,"tag":109,"props":337,"children":339},{"className":338},[],[340],{"type":46,"value":295},{"type":46,"value":342}," and make the assumption explicit in ",{"type":40,"tag":109,"props":344,"children":346},{"className":345},[],[347],{"type":46,"value":348},"## Open Questions",{"type":46,"value":350},".",{"type":40,"tag":66,"props":352,"children":353},{},[354,356,361,363,368,370,376,378,383],{"type":46,"value":355},"Never pair ",{"type":40,"tag":109,"props":357,"children":359},{"className":358},[],[360],{"type":46,"value":302},{"type":46,"value":362}," with ",{"type":40,"tag":109,"props":364,"children":366},{"className":365},[],[367],{"type":46,"value":284},{"type":46,"value":369},", and never pass ",{"type":40,"tag":109,"props":371,"children":373},{"className":372},[],[374],{"type":46,"value":375},"token:",{"type":46,"value":377}," to ",{"type":40,"tag":109,"props":379,"children":381},{"className":380},[],[382],{"type":46,"value":302},{"type":46,"value":350},{"type":40,"tag":66,"props":385,"children":386},{},[387,389,394,396,401,403,408],{"type":46,"value":388},"Wrap ",{"type":40,"tag":109,"props":390,"children":392},{"className":391},[],[393],{"type":46,"value":114},{"type":46,"value":395}," and ",{"type":40,"tag":109,"props":397,"children":399},{"className":398},[],[400],{"type":46,"value":122},{"type":46,"value":402}," inside ",{"type":40,"tag":109,"props":404,"children":406},{"className":405},[],[407],{"type":46,"value":221},{"type":46,"value":409}," functions for child runs.",{"type":40,"tag":66,"props":411,"children":412},{},[413,414,420],{"type":46,"value":227},{"type":40,"tag":109,"props":415,"children":417},{"className":416},[],[418],{"type":46,"value":419},"getStepMetadata().stepId",{"type":46,"value":421}," as the idempotency key for external writes.",{"type":40,"tag":66,"props":423,"children":424},{},[425,426,432,434,439],{"type":46,"value":227},{"type":40,"tag":109,"props":427,"children":429},{"className":428},[],[430],{"type":46,"value":431},"getWritable()",{"type":46,"value":433}," in workflow context to obtain the stream, but interact with it (write, close) only inside ",{"type":40,"tag":109,"props":435,"children":437},{"className":436},[],[438],{"type":46,"value":221},{"type":46,"value":210},{"type":40,"tag":66,"props":441,"children":442},{},[443],{"type":46,"value":444},"Prefer rollback stacks for multi-step compensation.",{"type":40,"tag":66,"props":446,"children":447},{},[448,450],{"type":46,"value":449},"Choose app-boundary syntax in this order:\n",{"type":40,"tag":62,"props":451,"children":452},{},[453,474,479],{"type":40,"tag":66,"props":454,"children":455},{},[456,458,464,466,472],{"type":46,"value":457},"If the prompt explicitly asks for framework-agnostic app-boundary code, use plain ",{"type":40,"tag":109,"props":459,"children":461},{"className":460},[],[462],{"type":46,"value":463},"Request",{"type":46,"value":465}," \u002F ",{"type":40,"tag":109,"props":467,"children":469},{"className":468},[],[470],{"type":46,"value":471},"Response",{"type":46,"value":473}," even when a framework like Hono is named.",{"type":40,"tag":66,"props":475,"children":476},{},[477],{"type":46,"value":478},"Otherwise, if the target framework is named, shape app-boundary examples to that framework.",{"type":40,"tag":66,"props":480,"children":481},{},[482,484,489,490,495],{"type":46,"value":483},"Otherwise, keep examples framework-agnostic with ",{"type":40,"tag":109,"props":485,"children":487},{"className":486},[],[488],{"type":46,"value":463},{"type":46,"value":465},{"type":40,"tag":109,"props":491,"children":493},{"className":492},[],[494],{"type":46,"value":471},{"type":46,"value":496},". Do not default to Next.js-only route signatures unless Next.js is explicitly named.",{"type":40,"tag":498,"props":499,"children":500},"blockquote",{},[501,506],{"type":40,"tag":49,"props":502,"children":503},{},[504],{"type":46,"value":505},"Fast memory aid:",{"type":40,"tag":72,"props":507,"children":508},{},[509,519,529],{"type":40,"tag":66,"props":510,"children":511},{},[512,514],{"type":46,"value":513},"Callback URL + default ack -> ",{"type":40,"tag":109,"props":515,"children":517},{"className":516},[],[518],{"type":46,"value":302},{"type":40,"tag":66,"props":520,"children":521},{},[522,524],{"type":46,"value":523},"Callback URL + custom ack -> ",{"type":40,"tag":109,"props":525,"children":527},{"className":526},[],[528],{"type":46,"value":328},{"type":40,"tag":66,"props":530,"children":531},{},[532,534,539,540],{"type":46,"value":533},"Deterministic server-side resume -> ",{"type":40,"tag":109,"props":535,"children":537},{"className":536},[],[538],{"type":46,"value":276},{"type":46,"value":278},{"type":40,"tag":109,"props":541,"children":543},{"className":542},[],[544],{"type":46,"value":284},{"type":40,"tag":55,"props":546,"children":548},{"id":547},"fast-path-router",[549],{"type":46,"value":550},"Fast-path router",{"type":40,"tag":49,"props":552,"children":553},{},[554,556,562,564,569,571,576],{"type":46,"value":555},"Load ",{"type":40,"tag":109,"props":557,"children":559},{"className":558},[],[560],{"type":46,"value":561},"references\u002Fresume-routing.md",{"type":46,"value":563}," when the source pauses for Signals, ",{"type":40,"tag":109,"props":565,"children":567},{"className":566},[],[568],{"type":46,"value":246},{"type":46,"value":570},", or ",{"type":40,"tag":109,"props":572,"children":574},{"className":573},[],[575],{"type":46,"value":254},{"type":46,"value":350},{"type":40,"tag":49,"props":578,"children":579},{},[580],{"type":46,"value":581},"Fast defaults:",{"type":40,"tag":72,"props":583,"children":584},{},[585,595,605,615,626,637],{"type":40,"tag":66,"props":586,"children":587},{},[588,590],{"type":46,"value":589},"callback URL only -> ",{"type":40,"tag":109,"props":591,"children":593},{"className":592},[],[594],{"type":46,"value":295},{"type":40,"tag":66,"props":596,"children":597},{},[598,600],{"type":46,"value":599},"callback URL + explicit custom response -> ",{"type":40,"tag":109,"props":601,"children":603},{"className":602},[],[604],{"type":46,"value":321},{"type":40,"tag":66,"props":606,"children":607},{},[608,610],{"type":46,"value":609},"deterministic server-side resume -> ",{"type":40,"tag":109,"props":611,"children":613},{"className":612},[],[614],{"type":46,"value":268},{"type":40,"tag":66,"props":616,"children":617},{},[618,620],{"type":46,"value":619},"self-hosted -> add ",{"type":40,"tag":109,"props":621,"children":623},{"className":622},[],[624],{"type":46,"value":625},"runtime\u002Fself-hosted",{"type":40,"tag":66,"props":627,"children":628},{},[629,631],{"type":46,"value":630},"named framework -> add ",{"type":40,"tag":109,"props":632,"children":634},{"className":633},[],[635],{"type":46,"value":636},"boundary\u002Fnamed-framework",{"type":40,"tag":66,"props":638,"children":639},{},[640,642],{"type":46,"value":641},"explicit framework-agnostic request -> add ",{"type":40,"tag":109,"props":643,"children":645},{"className":644},[],[646],{"type":46,"value":647},"boundary\u002Fframework-agnostic",{"type":40,"tag":49,"props":649,"children":650},{},[651,653,659,661,667],{"type":46,"value":652},"Before drafting ",{"type":40,"tag":109,"props":654,"children":656},{"className":655},[],[657],{"type":46,"value":658},"## Migrated Code",{"type":46,"value":660},", write the selected route keys in ",{"type":40,"tag":109,"props":662,"children":664},{"className":663},[],[665],{"type":46,"value":666},"## Migration Plan",{"type":46,"value":350},{"type":40,"tag":55,"props":669,"children":671},{"id":670},"source-references",[672],{"type":46,"value":673},"Source references",{"type":40,"tag":72,"props":675,"children":676},{},[677,688,699,710],{"type":40,"tag":66,"props":678,"children":679},{},[680,682],{"type":46,"value":681},"Temporal -> ",{"type":40,"tag":109,"props":683,"children":685},{"className":684},[],[686],{"type":46,"value":687},"references\u002Ftemporal.md",{"type":40,"tag":66,"props":689,"children":690},{},[691,693],{"type":46,"value":692},"Inngest -> ",{"type":40,"tag":109,"props":694,"children":696},{"className":695},[],[697],{"type":46,"value":698},"references\u002Finngest.md",{"type":40,"tag":66,"props":700,"children":701},{},[702,704],{"type":46,"value":703},"Trigger.dev -> ",{"type":40,"tag":109,"props":705,"children":707},{"className":706},[],[708],{"type":46,"value":709},"references\u002Ftrigger-dev.md",{"type":40,"tag":66,"props":711,"children":712},{},[713,715],{"type":46,"value":714},"AWS Step Functions -> ",{"type":40,"tag":109,"props":716,"children":718},{"className":717},[],[719],{"type":46,"value":720},"references\u002Faws-step-functions.md",{"type":40,"tag":55,"props":722,"children":724},{"id":723},"shared-references",[725],{"type":46,"value":726},"Shared references",{"type":40,"tag":72,"props":728,"children":729},{},[730,741,758,775],{"type":40,"tag":66,"props":731,"children":732},{},[733,739],{"type":40,"tag":109,"props":734,"children":736},{"className":735},[],[737],{"type":46,"value":738},"references\u002Fshared-patterns.md",{"type":46,"value":740}," — reusable code templates for hooks, child workflows, idempotency, streaming, and rollback.",{"type":40,"tag":66,"props":742,"children":743},{},[744,749,751,756],{"type":40,"tag":109,"props":745,"children":747},{"className":746},[],[748],{"type":46,"value":135},{"type":46,"value":750}," — Managed vs custom ",{"type":40,"tag":109,"props":752,"children":754},{"className":753},[],[755],{"type":46,"value":143},{"type":46,"value":757}," guidance.",{"type":40,"tag":66,"props":759,"children":760},{},[761,766,768,773],{"type":40,"tag":109,"props":762,"children":764},{"className":763},[],[765],{"type":46,"value":561},{"type":46,"value":767}," — route-key selection, obligations, and exact ",{"type":40,"tag":109,"props":769,"children":771},{"className":770},[],[772],{"type":46,"value":666},{"type":46,"value":774}," shape.",{"type":40,"tag":66,"props":776,"children":777},{},[778,784,786,792,793,799,800,806],{"type":40,"tag":109,"props":779,"children":781},{"className":780},[],[782],{"type":46,"value":783},"references\u002Fretries.md",{"type":46,"value":785}," — canonical retry mechanics: ",{"type":40,"tag":109,"props":787,"children":789},{"className":788},[],[790],{"type":46,"value":791},"stepFn.maxRetries",{"type":46,"value":116},{"type":40,"tag":109,"props":794,"children":796},{"className":795},[],[797],{"type":46,"value":798},"RetryableError({ retryAfter })",{"type":46,"value":116},{"type":40,"tag":109,"props":801,"children":803},{"className":802},[],[804],{"type":46,"value":805},"FatalError",{"type":46,"value":350},{"type":40,"tag":55,"props":808,"children":810},{"id":809},"required-output-shape",[811],{"type":46,"value":812},"Required output shape",{"type":40,"tag":49,"props":814,"children":815},{},[816],{"type":46,"value":817},"Return the migration in this structure:",{"type":40,"tag":819,"props":820,"children":825},"pre",{"className":821,"code":822,"language":823,"meta":824,"style":824},"language-md shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","## Migration Plan\n## Source -> Target Mapping\n## Migrated Code\n## App Boundary \u002F Resume Endpoints\n## Verification Checklist\n## Open Questions\n","md","",[826],{"type":40,"tag":109,"props":827,"children":828},{"__ignoreMap":824},[829,847,860,873,886,899],{"type":40,"tag":830,"props":831,"children":834},"span",{"class":832,"line":833},"line",1,[835,841],{"type":40,"tag":830,"props":836,"children":838},{"style":837},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[839],{"type":46,"value":840},"## ",{"type":40,"tag":830,"props":842,"children":844},{"style":843},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[845],{"type":46,"value":846},"Migration Plan\n",{"type":40,"tag":830,"props":848,"children":850},{"class":832,"line":849},2,[851,855],{"type":40,"tag":830,"props":852,"children":853},{"style":837},[854],{"type":46,"value":840},{"type":40,"tag":830,"props":856,"children":857},{"style":843},[858],{"type":46,"value":859},"Source -> Target Mapping\n",{"type":40,"tag":830,"props":861,"children":863},{"class":832,"line":862},3,[864,868],{"type":40,"tag":830,"props":865,"children":866},{"style":837},[867],{"type":46,"value":840},{"type":40,"tag":830,"props":869,"children":870},{"style":843},[871],{"type":46,"value":872},"Migrated Code\n",{"type":40,"tag":830,"props":874,"children":876},{"class":832,"line":875},4,[877,881],{"type":40,"tag":830,"props":878,"children":879},{"style":837},[880],{"type":46,"value":840},{"type":40,"tag":830,"props":882,"children":883},{"style":843},[884],{"type":46,"value":885},"App Boundary \u002F Resume Endpoints\n",{"type":40,"tag":830,"props":887,"children":889},{"class":832,"line":888},5,[890,894],{"type":40,"tag":830,"props":891,"children":892},{"style":837},[893],{"type":46,"value":840},{"type":40,"tag":830,"props":895,"children":896},{"style":843},[897],{"type":46,"value":898},"Verification Checklist\n",{"type":40,"tag":830,"props":900,"children":902},{"class":832,"line":901},6,[903,907],{"type":40,"tag":830,"props":904,"children":905},{"style":837},[906],{"type":46,"value":840},{"type":40,"tag":830,"props":908,"children":909},{"style":843},[910],{"type":46,"value":911},"Open Questions\n",{"type":40,"tag":55,"props":913,"children":915},{"id":914},"verification-checklist",[916],{"type":46,"value":917},"Verification checklist",{"type":40,"tag":49,"props":919,"children":920},{},[921],{"type":46,"value":922},"Fail the draft if any of these are true:",{"type":40,"tag":72,"props":924,"children":927},{"className":925},[926],"contains-task-list",[928,954,974,989,1004,1013,1022,1037,1068,1090,1099,1108,1135,1174],{"type":40,"tag":66,"props":929,"children":932},{"className":930},[931],"task-list-item",[933,939,941,946,948],{"type":40,"tag":934,"props":935,"children":938},"input",{"disabled":936,"type":937},true,"checkbox",[],{"type":46,"value":940}," ",{"type":40,"tag":109,"props":942,"children":944},{"className":943},[],[945],{"type":46,"value":666},{"type":46,"value":947}," omits ",{"type":40,"tag":109,"props":949,"children":951},{"className":950},[],[952],{"type":46,"value":953},"Route keys",{"type":40,"tag":66,"props":955,"children":957},{"className":956},[931],[958,961,962,967,968],{"type":40,"tag":934,"props":959,"children":960},{"disabled":936,"type":937},[],{"type":46,"value":940},{"type":40,"tag":109,"props":963,"children":965},{"className":964},[],[966],{"type":46,"value":666},{"type":46,"value":947},{"type":40,"tag":109,"props":969,"children":971},{"className":970},[],[972],{"type":46,"value":973},"Why these route keys",{"type":40,"tag":66,"props":975,"children":977},{"className":976},[931],[978,981,982,987],{"type":40,"tag":934,"props":979,"children":980},{"disabled":936,"type":937},[],{"type":46,"value":940},{"type":40,"tag":109,"props":983,"children":985},{"className":984},[],[986],{"type":46,"value":666},{"type":46,"value":988}," lists route keys that do not match the prompt",{"type":40,"tag":66,"props":990,"children":992},{"className":991},[931],[993,996,997,1002],{"type":40,"tag":934,"props":994,"children":995},{"disabled":936,"type":937},[],{"type":46,"value":940},{"type":40,"tag":109,"props":998,"children":1000},{"className":999},[],[1001],{"type":46,"value":666},{"type":46,"value":1003}," lists required code obligations that do not match the selected route keys",{"type":40,"tag":66,"props":1005,"children":1007},{"className":1006},[931],[1008,1011],{"type":40,"tag":934,"props":1009,"children":1010},{"disabled":936,"type":937},[],{"type":46,"value":1012}," Source-framework primitives remain in the migrated code",{"type":40,"tag":66,"props":1014,"children":1016},{"className":1015},[931],[1017,1020],{"type":40,"tag":934,"props":1018,"children":1019},{"disabled":936,"type":937},[],{"type":46,"value":1021}," Side effects remain in workflow context",{"type":40,"tag":66,"props":1023,"children":1025},{"className":1024},[931],[1026,1029,1030,1035],{"type":40,"tag":934,"props":1027,"children":1028},{"disabled":936,"type":937},[],{"type":46,"value":940},{"type":40,"tag":109,"props":1031,"children":1033},{"className":1032},[],[1034],{"type":46,"value":233},{"type":46,"value":1036}," appears inside a step",{"type":40,"tag":66,"props":1038,"children":1040},{"className":1039},[931],[1041,1044,1046,1052,1053,1059,1060,1066],{"type":40,"tag":934,"props":1042,"children":1043},{"disabled":936,"type":937},[],{"type":46,"value":1045}," Stream interaction (",{"type":40,"tag":109,"props":1047,"children":1049},{"className":1048},[],[1050],{"type":46,"value":1051},"getWriter()",{"type":46,"value":116},{"type":40,"tag":109,"props":1054,"children":1056},{"className":1055},[],[1057],{"type":46,"value":1058},"write()",{"type":46,"value":116},{"type":40,"tag":109,"props":1061,"children":1063},{"className":1062},[],[1064],{"type":46,"value":1065},"close()",{"type":46,"value":1067},") appears inside a workflow function",{"type":40,"tag":66,"props":1069,"children":1071},{"className":1070},[931],[1072,1075,1077,1082,1083,1088],{"type":40,"tag":934,"props":1073,"children":1074},{"disabled":936,"type":937},[],{"type":46,"value":1076}," Child workflows call ",{"type":40,"tag":109,"props":1078,"children":1080},{"className":1079},[],[1081],{"type":46,"value":114},{"type":46,"value":465},{"type":40,"tag":109,"props":1084,"children":1086},{"className":1085},[],[1087],{"type":46,"value":122},{"type":46,"value":1089}," directly from workflow context",{"type":40,"tag":66,"props":1091,"children":1093},{"className":1092},[931],[1094,1097],{"type":40,"tag":934,"props":1095,"children":1096},{"disabled":936,"type":937},[],{"type":46,"value":1098}," External writes omit idempotency keys",{"type":40,"tag":66,"props":1100,"children":1102},{"className":1101},[931],[1103,1106],{"type":40,"tag":934,"props":1104,"children":1105},{"disabled":936,"type":937},[],{"type":46,"value":1107}," Hooks\u002Fwebhooks are missing where the source used signals, waitForEvent, or task tokens",{"type":40,"tag":66,"props":1109,"children":1111},{"className":1110},[931],[1112,1115,1117,1122,1123,1128,1130],{"type":40,"tag":934,"props":1113,"children":1114},{"disabled":936,"type":937},[],{"type":46,"value":1116}," A callback-URL flow uses ",{"type":40,"tag":109,"props":1118,"children":1120},{"className":1119},[],[1121],{"type":46,"value":276},{"type":46,"value":278},{"type":40,"tag":109,"props":1124,"children":1126},{"className":1125},[],[1127],{"type":46,"value":284},{"type":46,"value":1129}," instead of ",{"type":40,"tag":109,"props":1131,"children":1133},{"className":1132},[],[1134],{"type":46,"value":302},{"type":40,"tag":66,"props":1136,"children":1138},{"className":1137},[931],[1139,1142,1144,1149,1151,1156,1158,1164,1166,1172],{"type":40,"tag":934,"props":1140,"children":1141},{"disabled":936,"type":937},[],{"type":46,"value":1143}," A ",{"type":40,"tag":109,"props":1145,"children":1147},{"className":1146},[],[1148],{"type":46,"value":295},{"type":46,"value":1150}," or ",{"type":40,"tag":109,"props":1152,"children":1154},{"className":1153},[],[1155],{"type":46,"value":321},{"type":46,"value":1157}," migration invents a user-authored callback route or ",{"type":40,"tag":109,"props":1159,"children":1161},{"className":1160},[],[1162],{"type":46,"value":1163},"resumeWebhook()",{"type":46,"value":1165}," wrapper when ",{"type":40,"tag":109,"props":1167,"children":1169},{"className":1168},[],[1170],{"type":46,"value":1171},"webhook.url",{"type":46,"value":1173}," should be the only resume surface",{"type":40,"tag":66,"props":1175,"children":1177},{"className":1176},[931],[1178,1181,1182,1187,1189,1195,1197],{"type":40,"tag":934,"props":1179,"children":1180},{"disabled":936,"type":937},[],{"type":46,"value":940},{"type":40,"tag":109,"props":1183,"children":1185},{"className":1184},[],[1186],{"type":46,"value":302},{"type":46,"value":1188}," is given a custom ",{"type":40,"tag":109,"props":1190,"children":1192},{"className":1191},[],[1193],{"type":46,"value":1194},"token",{"type":46,"value":1196}," or paired with ",{"type":40,"tag":109,"props":1198,"children":1200},{"className":1199},[],[1201],{"type":46,"value":284},{"type":40,"tag":49,"props":1203,"children":1204},{},[1205],{"type":46,"value":1206},"Validation note:",{"type":40,"tag":72,"props":1208,"children":1209},{},[1210],{"type":40,"tag":66,"props":1211,"children":1212},{},[1213,1215,1221],{"type":46,"value":1214},"Reading webhook request data in workflow context is allowed. Only ",{"type":40,"tag":109,"props":1216,"children":1218},{"className":1217},[],[1219],{"type":46,"value":1220},"request.respondWith()",{"type":46,"value":1222}," is step-only.",{"type":40,"tag":49,"props":1224,"children":1225},{},[1226],{"type":46,"value":1227},"Additional fail conditions:",{"type":40,"tag":72,"props":1229,"children":1230},{},[1231,1248,1258,1279,1296,1326,1349,1364,1385,1410,1431,1446,1471],{"type":40,"tag":66,"props":1232,"children":1233},{},[1234,1239,1241,1246],{"type":40,"tag":109,"props":1235,"children":1237},{"className":1236},[],[1238],{"type":46,"value":268},{"type":46,"value":1240}," output omits ",{"type":40,"tag":109,"props":1242,"children":1244},{"className":1243},[],[1245],{"type":46,"value":284},{"type":46,"value":1247}," in app-boundary code",{"type":40,"tag":66,"props":1249,"children":1250},{},[1251,1256],{"type":40,"tag":109,"props":1252,"children":1254},{"className":1253},[],[1255],{"type":46,"value":268},{"type":46,"value":1257}," output omits a deterministic business token",{"type":40,"tag":66,"props":1259,"children":1260},{},[1261,1266,1268,1273,1274],{"type":40,"tag":109,"props":1262,"children":1264},{"className":1263},[],[1265],{"type":46,"value":268},{"type":46,"value":1267}," output emits ",{"type":40,"tag":109,"props":1269,"children":1271},{"className":1270},[],[1272],{"type":46,"value":302},{"type":46,"value":1150},{"type":40,"tag":109,"props":1275,"children":1277},{"className":1276},[],[1278],{"type":46,"value":1171},{"type":40,"tag":66,"props":1280,"children":1281},{},[1282,1287,1289,1294],{"type":40,"tag":109,"props":1283,"children":1285},{"className":1284},[],[1286],{"type":46,"value":295},{"type":46,"value":1288}," output does not pass ",{"type":40,"tag":109,"props":1290,"children":1292},{"className":1291},[],[1293],{"type":46,"value":1171},{"type":46,"value":1295}," to the external system",{"type":40,"tag":66,"props":1297,"children":1298},{},[1299,1304,1305,1310,1311,1317,1318,1324],{"type":40,"tag":109,"props":1300,"children":1302},{"className":1301},[],[1303],{"type":46,"value":295},{"type":46,"value":1267},{"type":40,"tag":109,"props":1306,"children":1308},{"className":1307},[],[1309],{"type":46,"value":284},{"type":46,"value":116},{"type":40,"tag":109,"props":1312,"children":1314},{"className":1313},[],[1315],{"type":46,"value":1316},"respondWith: 'manual'",{"type":46,"value":570},{"type":40,"tag":109,"props":1319,"children":1321},{"className":1320},[],[1322],{"type":46,"value":1323},"RequestWithResponse",{"type":46,"value":1325}," without a custom-response requirement in the prompt",{"type":40,"tag":66,"props":1327,"children":1328},{},[1329,1334,1336,1341,1342,1347],{"type":40,"tag":109,"props":1330,"children":1332},{"className":1331},[],[1333],{"type":46,"value":295},{"type":46,"value":1335}," output invents a user-authored callback route or ",{"type":40,"tag":109,"props":1337,"children":1339},{"className":1338},[],[1340],{"type":46,"value":1163},{"type":46,"value":1165},{"type":40,"tag":109,"props":1343,"children":1345},{"className":1344},[],[1346],{"type":46,"value":1171},{"type":46,"value":1348}," is the intended resume surface",{"type":40,"tag":66,"props":1350,"children":1351},{},[1352,1357,1358,1363],{"type":40,"tag":109,"props":1353,"children":1355},{"className":1354},[],[1356],{"type":46,"value":321},{"type":46,"value":1288},{"type":40,"tag":109,"props":1359,"children":1361},{"className":1360},[],[1362],{"type":46,"value":1171},{"type":46,"value":1295},{"type":40,"tag":66,"props":1365,"children":1366},{},[1367,1372,1373,1378,1379],{"type":40,"tag":109,"props":1368,"children":1370},{"className":1369},[],[1371],{"type":46,"value":321},{"type":46,"value":1240},{"type":40,"tag":109,"props":1374,"children":1376},{"className":1375},[],[1377],{"type":46,"value":1323},{"type":46,"value":1150},{"type":40,"tag":109,"props":1380,"children":1382},{"className":1381},[],[1383],{"type":46,"value":1384},"await request.respondWith(...)",{"type":40,"tag":66,"props":1386,"children":1387},{},[1388,1393,1395,1401,1403,1408],{"type":40,"tag":109,"props":1389,"children":1391},{"className":1390},[],[1392],{"type":46,"value":321},{"type":46,"value":1394}," output calls ",{"type":40,"tag":109,"props":1396,"children":1398},{"className":1397},[],[1399],{"type":46,"value":1400},"request.respondWith(...)",{"type":46,"value":1402}," outside a ",{"type":40,"tag":109,"props":1404,"children":1406},{"className":1405},[],[1407],{"type":46,"value":221},{"type":46,"value":1409}," function",{"type":40,"tag":66,"props":1411,"children":1412},{},[1413,1418,1419,1424,1425,1430],{"type":40,"tag":109,"props":1414,"children":1416},{"className":1415},[],[1417],{"type":46,"value":321},{"type":46,"value":1335},{"type":40,"tag":109,"props":1420,"children":1422},{"className":1421},[],[1423],{"type":46,"value":1163},{"type":46,"value":1165},{"type":40,"tag":109,"props":1426,"children":1428},{"className":1427},[],[1429],{"type":46,"value":1171},{"type":46,"value":1348},{"type":40,"tag":66,"props":1432,"children":1433},{},[1434,1439,1441],{"type":40,"tag":109,"props":1435,"children":1437},{"className":1436},[],[1438],{"type":46,"value":302},{"type":46,"value":1440}," is paired with ",{"type":40,"tag":109,"props":1442,"children":1444},{"className":1443},[],[1445],{"type":46,"value":284},{"type":40,"tag":66,"props":1447,"children":1448},{},[1449,1451,1457,1458,1464,1466],{"type":46,"value":1450},"self-hosted output omits ",{"type":40,"tag":109,"props":1452,"children":1454},{"className":1453},[],[1455],{"type":46,"value":1456},"World extends Queue, Streamer, Storage",{"type":46,"value":116},{"type":40,"tag":109,"props":1459,"children":1461},{"className":1460},[],[1462],{"type":46,"value":1463},"startWorkflowWorld()",{"type":46,"value":1465},", or the explicit note that the workflow and step code can stay the same while the app still needs a custom ",{"type":40,"tag":109,"props":1467,"children":1469},{"className":1468},[],[1470],{"type":46,"value":143},{"type":40,"tag":66,"props":1472,"children":1473},{},[1474,1476,1481,1482,1487],{"type":46,"value":1475},"named-framework output mixes framework syntax with plain ",{"type":40,"tag":109,"props":1477,"children":1479},{"className":1478},[],[1480],{"type":46,"value":463},{"type":46,"value":465},{"type":40,"tag":109,"props":1483,"children":1485},{"className":1484},[],[1486],{"type":46,"value":471},{"type":46,"value":1488}," app-boundary code without a framework-agnostic override",{"type":40,"tag":49,"props":1490,"children":1491},{},[1492],{"type":46,"value":1493},"For concrete passing code, load:",{"type":40,"tag":72,"props":1495,"children":1496},{},[1497,1512,1527,1542],{"type":40,"tag":66,"props":1498,"children":1499},{},[1500,1505,1506],{"type":40,"tag":109,"props":1501,"children":1503},{"className":1502},[],[1504],{"type":46,"value":738},{"type":46,"value":270},{"type":40,"tag":109,"props":1507,"children":1509},{"className":1508},[],[1510],{"type":46,"value":1511},"## Generated callback URL (default response)",{"type":40,"tag":66,"props":1513,"children":1514},{},[1515,1520,1521],{"type":40,"tag":109,"props":1516,"children":1518},{"className":1517},[],[1519],{"type":46,"value":738},{"type":46,"value":270},{"type":40,"tag":109,"props":1522,"children":1524},{"className":1523},[],[1525],{"type":46,"value":1526},"## Generated callback URL (manual response)",{"type":40,"tag":66,"props":1528,"children":1529},{},[1530,1535,1536],{"type":40,"tag":109,"props":1531,"children":1533},{"className":1532},[],[1534],{"type":46,"value":135},{"type":46,"value":270},{"type":40,"tag":109,"props":1537,"children":1539},{"className":1538},[],[1540],{"type":46,"value":1541},"## Self-hosted output block",{"type":40,"tag":66,"props":1543,"children":1544},{},[1545,1550,1551],{"type":40,"tag":109,"props":1546,"children":1548},{"className":1547},[],[1549],{"type":46,"value":720},{"type":46,"value":270},{"type":40,"tag":109,"props":1552,"children":1554},{"className":1553},[],[1555],{"type":46,"value":1556},"## Combined recipe: callback URL on self-hosted Hono",{"type":40,"tag":55,"props":1558,"children":1560},{"id":1559},"sample-prompt",[1561],{"type":46,"value":1562},"Sample prompt",{"type":40,"tag":819,"props":1564,"children":1568},{"className":1565,"code":1567,"language":46},[1566],"language-text","Migrate this Inngest workflow to the Workflow SDK.\nIt uses step.waitForEvent() with a timeout and step.realtime.publish().\n",[1569],{"type":40,"tag":109,"props":1570,"children":1571},{"__ignoreMap":824},[1572],{"type":46,"value":1567},{"type":40,"tag":49,"props":1574,"children":1575},{},[1576],{"type":46,"value":1577},"Expected response shape:",{"type":40,"tag":819,"props":1579,"children":1580},{"className":821,"code":822,"language":823,"meta":824,"style":824},[1581],{"type":40,"tag":109,"props":1582,"children":1583},{"__ignoreMap":824},[1584,1595,1606,1617,1628,1639],{"type":40,"tag":830,"props":1585,"children":1586},{"class":832,"line":833},[1587,1591],{"type":40,"tag":830,"props":1588,"children":1589},{"style":837},[1590],{"type":46,"value":840},{"type":40,"tag":830,"props":1592,"children":1593},{"style":843},[1594],{"type":46,"value":846},{"type":40,"tag":830,"props":1596,"children":1597},{"class":832,"line":849},[1598,1602],{"type":40,"tag":830,"props":1599,"children":1600},{"style":837},[1601],{"type":46,"value":840},{"type":40,"tag":830,"props":1603,"children":1604},{"style":843},[1605],{"type":46,"value":859},{"type":40,"tag":830,"props":1607,"children":1608},{"class":832,"line":862},[1609,1613],{"type":40,"tag":830,"props":1610,"children":1611},{"style":837},[1612],{"type":46,"value":840},{"type":40,"tag":830,"props":1614,"children":1615},{"style":843},[1616],{"type":46,"value":872},{"type":40,"tag":830,"props":1618,"children":1619},{"class":832,"line":875},[1620,1624],{"type":40,"tag":830,"props":1621,"children":1622},{"style":837},[1623],{"type":46,"value":840},{"type":40,"tag":830,"props":1625,"children":1626},{"style":843},[1627],{"type":46,"value":885},{"type":40,"tag":830,"props":1629,"children":1630},{"class":832,"line":888},[1631,1635],{"type":40,"tag":830,"props":1632,"children":1633},{"style":837},[1634],{"type":46,"value":840},{"type":40,"tag":830,"props":1636,"children":1637},{"style":843},[1638],{"type":46,"value":898},{"type":40,"tag":830,"props":1640,"children":1641},{"class":832,"line":901},[1642,1646],{"type":40,"tag":830,"props":1643,"children":1644},{"style":837},[1645],{"type":46,"value":840},{"type":40,"tag":830,"props":1647,"children":1648},{"style":843},[1649],{"type":46,"value":911},{"type":40,"tag":55,"props":1651,"children":1653},{"id":1652},"example-references",[1654],{"type":46,"value":1655},"Example references",{"type":40,"tag":49,"props":1657,"children":1658},{},[1659],{"type":46,"value":1660},"Load a worked example only when the prompt needs concrete code:",{"type":40,"tag":72,"props":1662,"children":1663},{},[1664,1679,1693,1707,1721],{"type":40,"tag":66,"props":1665,"children":1666},{},[1667,1672,1673],{"type":40,"tag":109,"props":1668,"children":1670},{"className":1669},[],[1671],{"type":46,"value":738},{"type":46,"value":270},{"type":40,"tag":109,"props":1674,"children":1676},{"className":1675},[],[1677],{"type":46,"value":1678},"## Named-framework internal resume example (Hono)",{"type":40,"tag":66,"props":1680,"children":1681},{},[1682,1687,1688],{"type":40,"tag":109,"props":1683,"children":1685},{"className":1684},[],[1686],{"type":46,"value":738},{"type":46,"value":270},{"type":40,"tag":109,"props":1689,"children":1691},{"className":1690},[],[1692],{"type":46,"value":1511},{"type":40,"tag":66,"props":1694,"children":1695},{},[1696,1701,1702],{"type":40,"tag":109,"props":1697,"children":1699},{"className":1698},[],[1700],{"type":46,"value":738},{"type":46,"value":270},{"type":40,"tag":109,"props":1703,"children":1705},{"className":1704},[],[1706],{"type":46,"value":1526},{"type":40,"tag":66,"props":1708,"children":1709},{},[1710,1715,1716],{"type":40,"tag":109,"props":1711,"children":1713},{"className":1712},[],[1714],{"type":46,"value":135},{"type":46,"value":270},{"type":40,"tag":109,"props":1717,"children":1719},{"className":1718},[],[1720],{"type":46,"value":1541},{"type":40,"tag":66,"props":1722,"children":1723},{},[1724,1729,1730],{"type":40,"tag":109,"props":1725,"children":1727},{"className":1726},[],[1728],{"type":46,"value":720},{"type":46,"value":270},{"type":40,"tag":109,"props":1731,"children":1733},{"className":1732},[],[1734],{"type":46,"value":1556},{"type":40,"tag":49,"props":1736,"children":1737},{},[1738],{"type":46,"value":1739},"Reject these counterexamples:",{"type":40,"tag":72,"props":1741,"children":1742},{},[1743,1765,1780],{"type":40,"tag":66,"props":1744,"children":1745},{},[1746,1751,1752,1757,1759,1764],{"type":40,"tag":109,"props":1747,"children":1749},{"className":1748},[],[1750],{"type":46,"value":295},{"type":46,"value":1150},{"type":40,"tag":109,"props":1753,"children":1755},{"className":1754},[],[1756],{"type":46,"value":321},{"type":46,"value":1758}," + user-authored callback route when ",{"type":40,"tag":109,"props":1760,"children":1762},{"className":1761},[],[1763],{"type":46,"value":1171},{"type":46,"value":1348},{"type":40,"tag":66,"props":1766,"children":1767},{},[1768,1773,1775],{"type":40,"tag":109,"props":1769,"children":1771},{"className":1770},[],[1772],{"type":46,"value":302},{"type":46,"value":1774}," paired with ",{"type":40,"tag":109,"props":1776,"children":1778},{"className":1777},[],[1779],{"type":46,"value":284},{"type":40,"tag":66,"props":1781,"children":1782},{},[1783,1785,1790,1791,1796],{"type":46,"value":1784},"named-framework app-boundary output mixed with plain ",{"type":40,"tag":109,"props":1786,"children":1788},{"className":1787},[],[1789],{"type":46,"value":463},{"type":46,"value":465},{"type":40,"tag":109,"props":1792,"children":1794},{"className":1793},[],[1795],{"type":46,"value":471},{"type":46,"value":1797}," without a framework-agnostic override",{"type":40,"tag":1799,"props":1800,"children":1801},"style",{},[1802],{"type":46,"value":1803},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1805,"total":1982},[1806,1826,1840,1859,1870,1885,1901,1919,1931,1950,1962,1972],{"slug":1807,"name":1807,"fn":1808,"description":1809,"org":1810,"tags":1811,"stars":1823,"repoUrl":1824,"updatedAt":1825},"next-cache-components-adoption","enable and migrate to Next.js Cache Components","Turn on Cache Components in a Next.js app and resolve the blocking routes it surfaces. Use when the user wants to enable, adopt, or migrate to Cache Components, flip the `cacheComponents` flag, work through a flood of blocking-prerender \u002F instant validation errors, run the `cache-components-instant-false` codemod, or decide between opting routes out with `export const instant = false` and fixing them in place.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1812,1815,1818,1819,1822],{"name":1813,"slug":1814,"type":13},"Caching","caching",{"name":1816,"slug":1817,"type":13},"Frontend","frontend",{"name":15,"slug":16,"type":13},{"name":1820,"slug":1821,"type":13},"Next.js","next-js",{"name":9,"slug":8,"type":13},141208,"https:\u002F\u002Fgithub.com\u002Fvercel\u002Fnext.js","2026-07-24T05:38:30.118542",{"slug":1827,"name":1827,"fn":1828,"description":1829,"org":1830,"tags":1831,"stars":1823,"repoUrl":1824,"updatedAt":1839},"next-cache-components-optimizer","optimize Next.js cache components","Drive a Next.js route to instant navigation by setting up an agentic loop, under Cache Components \u002F PPR, on initial load (hard navigation) and client-side navigation (soft navigation). Encode the goal as a failing @next\u002Fplaywright instant() e2e and work it to green, one verified route at a time; the shipped test then guards against regression. Use when asked to make a route's navigation instant (its static shell commits immediately), fix a route whose static shell isn't prerendered\u002Fserved\u002Fprefetched, grow a route's static shell or fix its slow first paint, diagnose which Suspense boundary keeps a route out of its static shell, or write the instant() e2e guard for one. Requires Next.js 16.3+ with cacheComponents; directs an upgrade if older.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1832,1833,1834,1835,1838],{"name":1813,"slug":1814,"type":13},{"name":1816,"slug":1817,"type":13},{"name":1820,"slug":1821,"type":13},{"name":1836,"slug":1837,"type":13},"Performance","performance",{"name":9,"slug":8,"type":13},"2026-07-30T05:31:10.674078",{"slug":1841,"name":1841,"fn":1842,"description":1843,"org":1844,"tags":1845,"stars":1823,"repoUrl":1824,"updatedAt":1858},"next-dev-loop","verify Next.js runtime behavior","Verify Next.js runtime behavior after editing app code. Use this skill to confirm a change actually works in a running app — not just that it compiles or type-checks. Combines \u002F_next\u002Fmcp (Next.js's view) with agent-browser (the browser's view). Requires a running `next dev`.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1846,1849,1850,1853,1854,1855],{"name":1847,"slug":1848,"type":13},"Debugging","debugging",{"name":1816,"slug":1817,"type":13},{"name":1851,"slug":1852,"type":13},"Local Development","local-development",{"name":1820,"slug":1821,"type":13},{"name":9,"slug":8,"type":13},{"name":1856,"slug":1857,"type":13},"Web Development","web-development","2026-05-22T06:45:28.627735",{"slug":1860,"name":1860,"fn":1861,"description":1862,"org":1863,"tags":1864,"stars":1823,"repoUrl":1824,"updatedAt":1869},"next-partial-prefetching-adoption","adopt Partial Prefetching in Next.js apps","Turn on Partial Prefetching in a Next.js app and work through the insights it surfaces. Use when the user wants to enable or adopt Partial Prefetching, flip the `partialPrefetching` flag, opt routes in with `export const prefetch = 'partial'`, audit `\u003CLink prefetch={true}>` calls, or resolve the link-prefetch-partial and instant-shell-url-data insights.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1865,1866,1867,1868],{"name":1816,"slug":1817,"type":13},{"name":1820,"slug":1821,"type":13},{"name":1836,"slug":1837,"type":13},{"name":9,"slug":8,"type":13},"2026-07-30T05:31:11.591864",{"slug":1871,"name":1871,"fn":1872,"description":1873,"org":1874,"tags":1875,"stars":1882,"repoUrl":1883,"updatedAt":1884},"turborepo","manage monorepos with Turborepo","Turborepo monorepo build system guidance. Triggers on: turbo.json, task pipelines,\ndependsOn, caching, remote cache, the \"turbo\" CLI, --filter, --affected, CI optimization, environment\nvariables, internal packages, monorepo structure\u002Fbest practices, and boundaries.\n\nUse when user: configures tasks\u002Fworkflows\u002Fpipelines, creates packages, sets up\nmonorepo, shares code between apps, runs changed\u002Faffected packages, debugs cache,\nor has apps\u002Fpackages directories.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1876,1879,1880],{"name":1877,"slug":1878,"type":13},"CI\u002FCD","ci-cd",{"name":1836,"slug":1837,"type":13},{"name":1881,"slug":1871,"type":13},"Turborepo",30809,"https:\u002F\u002Fgithub.com\u002Fvercel\u002Fturborepo","2026-07-30T05:32:14.920116",{"slug":1886,"name":1886,"fn":1887,"description":1888,"org":1889,"tags":1890,"stars":1898,"repoUrl":1899,"updatedAt":1900},"add-function-examples","add AI function examples for testing","Guide for adding new AI function examples, for testing specific features against the actual provider APIs.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1891,1894,1897],{"name":1892,"slug":1893,"type":13},"AI SDK","ai-sdk",{"name":1895,"slug":1896,"type":13},"Testing","testing",{"name":9,"slug":8,"type":13},25670,"https:\u002F\u002Fgithub.com\u002Fvercel\u002Fai","2026-04-06T18:55:51.318866",{"slug":1902,"name":1902,"fn":1903,"description":1904,"org":1905,"tags":1906,"stars":1898,"repoUrl":1899,"updatedAt":1918},"add-harness-package","add AI SDK harness packages","Guide for adding new AI SDK harness packages. Use when creating a new @ai-sdk\u002Fharness-\u003Cname> package that adapts a coding-agent runtime to HarnessV1.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1907,1910,1911,1914,1917],{"name":1908,"slug":1909,"type":13},"Agents","agents",{"name":1892,"slug":1893,"type":13},{"name":1912,"slug":1913,"type":13},"Harness","harness",{"name":1915,"slug":1916,"type":13},"SDK","sdk",{"name":9,"slug":8,"type":13},"2026-06-18T08:29:19.858737",{"slug":1920,"name":1920,"fn":1921,"description":1922,"org":1923,"tags":1924,"stars":1898,"repoUrl":1899,"updatedAt":1930},"add-provider-package","add new provider packages to AI SDK","Guide for adding new AI provider packages to the AI SDK. Use when creating a new @ai-sdk\u002F\u003Cprovider> package to integrate an AI service into the SDK.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1925,1926,1929],{"name":1892,"slug":1893,"type":13},{"name":1927,"slug":1928,"type":13},"API Development","api-development",{"name":9,"slug":8,"type":13},"2026-04-06T18:55:47.45549",{"slug":1932,"name":1932,"fn":1933,"description":1934,"org":1935,"tags":1936,"stars":1898,"repoUrl":1899,"updatedAt":1949},"adr-skill","create and maintain architecture decision records","Create and maintain Architecture Decision Records (ADRs) optimized for agentic coding workflows. Use when you need to propose, write, update, accept\u002Freject, deprecate, or supersede an ADR; bootstrap an adr folder and index; consult existing ADRs before implementing changes; or enforce ADR conventions. This skill uses Socratic questioning to capture intent before drafting, and validates output against an agent-readiness checklist.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1937,1940,1943,1946],{"name":1938,"slug":1939,"type":13},"ADR","adr",{"name":1941,"slug":1942,"type":13},"Architecture","architecture",{"name":1944,"slug":1945,"type":13},"Documentation","documentation",{"name":1947,"slug":1948,"type":13},"Engineering","engineering","2026-04-06T18:55:50.043694",{"slug":1893,"name":1893,"fn":1951,"description":1952,"org":1953,"tags":1954,"stars":1898,"repoUrl":1899,"updatedAt":1961},"build AI features with Vercel AI SDK","Answer questions about the AI SDK and help build AI-powered features. Use when developers: (1) Ask about AI SDK functions like generateText, streamText, ToolLoopAgent, embed, or tools, (2) Want to build AI agents, chatbots, RAG systems, or text generation features, (3) Have questions about AI providers (OpenAI, Anthropic, Google, etc.), streaming, tool calling, structured output, or embeddings, (4) Use React hooks like useChat or useCompletion. Triggers on: \"AI SDK\", \"Vercel AI SDK\", \"generateText\", \"streamText\", \"add AI to my app\", \"build an agent\", \"tool calling\", \"structured output\", \"useChat\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1955,1956,1957,1960],{"name":1908,"slug":1909,"type":13},{"name":1892,"slug":1893,"type":13},{"name":1958,"slug":1959,"type":13},"LLM","llm",{"name":9,"slug":8,"type":13},"2026-04-06T18:55:48.739463",{"slug":1963,"name":1963,"fn":1964,"description":1965,"org":1966,"tags":1967,"stars":1898,"repoUrl":1899,"updatedAt":1971},"capture-api-response-test-fixture","capture API response test fixtures","Capture API response test fixture.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1968,1969,1970],{"name":1927,"slug":1928,"type":13},{"name":1895,"slug":1896,"type":13},{"name":9,"slug":8,"type":13},"2026-04-06T18:55:56.374433",{"slug":1973,"name":1973,"fn":1974,"description":1975,"org":1976,"tags":1977,"stars":1898,"repoUrl":1899,"updatedAt":1981},"develop-ai-functions-example","develop AI SDK function examples","Develop examples for AI SDK functions. Use when creating, running, or modifying examples under examples\u002Fai-functions\u002Fsrc to validate provider support, demonstrate features, or create test fixtures.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1978,1979,1980],{"name":1892,"slug":1893,"type":13},{"name":1895,"slug":1896,"type":13},{"name":9,"slug":8,"type":13},"2026-04-06T18:55:55.088956",68,{"items":1984,"total":875},[1985,1998,2004,2017],{"slug":1986,"name":1986,"fn":1987,"description":1988,"org":1989,"tags":1990,"stars":20,"repoUrl":21,"updatedAt":1997},"internal-dev-workbench","set up isolated development workbenches","Spin up a portless + tmux dev session for the Workflow SDK that gives each git worktree isolated `\u003Cbranch>.\u003Cname>.localhost` URLs for the Next.js workbench and the observability UI, plus a Claude statusline that surfaces those URLs. Use only when the user asks for a \"portless dev session\", a \"tmux dev layout for workflow\", \"worktree-isolated dev URLs\", or wants to wire workflow dev URLs into the Claude statusline. Do not activate for the generic \"start the dev server\" \u002F \"run pnpm dev\" task.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1991,1992,1993,1996],{"name":1947,"slug":1948,"type":13},{"name":1851,"slug":1852,"type":13},{"name":1994,"slug":1995,"type":13},"Observability","observability",{"name":9,"slug":8,"type":13},"2026-05-05T05:21:00.024468",{"slug":4,"name":4,"fn":5,"description":6,"org":1999,"tags":2000,"stars":20,"repoUrl":21,"updatedAt":22},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2001,2002,2003],{"name":15,"slug":16,"type":13},{"name":9,"slug":8,"type":13},{"name":18,"slug":19,"type":13},{"slug":2005,"name":2005,"fn":2006,"description":2007,"org":2008,"tags":2009,"stars":20,"repoUrl":21,"updatedAt":2016},"workflow","build durable workflows with Vercel","Creates durable, resumable workflows using Vercel's Workflow SDK. Use when building workflows that need to survive restarts, pause for external events, retry on failure, or coordinate multi-step operations over time. Triggers on mentions of \"workflow\", \"durable functions\", \"resumable\", \"workflow sdk\", \"queue\", \"event\", \"push\", \"subscribe\", or step-based orchestration.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2010,2013,2014,2015],{"name":2011,"slug":2012,"type":13},"Backend","backend",{"name":1915,"slug":1916,"type":13},{"name":9,"slug":8,"type":13},{"name":18,"slug":19,"type":13},"2026-04-06T18:55:58.915052",{"slug":2018,"name":2018,"fn":2019,"description":2020,"org":2021,"tags":2022,"stars":20,"repoUrl":21,"updatedAt":2029},"workflow-init","initialize Vercel Workflow SDK","Install and configure Vercel Workflow SDK before it exists in node_modules. Use when the user asks to \"install workflow\", \"set up workflow\", \"add durable workflows\", \"configure workflow sdk\", or \"init workflow\" for Next.js, Express, Hono, Fastify, NestJS, Nitro, Nuxt, Astro, SvelteKit, or Vite.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2023,2026,2027,2028],{"name":2024,"slug":2025,"type":13},"Node.js","node-js",{"name":1915,"slug":1916,"type":13},{"name":9,"slug":8,"type":13},{"name":18,"slug":19,"type":13},"2026-04-06T18:56:00.193699"]