[{"data":1,"prerenderedAt":819},["ShallowReactive",2],{"navigation_docs":3,"-guide-api-define-endpoints":168,"-guide-api-define-endpoints-surround":815},[4,146],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":36},"Guide","i-lucide-book-open","\u002Fguide","1.guide",[10,14,37,55,59,63,67,71,75,79,83,87,109,134,138,142],{"title":11,"path":12,"stem":13},"What is Agent Zero?","\u002Fguide\u002Fintroduction","1.guide\u002F1.introduction",{"title":15,"icon":16,"path":17,"stem":18,"children":19,"page":36},"API","i-lucide-plug","\u002Fguide\u002Fapi","1.guide\u002F10.api",[20,24,28,32],{"title":21,"path":22,"stem":23},"API overview","\u002Fguide\u002Fapi\u002Foverview","1.guide\u002F10.api\u002F1.overview",{"title":25,"path":26,"stem":27},"Define endpoints","\u002Fguide\u002Fapi\u002Fdefine-endpoints","1.guide\u002F10.api\u002F2.define-endpoints",{"title":29,"path":30,"stem":31},"Use the API from a client","\u002Fguide\u002Fapi\u002Fuse-from-client","1.guide\u002F10.api\u002F3.use-from-client",{"title":33,"path":34,"stem":35},"Protect endpoints","\u002Fguide\u002Fapi\u002Fprotect-endpoints","1.guide\u002F10.api\u002F4.protect-endpoints",false,{"title":38,"icon":39,"path":40,"stem":41,"children":42,"page":36},"Authentication","i-lucide-lock","\u002Fguide\u002Fauthentication","1.guide\u002F11.authentication",[43,47,51],{"title":44,"path":45,"stem":46},"Authentication overview","\u002Fguide\u002Fauthentication\u002Foverview","1.guide\u002F11.authentication\u002F1.overview",{"title":48,"path":49,"stem":50},"GitHub OAuth","\u002Fguide\u002Fauthentication\u002Foauth","1.guide\u002F11.authentication\u002F2.oauth",{"title":52,"path":53,"stem":54},"Permissions","\u002Fguide\u002Fauthentication\u002Fpermissions","1.guide\u002F11.authentication\u002F3.permissions",{"title":56,"path":57,"stem":58},"Organizations","\u002Fguide\u002Forganizations","1.guide\u002F12.organizations",{"title":60,"path":61,"stem":62},"Frontend","\u002Fguide\u002Ffrontend","1.guide\u002F13.frontend",{"title":64,"path":65,"stem":66},"Mails","\u002Fguide\u002Fmails","1.guide\u002F14.mails",{"title":68,"path":69,"stem":70},"Internationalization","\u002Fguide\u002Finternationalization","1.guide\u002F15.internationalization",{"title":72,"path":73,"stem":74},"Deployment","\u002Fguide\u002Fdeployment","1.guide\u002F16.deployment",{"title":76,"path":77,"stem":78},"Tech stack","\u002Fguide\u002Ftech-stack","1.guide\u002F2.tech-stack",{"title":80,"path":81,"stem":82},"Installation","\u002Fguide\u002Finstallation","1.guide\u002F3.installation",{"title":84,"path":85,"stem":86},"Environment variables","\u002Fguide\u002Fenvironment-variables","1.guide\u002F4.environment-variables",{"title":88,"icon":89,"path":90,"stem":91,"children":92,"page":36},"Codebase","i-lucide-folder-tree","\u002Fguide\u002Fcodebase","1.guide\u002F5.codebase",[93,97,101,105],{"title":94,"path":95,"stem":96},"Codebase structure","\u002Fguide\u002Fcodebase\u002Fstructure","1.guide\u002F5.codebase\u002F1.structure",{"title":98,"path":99,"stem":100},"Dependencies","\u002Fguide\u002Fcodebase\u002Fdependencies","1.guide\u002F5.codebase\u002F2.dependencies",{"title":102,"path":103,"stem":104},"Formatting and linting","\u002Fguide\u002Fcodebase\u002Fformatting-linting","1.guide\u002F5.codebase\u002F3.formatting-linting",{"title":106,"path":107,"stem":108},"Agent Skills","\u002Fguide\u002Fcodebase\u002Fagent-skills","1.guide\u002F5.codebase\u002F4.agent-skills",{"title":110,"icon":111,"path":112,"stem":113,"children":114,"page":36},"Architecture","i-lucide-layers","\u002Fguide\u002Farchitecture","1.guide\u002F6.architecture",[115,118,122,126,130],{"title":110,"path":116,"stem":117},"\u002Fguide\u002Farchitecture\u002Foverview","1.guide\u002F6.architecture\u002F1.overview",{"title":119,"path":120,"stem":121},"State machine","\u002Fguide\u002Farchitecture\u002Fstate-machine","1.guide\u002F6.architecture\u002F2.state-machine",{"title":123,"path":124,"stem":125},"Execution boundary","\u002Fguide\u002Farchitecture\u002Fexecution-boundary","1.guide\u002F6.architecture\u002F3.execution-boundary",{"title":127,"path":128,"stem":129},"Issue-to-PR workflow","\u002Fguide\u002Farchitecture\u002Fissue-to-pr","1.guide\u002F6.architecture\u002F4.issue-to-pr",{"title":131,"path":132,"stem":133},"Adding a capability","\u002Fguide\u002Farchitecture\u002Fadding-a-capability","1.guide\u002F6.architecture\u002F5.adding-a-capability",{"title":135,"path":136,"stem":137},"Repository policy","\u002Fguide\u002Fconfiguration","1.guide\u002F7.configuration",{"title":139,"path":140,"stem":141},"Safety model","\u002Fguide\u002Fsafety","1.guide\u002F8.safety",{"title":143,"path":144,"stem":145},"Database","\u002Fguide\u002Fdatabase","1.guide\u002F9.database",{"title":147,"icon":148,"path":149,"stem":150,"children":151,"page":36},"Reference","i-lucide-book-marked","\u002Freference","2.reference",[152,156,160,164],{"title":153,"path":154,"stem":155},"CLI","\u002Freference\u002Fcli","2.reference\u002F1.cli",{"title":157,"path":158,"stem":159},"Model providers","\u002Freference\u002Fmodel-providers","2.reference\u002F2.model-providers",{"title":161,"path":162,"stem":163},"Source-control providers","\u002Freference\u002Fsource-control-providers","2.reference\u002F3.source-control-providers",{"title":165,"path":166,"stem":167},"Sandbox providers","\u002Freference\u002Fsandbox-providers","2.reference\u002F4.sandbox-providers",{"id":169,"title":25,"body":170,"description":809,"extension":810,"links":811,"meta":812,"navigation":292,"path":26,"seo":813,"stem":27,"__hash__":814},"docs\u002F1.guide\u002F10.api\u002F2.define-endpoints.md",{"type":171,"value":172,"toc":803},"minimark",[173,191,196,609,612,659,663,668,753,760,764,786,790,799],[174,175,176,177,181,182,185,186,190],"p",{},"Procedures are defined once in ",[178,179,180],"code",{},"packages\u002Fapi\u002Fsrc\u002Forpc\u002Frouter.ts"," and served over both transports automatically. Before changing routes, read the ",[178,183,184],{},"orpc-server"," ",[187,188,189],"a",{"href":107},"Agent Skill",".",[192,193,195],"h2",{"id":194},"anatomy-of-a-procedure","Anatomy of a procedure",[197,198,203],"pre",{"className":199,"code":200,"language":201,"meta":202,"style":202},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { openapi } from '@orpc\u002Fopenapi';\nimport { os } from '@orpc\u002Fserver';\nimport { z } from 'zod';\n\nconst procedure = os.$context\u003CRpcContext>();\n\nexport const rpcRouter = {\n  tasks: {\n    get: procedure\n      .meta(\n        openapi({\n          method: 'GET',\n          path: '\u002Ftasks\u002F{id}',\n          tags: ['Tasks'],\n          summary: 'Get a task by id',\n        }),\n      )\n      .input(z.object({ id: z.string().min(1) }))\n      .handler(({ input, context }) => getStoredTask(input.id, context.store)),\n  },\n};\n","ts","",[178,204,205,241,264,287,294,330,335,352,364,375,387,399,417,434,457,474,485,491,546,597,603],{"__ignoreMap":202},[206,207,210,214,218,222,225,228,231,235,238],"span",{"class":208,"line":209},"line",1,[206,211,213],{"class":212},"s7zQu","import",[206,215,217],{"class":216},"sMK4o"," {",[206,219,221],{"class":220},"sTEyZ"," openapi",[206,223,224],{"class":216}," }",[206,226,227],{"class":212}," from",[206,229,230],{"class":216}," '",[206,232,234],{"class":233},"sfazB","@orpc\u002Fopenapi",[206,236,237],{"class":216},"'",[206,239,240],{"class":216},";\n",[206,242,244,246,248,251,253,255,257,260,262],{"class":208,"line":243},2,[206,245,213],{"class":212},[206,247,217],{"class":216},[206,249,250],{"class":220}," os",[206,252,224],{"class":216},[206,254,227],{"class":212},[206,256,230],{"class":216},[206,258,259],{"class":233},"@orpc\u002Fserver",[206,261,237],{"class":216},[206,263,240],{"class":216},[206,265,267,269,271,274,276,278,280,283,285],{"class":208,"line":266},3,[206,268,213],{"class":212},[206,270,217],{"class":216},[206,272,273],{"class":220}," z",[206,275,224],{"class":216},[206,277,227],{"class":212},[206,279,230],{"class":216},[206,281,282],{"class":233},"zod",[206,284,237],{"class":216},[206,286,240],{"class":216},[206,288,290],{"class":208,"line":289},4,[206,291,293],{"emptyLinePlaceholder":292},true,"\n",[206,295,297,301,304,307,309,311,315,318,322,325,328],{"class":208,"line":296},5,[206,298,300],{"class":299},"spNyl","const",[206,302,303],{"class":220}," procedure ",[206,305,306],{"class":216},"=",[206,308,250],{"class":220},[206,310,190],{"class":216},[206,312,314],{"class":313},"s2Zo4","$context",[206,316,317],{"class":216},"\u003C",[206,319,321],{"class":320},"sBMFI","RpcContext",[206,323,324],{"class":216},">",[206,326,327],{"class":220},"()",[206,329,240],{"class":216},[206,331,333],{"class":208,"line":332},6,[206,334,293],{"emptyLinePlaceholder":292},[206,336,338,341,344,347,349],{"class":208,"line":337},7,[206,339,340],{"class":212},"export",[206,342,343],{"class":299}," const",[206,345,346],{"class":220}," rpcRouter ",[206,348,306],{"class":216},[206,350,351],{"class":216}," {\n",[206,353,355,359,362],{"class":208,"line":354},8,[206,356,358],{"class":357},"swJcz","  tasks",[206,360,361],{"class":216},":",[206,363,351],{"class":216},[206,365,367,370,372],{"class":208,"line":366},9,[206,368,369],{"class":357},"    get",[206,371,361],{"class":216},[206,373,374],{"class":220}," procedure\n",[206,376,378,381,384],{"class":208,"line":377},10,[206,379,380],{"class":216},"      .",[206,382,383],{"class":313},"meta",[206,385,386],{"class":220},"(\n",[206,388,390,393,396],{"class":208,"line":389},11,[206,391,392],{"class":313},"        openapi",[206,394,395],{"class":220},"(",[206,397,398],{"class":216},"{\n",[206,400,402,405,407,409,412,414],{"class":208,"line":401},12,[206,403,404],{"class":357},"          method",[206,406,361],{"class":216},[206,408,230],{"class":216},[206,410,411],{"class":233},"GET",[206,413,237],{"class":216},[206,415,416],{"class":216},",\n",[206,418,420,423,425,427,430,432],{"class":208,"line":419},13,[206,421,422],{"class":357},"          path",[206,424,361],{"class":216},[206,426,230],{"class":216},[206,428,429],{"class":233},"\u002Ftasks\u002F{id}",[206,431,237],{"class":216},[206,433,416],{"class":216},[206,435,437,440,442,445,447,450,452,455],{"class":208,"line":436},14,[206,438,439],{"class":357},"          tags",[206,441,361],{"class":216},[206,443,444],{"class":220}," [",[206,446,237],{"class":216},[206,448,449],{"class":233},"Tasks",[206,451,237],{"class":216},[206,453,454],{"class":220},"]",[206,456,416],{"class":216},[206,458,460,463,465,467,470,472],{"class":208,"line":459},15,[206,461,462],{"class":357},"          summary",[206,464,361],{"class":216},[206,466,230],{"class":216},[206,468,469],{"class":233},"Get a task by id",[206,471,237],{"class":216},[206,473,416],{"class":216},[206,475,477,480,483],{"class":208,"line":476},16,[206,478,479],{"class":216},"        }",[206,481,482],{"class":220},")",[206,484,416],{"class":216},[206,486,488],{"class":208,"line":487},17,[206,489,490],{"class":220},"      )\n",[206,492,494,496,499,502,504,507,509,512,515,517,519,521,524,526,528,531,533,537,540,543],{"class":208,"line":493},18,[206,495,380],{"class":216},[206,497,498],{"class":313},"input",[206,500,501],{"class":220},"(z",[206,503,190],{"class":216},[206,505,506],{"class":313},"object",[206,508,395],{"class":220},[206,510,511],{"class":216},"{",[206,513,514],{"class":357}," id",[206,516,361],{"class":216},[206,518,273],{"class":220},[206,520,190],{"class":216},[206,522,523],{"class":313},"string",[206,525,327],{"class":220},[206,527,190],{"class":216},[206,529,530],{"class":313},"min",[206,532,395],{"class":220},[206,534,536],{"class":535},"sbssI","1",[206,538,539],{"class":220},") ",[206,541,542],{"class":216},"}",[206,544,545],{"class":220},"))\n",[206,547,549,551,554,556,559,563,566,569,572,575,578,581,583,586,588,590,592,595],{"class":208,"line":548},19,[206,550,380],{"class":216},[206,552,553],{"class":313},"handler",[206,555,395],{"class":220},[206,557,558],{"class":216},"({",[206,560,562],{"class":561},"sHdIc"," input",[206,564,565],{"class":216},",",[206,567,568],{"class":561}," context",[206,570,571],{"class":216}," })",[206,573,574],{"class":299}," =>",[206,576,577],{"class":313}," getStoredTask",[206,579,580],{"class":220},"(input",[206,582,190],{"class":216},[206,584,585],{"class":220},"id",[206,587,565],{"class":216},[206,589,568],{"class":220},[206,591,190],{"class":216},[206,593,594],{"class":220},"store))",[206,596,416],{"class":216},[206,598,600],{"class":208,"line":599},20,[206,601,602],{"class":216},"  },\n",[206,604,606],{"class":208,"line":605},21,[206,607,608],{"class":216},"};\n",[174,610,611],{},"Three rules shape every procedure:",[613,614,615,627,639],"ul",{},[616,617,618,622,623,626],"li",{},[619,620,621],"strong",{},"Validate at the boundary with Zod, then delegate."," Handlers call operations from ",[178,624,625],{},"packages\u002Fapi\u002Fsrc\u002Foperations.ts","; they never invoke a shell or touch a checkout.",[616,628,629,636,637,190],{},[619,630,631,632,635],{},"Mutations build on the ",[178,633,634],{},"authenticated"," middleware",", which requires a resolved principal and fails closed. Reads stay open for the dashboard. See ",[187,638,33],{"href":34},[616,640,641,651,652,654,655,658],{},[619,642,643,644,647,648,190],{},"OpenAPI metadata goes through ",[178,645,646],{},".meta(openapi(...))",", not ",[178,649,650],{},".route()"," The metadata (method, path, tags) exists purely for the OpenAPI transport and has no effect on the RPC transport. It is attached through a real, regularly-imported function rather than ",[178,653,234],{},"'s bare side-effect import, because Nitro's production bundler tree-shakes an unused side-effect import away — procedures would build fine but lose all ",[178,656,657],{},"\u002Fapi\u002Fv1\u002F**"," routing at runtime.",[192,660,662],{"id":661},"context","Context",[174,664,665,667],{},[178,666,321],{}," carries what the transport resolved for the request:",[197,669,671],{"className":199,"code":670,"language":201,"meta":202,"style":202},"export interface RpcContext {\n  store: TaskStore;\n  \u002F** Authenticated caller resolved by the transport; absent for anonymous requests. *\u002F\n  principal?: Principal;\n  \u002F** Whether tasks.create may target this repository. Fails closed when absent. *\u002F\n  mayTargetRepository?: (repository: string) => boolean;\n}\n",[178,672,673,685,697,703,716,721,748],{"__ignoreMap":202},[206,674,675,677,680,683],{"class":208,"line":209},[206,676,340],{"class":212},[206,678,679],{"class":299}," interface",[206,681,682],{"class":320}," RpcContext",[206,684,351],{"class":216},[206,686,687,690,692,695],{"class":208,"line":243},[206,688,689],{"class":357},"  store",[206,691,361],{"class":216},[206,693,694],{"class":320}," TaskStore",[206,696,240],{"class":216},[206,698,699],{"class":208,"line":266},[206,700,702],{"class":701},"sHwdD","  \u002F** Authenticated caller resolved by the transport; absent for anonymous requests. *\u002F\n",[206,704,705,708,711,714],{"class":208,"line":289},[206,706,707],{"class":357},"  principal",[206,709,710],{"class":216},"?:",[206,712,713],{"class":320}," Principal",[206,715,240],{"class":216},[206,717,718],{"class":208,"line":296},[206,719,720],{"class":701},"  \u002F** Whether tasks.create may target this repository. Fails closed when absent. *\u002F\n",[206,722,723,726,728,731,734,736,739,741,743,746],{"class":208,"line":332},[206,724,725],{"class":357},"  mayTargetRepository",[206,727,710],{"class":216},[206,729,730],{"class":216}," (",[206,732,733],{"class":561},"repository",[206,735,361],{"class":216},[206,737,738],{"class":320}," string",[206,740,482],{"class":216},[206,742,574],{"class":299},[206,744,745],{"class":320}," boolean",[206,747,240],{"class":216},[206,749,750],{"class":208,"line":337},[206,751,752],{"class":216},"}\n",[174,754,755,756,759],{},"Transport concerns stop at the route handlers in ",[178,757,758],{},"apps\u002Fdashboard\u002Fserver\u002F",": headers, status mapping, and request objects never reach a runtime package.",[192,761,763],{"id":762},"request-logging","Request logging",[174,765,766,769,770,773,774,777,778,781,782,785],{},[178,767,768],{},"EvlogHandlerPlugin"," attaches structured request logs through one ",[178,771,772],{},"AsyncLocalStorage","-backed logger shared by every transport (",[178,775,776],{},"packages\u002Fapi\u002Fsrc\u002Forpc\u002Flogging.ts","). Procedures read it defensively — ",[178,779,780],{},"requestLoggerStorage?.getStore()?.set(...)"," — so router tests that call procedures directly through ",[178,783,784],{},"createRouterClient",", without a transport's plugin attached, still pass.",[192,787,789],{"id":788},"testing","Testing",[174,791,792,793,795,796,190],{},"Call procedures directly through ",[178,794,784],{}," in unit tests — no HTTP server needed, and the same authorization rules apply. Add deterministic tests for success, rejection, and policy cases beside the source as ",[178,797,798],{},"*.test.ts",[800,801,802],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}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);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":202,"searchDepth":243,"depth":243,"links":804},[805,806,807,808],{"id":194,"depth":243,"text":195},{"id":661,"depth":243,"text":662},{"id":762,"depth":243,"text":763},{"id":788,"depth":243,"text":789},"Procedures are defined once in packages\u002Fapi\u002Fsrc\u002Forpc\u002Frouter.ts and served over both transports automatically. Before changing routes, read the orpc-server Agent Skill.","md",null,{},{"title":25,"description":809},"5mqL2e2e3nPz6m1lMp0kHlpVtSQVWQaShr1PlXInM3A",[816,818],{"title":21,"path":22,"stem":23,"description":817,"children":-1},"Agent Zero exposes one typed router — rpcRouter from packages\u002Fapi — served over two wire protocols by the dashboard's Nitro server. Authorization behaves identically either way, because both transports serve the exact same procedures.",{"title":29,"path":30,"stem":31,"description":202,"children":-1},1787482153325]