[{"data":1,"prerenderedAt":668},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fv2\u002Fagent\u002Fserver\u002Fplugins":3},{"id":4,"title":5,"body":6,"description":17,"extension":661,"meta":662,"navigation":156,"path":664,"seo":665,"stem":666,"__hash__":667},"docs\u002Fdocs\u002Fv2\u002Fagent\u002Fserver\u002Fplugins.md","plugins\u002F",{"type":7,"value":8,"toc":655},"minimark",[9,14,18,21,67,72,227,237,240,244,247,507,511,627,633,637,640,651],[10,11,13],"h1",{"id":12},"serverplugins","server\u002Fplugins\u002F",[15,16,17],"p",{},"Plugins run once at boot, before the HTTP server accepts requests. Use them for\ninitialization: database connections, SDK clients, hook subscriptions, shutdown cleanup.",[15,19,20],{},"Files load in filename order. If order matters, use numeric prefixes:",[22,23,28],"pre",{"className":24,"code":25,"language":26,"meta":27,"style":27},"language-bash shiki shiki-themes dark-plus","server\u002Fplugins\u002F\n├── 01-database.ts\n├── 02-cache.ts\n└── github.ts\n","bash","",[29,30,31,40,50,58],"code",{"__ignoreMap":27},[32,33,36],"span",{"class":34,"line":35},"line",1,[32,37,39],{"class":38},"sCudf","server\u002Fplugins\u002F\n",[32,41,43,46],{"class":34,"line":42},2,[32,44,45],{"class":38},"├──",[32,47,49],{"class":48},"sKc5r"," 01-database.ts\n",[32,51,53,55],{"class":34,"line":52},3,[32,54,45],{"class":38},[32,56,57],{"class":48}," 02-cache.ts\n",[32,59,61,64],{"class":34,"line":60},4,[32,62,63],{"class":38},"└──",[32,65,66],{"class":48}," github.ts\n",[68,69,71],"h2",{"id":70},"defining-a-plugin","Defining a plugin",[22,73,77],{"className":74,"code":75,"language":76,"meta":27,"style":27},"language-ts shiki shiki-themes dark-plus","\u002F\u002F server\u002Fplugins\u002Fdatabase.ts\nexport default defineAxonPlugin(async axon => {\n    const db = await connectDb(process.env.DATABASE_URL)\n\n    axon.hooks.hook(\"shutdown\", async () => db.close())\n\n    globalThis.db = db\n})\n","ts",[29,78,79,85,115,152,158,200,205,221],{"__ignoreMap":27},[32,80,81],{"class":34,"line":35},[32,82,84],{"class":83},"sOLPB","\u002F\u002F server\u002Fplugins\u002Fdatabase.ts\n",[32,86,87,91,94,97,101,105,109,112],{"class":34,"line":42},[32,88,90],{"class":89},"sYbnZ","export",[32,92,93],{"class":89}," default",[32,95,96],{"class":38}," defineAxonPlugin",[32,98,100],{"class":99},"sTNBD","(",[32,102,104],{"class":103},"scz_3","async",[32,106,108],{"class":107},"s3F5K"," axon",[32,110,111],{"class":103}," =>",[32,113,114],{"class":99}," {\n",[32,116,117,120,124,127,130,133,135,138,141,144,146,149],{"class":34,"line":52},[32,118,119],{"class":103},"    const",[32,121,123],{"class":122},"s9McN"," db",[32,125,126],{"class":99}," = ",[32,128,129],{"class":89},"await",[32,131,132],{"class":38}," connectDb",[32,134,100],{"class":99},[32,136,137],{"class":107},"process",[32,139,140],{"class":99},".",[32,142,143],{"class":107},"env",[32,145,140],{"class":99},[32,147,148],{"class":122},"DATABASE_URL",[32,150,151],{"class":99},")\n",[32,153,154],{"class":34,"line":60},[32,155,157],{"emptyLinePlaceholder":156},true,"\n",[32,159,161,164,166,169,171,174,176,179,182,184,187,190,192,194,197],{"class":34,"line":160},5,[32,162,163],{"class":107},"    axon",[32,165,140],{"class":99},[32,167,168],{"class":107},"hooks",[32,170,140],{"class":99},[32,172,173],{"class":38},"hook",[32,175,100],{"class":99},[32,177,178],{"class":48},"\"shutdown\"",[32,180,181],{"class":99},", ",[32,183,104],{"class":103},[32,185,186],{"class":99}," () ",[32,188,189],{"class":103},"=>",[32,191,123],{"class":107},[32,193,140],{"class":99},[32,195,196],{"class":38},"close",[32,198,199],{"class":99},"())\n",[32,201,203],{"class":34,"line":202},6,[32,204,157],{"emptyLinePlaceholder":156},[32,206,208,211,213,216,218],{"class":34,"line":207},7,[32,209,210],{"class":107},"    globalThis",[32,212,140],{"class":99},[32,214,215],{"class":107},"db",[32,217,126],{"class":99},[32,219,220],{"class":107},"db\n",[32,222,224],{"class":34,"line":223},8,[32,225,226],{"class":99},"})\n",[15,228,229,232,233,236],{},[29,230,231],{},"defineAxonPlugin"," receives the live ",[29,234,235],{},"axon"," handle. Use it to initialize connections,\nregister hook handlers, and set up globals that routes can use.",[15,238,239],{},"A plugin that throws aborts boot entirely — the server never starts. This ensures the\nagent never runs in a partially-initialized state.",[68,241,243],{"id":242},"hook-subscriptions","Hook subscriptions",[15,245,246],{},"Plugins are the right place to subscribe to module hooks. When a module emits a named\nhook from a route, you wire the response here:",[22,248,250],{"className":74,"code":249,"language":76,"meta":27,"style":27},"\u002F\u002F server\u002Fplugins\u002Fintegrations.ts\nexport default defineAxonPlugin(async axon => {\n    axon.hooks.hook(\"github:pr.opened\", async ({ number, title }) => {\n        const prompt = await axon.prompt(\"pr-review\", { number, title })\n        void axon.request({ prompt, thread: `pr-${number}` })\n    })\n\n    axon.hooks.hook(\"linear:issue.created\", async ({ id, title }) => {\n        const prompt = await axon.prompt(\"triage\", { id, title })\n        void axon.request({ prompt, thread: `issue-${id}` })\n    })\n})\n",[29,251,252,257,275,314,350,388,393,397,433,465,497,502],{"__ignoreMap":27},[32,253,254],{"class":34,"line":35},[32,255,256],{"class":83},"\u002F\u002F server\u002Fplugins\u002Fintegrations.ts\n",[32,258,259,261,263,265,267,269,271,273],{"class":34,"line":42},[32,260,90],{"class":89},[32,262,93],{"class":89},[32,264,96],{"class":38},[32,266,100],{"class":99},[32,268,104],{"class":103},[32,270,108],{"class":107},[32,272,111],{"class":103},[32,274,114],{"class":99},[32,276,277,279,281,283,285,287,289,292,294,296,299,302,304,307,310,312],{"class":34,"line":52},[32,278,163],{"class":107},[32,280,140],{"class":99},[32,282,168],{"class":107},[32,284,140],{"class":99},[32,286,173],{"class":38},[32,288,100],{"class":99},[32,290,291],{"class":48},"\"github:pr.opened\"",[32,293,181],{"class":99},[32,295,104],{"class":103},[32,297,298],{"class":99}," ({ ",[32,300,301],{"class":107},"number",[32,303,181],{"class":99},[32,305,306],{"class":107},"title",[32,308,309],{"class":99}," }) ",[32,311,189],{"class":103},[32,313,114],{"class":99},[32,315,316,319,322,324,326,328,330,333,335,338,341,343,345,347],{"class":34,"line":60},[32,317,318],{"class":103},"        const",[32,320,321],{"class":122}," prompt",[32,323,126],{"class":99},[32,325,129],{"class":89},[32,327,108],{"class":107},[32,329,140],{"class":99},[32,331,332],{"class":38},"prompt",[32,334,100],{"class":99},[32,336,337],{"class":48},"\"pr-review\"",[32,339,340],{"class":99},", { ",[32,342,301],{"class":107},[32,344,181],{"class":99},[32,346,306],{"class":107},[32,348,349],{"class":99}," })\n",[32,351,352,355,357,359,362,365,367,369,372,375,378,380,383,386],{"class":34,"line":160},[32,353,354],{"class":103},"        void",[32,356,108],{"class":107},[32,358,140],{"class":99},[32,360,361],{"class":38},"request",[32,363,364],{"class":99},"({ ",[32,366,332],{"class":107},[32,368,181],{"class":99},[32,370,371],{"class":107},"thread:",[32,373,374],{"class":48}," `pr-",[32,376,377],{"class":103},"${",[32,379,301],{"class":107},[32,381,382],{"class":103},"}",[32,384,385],{"class":48},"`",[32,387,349],{"class":99},[32,389,390],{"class":34,"line":202},[32,391,392],{"class":99},"    })\n",[32,394,395],{"class":34,"line":207},[32,396,157],{"emptyLinePlaceholder":156},[32,398,399,401,403,405,407,409,411,414,416,418,420,423,425,427,429,431],{"class":34,"line":223},[32,400,163],{"class":107},[32,402,140],{"class":99},[32,404,168],{"class":107},[32,406,140],{"class":99},[32,408,173],{"class":38},[32,410,100],{"class":99},[32,412,413],{"class":48},"\"linear:issue.created\"",[32,415,181],{"class":99},[32,417,104],{"class":103},[32,419,298],{"class":99},[32,421,422],{"class":107},"id",[32,424,181],{"class":99},[32,426,306],{"class":107},[32,428,309],{"class":99},[32,430,189],{"class":103},[32,432,114],{"class":99},[32,434,436,438,440,442,444,446,448,450,452,455,457,459,461,463],{"class":34,"line":435},9,[32,437,318],{"class":103},[32,439,321],{"class":122},[32,441,126],{"class":99},[32,443,129],{"class":89},[32,445,108],{"class":107},[32,447,140],{"class":99},[32,449,332],{"class":38},[32,451,100],{"class":99},[32,453,454],{"class":48},"\"triage\"",[32,456,340],{"class":99},[32,458,422],{"class":107},[32,460,181],{"class":99},[32,462,306],{"class":107},[32,464,349],{"class":99},[32,466,468,470,472,474,476,478,480,482,484,487,489,491,493,495],{"class":34,"line":467},10,[32,469,354],{"class":103},[32,471,108],{"class":107},[32,473,140],{"class":99},[32,475,361],{"class":38},[32,477,364],{"class":99},[32,479,332],{"class":107},[32,481,181],{"class":99},[32,483,371],{"class":107},[32,485,486],{"class":48}," `issue-",[32,488,377],{"class":103},[32,490,422],{"class":107},[32,492,382],{"class":103},[32,494,385],{"class":48},[32,496,349],{"class":99},[32,498,500],{"class":34,"line":499},11,[32,501,392],{"class":99},[32,503,505],{"class":34,"line":504},12,[32,506,226],{"class":99},[68,508,510],{"id":509},"lifecycle-hooks","Lifecycle hooks",[22,512,514],{"className":74,"code":513,"language":76,"meta":27,"style":27},"axon.hooks.hook(\"boot\", () => { ... })          \u002F\u002F after plugins, before server ready\naxon.hooks.hook(\"server:ready\", () => { ... })  \u002F\u002F HTTP server is listening\naxon.hooks.hook(\"server:close\", () => { ... }) \u002F\u002F server stopped accepting requests\naxon.hooks.hook(\"shutdown\", async () => { ... }) \u002F\u002F final cleanup\n",[29,515,516,544,571,598],{"__ignoreMap":27},[32,517,518,520,522,524,526,528,530,533,536,538,541],{"class":34,"line":35},[32,519,235],{"class":107},[32,521,140],{"class":99},[32,523,168],{"class":107},[32,525,140],{"class":99},[32,527,173],{"class":38},[32,529,100],{"class":99},[32,531,532],{"class":48},"\"boot\"",[32,534,535],{"class":99},", () ",[32,537,189],{"class":103},[32,539,540],{"class":99}," { ... })          ",[32,542,543],{"class":83},"\u002F\u002F after plugins, before server ready\n",[32,545,546,548,550,552,554,556,558,561,563,565,568],{"class":34,"line":42},[32,547,235],{"class":107},[32,549,140],{"class":99},[32,551,168],{"class":107},[32,553,140],{"class":99},[32,555,173],{"class":38},[32,557,100],{"class":99},[32,559,560],{"class":48},"\"server:ready\"",[32,562,535],{"class":99},[32,564,189],{"class":103},[32,566,567],{"class":99}," { ... })  ",[32,569,570],{"class":83},"\u002F\u002F HTTP server is listening\n",[32,572,573,575,577,579,581,583,585,588,590,592,595],{"class":34,"line":52},[32,574,235],{"class":107},[32,576,140],{"class":99},[32,578,168],{"class":107},[32,580,140],{"class":99},[32,582,173],{"class":38},[32,584,100],{"class":99},[32,586,587],{"class":48},"\"server:close\"",[32,589,535],{"class":99},[32,591,189],{"class":103},[32,593,594],{"class":99}," { ... }) ",[32,596,597],{"class":83},"\u002F\u002F server stopped accepting requests\n",[32,599,600,602,604,606,608,610,612,614,616,618,620,622,624],{"class":34,"line":60},[32,601,235],{"class":107},[32,603,140],{"class":99},[32,605,168],{"class":107},[32,607,140],{"class":99},[32,609,173],{"class":38},[32,611,100],{"class":99},[32,613,178],{"class":48},[32,615,181],{"class":99},[32,617,104],{"class":103},[32,619,186],{"class":99},[32,621,189],{"class":103},[32,623,594],{"class":99},[32,625,626],{"class":83},"\u002F\u002F final cleanup\n",[15,628,629,630,632],{},"Use ",[29,631,178],{}," for cleanup — closing database connections, flushing queues, graceful\ntermination of background processes.",[68,634,636],{"id":635},"boot-order","Boot order",[15,638,639],{},"Module plugins run before user plugins. This guarantees modules can set up dependencies — SDK clients, event emitters — before your code subscribes to them.",[15,641,642,643,646,647,650],{},"Order: module plugins → user plugins → ",[29,644,645],{},"boot"," hook → HTTP server ready → ",[29,648,649],{},"server:ready"," hook.",[652,653,654],"style",{},"html pre.shiki code .sCudf, html code.shiki .sCudf{--shiki-default:#DCDCAA}html pre.shiki code .sKc5r, html code.shiki .sKc5r{--shiki-default:#CE9178}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 pre.shiki code .sOLPB, html code.shiki .sOLPB{--shiki-default:#6A9955}html pre.shiki code .sYbnZ, html code.shiki .sYbnZ{--shiki-default:#C586C0}html pre.shiki code .sTNBD, html code.shiki .sTNBD{--shiki-default:#D4D4D4}html pre.shiki code .scz_3, html code.shiki .scz_3{--shiki-default:#569CD6}html pre.shiki code .s3F5K, html code.shiki .s3F5K{--shiki-default:#9CDCFE}html pre.shiki code .s9McN, html code.shiki .s9McN{--shiki-default:#4FC1FF}",{"title":27,"searchDepth":42,"depth":42,"links":656},[657,658,659,660],{"id":70,"depth":42,"text":71},{"id":242,"depth":42,"text":243},{"id":509,"depth":42,"text":510},{"id":635,"depth":42,"text":636},"md",{"icon":663},"vscode-icons:folder-type-plugin","\u002Fdocs\u002Fv2\u002Fagent\u002Fserver\u002Fplugins",{"title":5,"description":17},"docs\u002Fv2\u002Fagent\u002Fserver\u002Fplugins","AHDUs6Ra95eWXoCXbFCntdxU9nfykT_vvrk0hIX5bEQ",1785671806583]