[{"data":1,"prerenderedAt":820},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fv2\u002Fconcepts\u002Fmodules":3},{"id":4,"title":5,"body":6,"description":16,"extension":814,"meta":815,"navigation":310,"path":816,"seo":817,"stem":818,"__hash__":819},"docs\u002Fdocs\u002Fv2\u002Fconcepts\u002Fmodules.md","Modules",{"type":7,"value":8,"toc":806},"minimark",[9,13,17,43,58,63,88,98,111,117,121,128,232,235,239,246,249,253,256,555,558,562,565,753,756,760,763,795,802],[10,11,5],"h1",{"id":12},"modules",[14,15,16],"p",{},"A module is an installable capability package. It contributes tools, prompts, scripts, and\nroutes to your agent — the same primitives you author yourself, shipped by someone else.",[18,19,24],"pre",{"className":20,"code":21,"language":22,"meta":23,"style":23},"language-bash shiki shiki-themes dark-plus","axon install @axon\u002Fgithub\n","bash","",[25,26,27],"code",{"__ignoreMap":23},[28,29,32,36,40],"span",{"class":30,"line":31},"line",1,[28,33,35],{"class":34},"sCudf","axon",[28,37,39],{"class":38},"sKc5r"," install",[28,41,42],{"class":38}," @axon\u002Fgithub\n",[14,44,45,46,49,50,53,54,57],{},"After that command, your agent has ",[25,47,48],{},"github.*"," tools the agent can call, prompts for common\nGitHub tasks, and a webhook route at ",[25,51,52],{},"\u002Fapi\u002Fwebhooks\u002Fgithub"," that the module manages.\nNothing to wire up. Nothing to configure beyond your API key in ",[25,55,56],{},".env",".",[59,60,62],"h2",{"id":61},"what-a-module-can-contribute","What a module can contribute",[14,64,65,69,70,73,74,77,78,77,81,84,85,57],{},[66,67,68],"strong",{},"Tools"," — async functions available to the agent under a typed namespace. ",[25,71,72],{},"@axon\u002Fgithub","\ncontributes ",[25,75,76],{},"github.openPr()",", ",[25,79,80],{},"github.getPr()",[25,82,83],{},"github.createIssue()",", and others. The\nagent sees them the same way it sees tools you write in ",[25,86,87],{},"src\u002Ftools\u002F",[14,89,90,93,94,97],{},[66,91,92],{},"Prompts"," — reusable context templates your scripts can load. A module might ship a\n",[25,95,96],{},"github\u002Fissue-context"," prompt that hydrates everything about an issue in one call.",[14,99,100,103,104,106,107,110],{},[66,101,102],{},"Scripts"," — automations you can invoke directly. ",[25,105,72],{}," might ship a\n",[25,108,109],{},"pr-review"," script that loads the diff, runs the agent, and posts a comment.",[14,112,113,116],{},[66,114,115],{},"Routes"," — HTTP endpoints the module registers alongside your own. A module that handles\nwebhooks ships the route that receives them and emits the hooks your plugins subscribe to.",[59,118,120],{"id":119},"where-modules-live","Where modules live",[14,122,123,124,127],{},"Installed modules land in ",[25,125,126],{},"modules\u002F"," inside the agent folder:",[18,129,131],{"className":20,"code":130,"language":22,"meta":23,"style":23},"my-agent\u002F\n└── modules\u002F\n    └── @axon\u002F\n        └── github\u002F\n            ├── server\u002F\n            │   └── api\u002F\n            ├── src\u002F\n            │   ├── prompts\u002F\n            │   └── tools\u002F\n            ├── module.config.ts\n            └── package.json\n",[25,132,133,138,147,156,165,174,186,194,205,215,223],{"__ignoreMap":23},[28,134,135],{"class":30,"line":31},[28,136,137],{"class":34},"my-agent\u002F\n",[28,139,141,144],{"class":30,"line":140},2,[28,142,143],{"class":34},"└──",[28,145,146],{"class":38}," modules\u002F\n",[28,148,150,153],{"class":30,"line":149},3,[28,151,152],{"class":34},"    └──",[28,154,155],{"class":38}," @axon\u002F\n",[28,157,159,162],{"class":30,"line":158},4,[28,160,161],{"class":34},"        └──",[28,163,164],{"class":38}," github\u002F\n",[28,166,168,171],{"class":30,"line":167},5,[28,169,170],{"class":34},"            ├──",[28,172,173],{"class":38}," server\u002F\n",[28,175,177,180,183],{"class":30,"line":176},6,[28,178,179],{"class":34},"            │",[28,181,182],{"class":38},"   └──",[28,184,185],{"class":38}," api\u002F\n",[28,187,189,191],{"class":30,"line":188},7,[28,190,170],{"class":34},[28,192,193],{"class":38}," src\u002F\n",[28,195,197,199,202],{"class":30,"line":196},8,[28,198,179],{"class":34},[28,200,201],{"class":38},"   ├──",[28,203,204],{"class":38}," prompts\u002F\n",[28,206,208,210,212],{"class":30,"line":207},9,[28,209,179],{"class":34},[28,211,182],{"class":38},[28,213,214],{"class":38}," tools\u002F\n",[28,216,218,220],{"class":30,"line":217},10,[28,219,170],{"class":34},[28,221,222],{"class":38}," module.config.ts\n",[28,224,226,229],{"class":30,"line":225},11,[28,227,228],{"class":34},"            └──",[28,230,231],{"class":38}," package.json\n",[14,233,234],{},"They're source on disk, not a build artifact. You can read every file. Axon discovers them\nautomatically at boot — there's no registration step.",[59,236,238],{"id":237},"your-agent-stays-in-charge","Your agent stays in charge",[14,240,241,242,245],{},"Modules operate within your agent's policy. A module tool that tries to write outside the\npaths your ",[25,243,244],{},"fs"," policy allows will be rejected exactly the same as if your own tool tried\nit. The module doesn't declare its own policy — your base policy applies to everything\nrunning in the capsule.",[14,247,248],{},"Modules also don't touch your boot prompt, your session state, or your thread history.\nThey extend the surface area of what the agent can do; they don't change what the agent is.",[59,250,252],{"id":251},"composing-your-own-tools-with-module-tools","Composing your own tools with module tools",[14,254,255],{},"Module tools are available in scripts the same way your own tools are:",[18,257,261],{"className":258,"code":259,"language":260,"meta":23,"style":23},"language-ts shiki shiki-themes dark-plus","\u002F\u002F src\u002Fscripts\u002Fpr-review.ts\nconst { domain } = defineArgs\u003C{ pr: string }>()\n\n\u002F\u002F module tool — fetches PR metadata and diff\nconst pr = await axon.tools.github.getPr(parseInt(domain))\n\n\u002F\u002F your tool — reads your repo's style guide\nconst standards = await axon.tools.repo.getCodingStandards()\n\nconst review = await axon.prompt(\"code-review\", { pr, standards })\nconst { stream } = axon.stream({ prompt: review })\n\nfor await (const entry of stream) {\n    if (entry.type === \"text\") process.stdout.write(entry.content)\n}\n","ts",[25,262,263,269,306,312,317,362,366,371,401,405,441,468,473,499,549],{"__ignoreMap":23},[28,264,265],{"class":30,"line":31},[28,266,268],{"class":267},"sOLPB","\u002F\u002F src\u002Fscripts\u002Fpr-review.ts\n",[28,270,271,275,279,283,286,289,292,296,299,303],{"class":30,"line":140},[28,272,274],{"class":273},"scz_3","const",[28,276,278],{"class":277},"sTNBD"," { ",[28,280,282],{"class":281},"s9McN","domain",[28,284,285],{"class":277}," } = ",[28,287,288],{"class":34},"defineArgs",[28,290,291],{"class":277},"\u003C{ ",[28,293,295],{"class":294},"s3F5K","pr",[28,297,298],{"class":277},": ",[28,300,302],{"class":301},"sNl3T","string",[28,304,305],{"class":277}," }>()\n",[28,307,308],{"class":30,"line":149},[28,309,311],{"emptyLinePlaceholder":310},true,"\n",[28,313,314],{"class":30,"line":158},[28,315,316],{"class":267},"\u002F\u002F module tool — fetches PR metadata and diff\n",[28,318,319,321,324,327,331,334,336,339,341,344,346,349,352,355,357,359],{"class":30,"line":167},[28,320,274],{"class":273},[28,322,323],{"class":281}," pr",[28,325,326],{"class":277}," = ",[28,328,330],{"class":329},"sYbnZ","await",[28,332,333],{"class":294}," axon",[28,335,57],{"class":277},[28,337,338],{"class":294},"tools",[28,340,57],{"class":277},[28,342,343],{"class":294},"github",[28,345,57],{"class":277},[28,347,348],{"class":34},"getPr",[28,350,351],{"class":277},"(",[28,353,354],{"class":34},"parseInt",[28,356,351],{"class":277},[28,358,282],{"class":294},[28,360,361],{"class":277},"))\n",[28,363,364],{"class":30,"line":176},[28,365,311],{"emptyLinePlaceholder":310},[28,367,368],{"class":30,"line":188},[28,369,370],{"class":267},"\u002F\u002F your tool — reads your repo's style guide\n",[28,372,373,375,378,380,382,384,386,388,390,393,395,398],{"class":30,"line":196},[28,374,274],{"class":273},[28,376,377],{"class":281}," standards",[28,379,326],{"class":277},[28,381,330],{"class":329},[28,383,333],{"class":294},[28,385,57],{"class":277},[28,387,338],{"class":294},[28,389,57],{"class":277},[28,391,392],{"class":294},"repo",[28,394,57],{"class":277},[28,396,397],{"class":34},"getCodingStandards",[28,399,400],{"class":277},"()\n",[28,402,403],{"class":30,"line":207},[28,404,311],{"emptyLinePlaceholder":310},[28,406,407,409,412,414,416,418,420,423,425,428,431,433,435,438],{"class":30,"line":217},[28,408,274],{"class":273},[28,410,411],{"class":281}," review",[28,413,326],{"class":277},[28,415,330],{"class":329},[28,417,333],{"class":294},[28,419,57],{"class":277},[28,421,422],{"class":34},"prompt",[28,424,351],{"class":277},[28,426,427],{"class":38},"\"code-review\"",[28,429,430],{"class":277},", { ",[28,432,295],{"class":294},[28,434,77],{"class":277},[28,436,437],{"class":294},"standards",[28,439,440],{"class":277}," })\n",[28,442,443,445,447,450,452,454,456,458,461,464,466],{"class":30,"line":225},[28,444,274],{"class":273},[28,446,278],{"class":277},[28,448,449],{"class":281},"stream",[28,451,285],{"class":277},[28,453,35],{"class":294},[28,455,57],{"class":277},[28,457,449],{"class":34},[28,459,460],{"class":277},"({ ",[28,462,463],{"class":294},"prompt:",[28,465,411],{"class":294},[28,467,440],{"class":277},[28,469,471],{"class":30,"line":470},12,[28,472,311],{"emptyLinePlaceholder":310},[28,474,476,479,482,485,487,490,493,496],{"class":30,"line":475},13,[28,477,478],{"class":329},"for",[28,480,481],{"class":329}," await",[28,483,484],{"class":277}," (",[28,486,274],{"class":273},[28,488,489],{"class":281}," entry",[28,491,492],{"class":273}," of",[28,494,495],{"class":294}," stream",[28,497,498],{"class":277},") {\n",[28,500,502,505,507,510,512,515,518,521,524,527,529,532,534,537,539,541,543,546],{"class":30,"line":501},14,[28,503,504],{"class":329},"    if",[28,506,484],{"class":277},[28,508,509],{"class":294},"entry",[28,511,57],{"class":277},[28,513,514],{"class":294},"type",[28,516,517],{"class":277}," === ",[28,519,520],{"class":38},"\"text\"",[28,522,523],{"class":277},") ",[28,525,526],{"class":294},"process",[28,528,57],{"class":277},[28,530,531],{"class":294},"stdout",[28,533,57],{"class":277},[28,535,536],{"class":34},"write",[28,538,351],{"class":277},[28,540,509],{"class":294},[28,542,57],{"class":277},[28,544,545],{"class":294},"content",[28,547,548],{"class":277},")\n",[28,550,552],{"class":30,"line":551},15,[28,553,554],{"class":277},"}\n",[14,556,557],{},"The agent sees module tools and your tools in the same typed namespace. From the agent's\nperspective, there's no distinction between a tool you wrote and one a module contributed.",[59,559,561],{"id":560},"hooks-from-modules","Hooks from modules",[14,563,564],{},"Modules emit named hooks when things happen. You subscribe in your plugins:",[18,566,568],{"className":258,"code":567,"language":260,"meta":23,"style":23},"\u002F\u002F server\u002Fplugins\u002Fgithub.ts\nexport default defineAxonPlugin(async axon => {\n    axon.hooks.hook(\"github:pr.opened\", async ({ number, title, head }) => {\n        const pr = await axon.tools.github.getPr(number)\n        const prompt = await axon.prompt(\"pr-review\", { pr })\n        void axon.request({ prompt, thread: `pr-${number}` })\n    })\n})\n",[25,569,570,575,599,647,678,706,743,748],{"__ignoreMap":23},[28,571,572],{"class":30,"line":31},[28,573,574],{"class":267},"\u002F\u002F server\u002Fplugins\u002Fgithub.ts\n",[28,576,577,580,583,586,588,591,593,596],{"class":30,"line":140},[28,578,579],{"class":329},"export",[28,581,582],{"class":329}," default",[28,584,585],{"class":34}," defineAxonPlugin",[28,587,351],{"class":277},[28,589,590],{"class":273},"async",[28,592,333],{"class":294},[28,594,595],{"class":273}," =>",[28,597,598],{"class":277}," {\n",[28,600,601,604,606,609,611,614,616,619,621,623,626,629,631,634,636,639,642,645],{"class":30,"line":149},[28,602,603],{"class":294},"    axon",[28,605,57],{"class":277},[28,607,608],{"class":294},"hooks",[28,610,57],{"class":277},[28,612,613],{"class":34},"hook",[28,615,351],{"class":277},[28,617,618],{"class":38},"\"github:pr.opened\"",[28,620,77],{"class":277},[28,622,590],{"class":273},[28,624,625],{"class":277}," ({ ",[28,627,628],{"class":294},"number",[28,630,77],{"class":277},[28,632,633],{"class":294},"title",[28,635,77],{"class":277},[28,637,638],{"class":294},"head",[28,640,641],{"class":277}," }) ",[28,643,644],{"class":273},"=>",[28,646,598],{"class":277},[28,648,649,652,654,656,658,660,662,664,666,668,670,672,674,676],{"class":30,"line":158},[28,650,651],{"class":273},"        const",[28,653,323],{"class":281},[28,655,326],{"class":277},[28,657,330],{"class":329},[28,659,333],{"class":294},[28,661,57],{"class":277},[28,663,338],{"class":294},[28,665,57],{"class":277},[28,667,343],{"class":294},[28,669,57],{"class":277},[28,671,348],{"class":34},[28,673,351],{"class":277},[28,675,628],{"class":294},[28,677,548],{"class":277},[28,679,680,682,685,687,689,691,693,695,697,700,702,704],{"class":30,"line":167},[28,681,651],{"class":273},[28,683,684],{"class":281}," prompt",[28,686,326],{"class":277},[28,688,330],{"class":329},[28,690,333],{"class":294},[28,692,57],{"class":277},[28,694,422],{"class":34},[28,696,351],{"class":277},[28,698,699],{"class":38},"\"pr-review\"",[28,701,430],{"class":277},[28,703,295],{"class":294},[28,705,440],{"class":277},[28,707,708,711,713,715,718,720,722,724,727,730,733,735,738,741],{"class":30,"line":176},[28,709,710],{"class":273},"        void",[28,712,333],{"class":294},[28,714,57],{"class":277},[28,716,717],{"class":34},"request",[28,719,460],{"class":277},[28,721,422],{"class":294},[28,723,77],{"class":277},[28,725,726],{"class":294},"thread:",[28,728,729],{"class":38}," `pr-",[28,731,732],{"class":273},"${",[28,734,628],{"class":294},[28,736,737],{"class":273},"}",[28,739,740],{"class":38},"`",[28,742,440],{"class":277},[28,744,745],{"class":30,"line":188},[28,746,747],{"class":277},"    })\n",[28,749,750],{"class":30,"line":196},[28,751,752],{"class":277},"})\n",[14,754,755],{},"The module routes the webhook and emits the hook. You decide what the agent does with it.\nThis separation means you can handle the same event differently from the module's default\nbehaviour, or handle it in multiple plugins for different purposes.",[59,757,759],{"id":758},"the-registry","The registry",[14,761,762],{},"Published modules are listed in the Axon registry. Browse them, read their source, and\nsee their declared policy before installing. A module's policy block is public — you can\nsee exactly what it's allowed to do on your machine before you install it.",[18,764,766],{"className":20,"code":765,"language":22,"meta":23,"style":23},"axon install @axon\u002Flinear\naxon install @axon\u002Fbrowser\naxon install @axon\u002Fpostgres\n",[25,767,768,777,786],{"__ignoreMap":23},[28,769,770,772,774],{"class":30,"line":31},[28,771,35],{"class":34},[28,773,39],{"class":38},[28,775,776],{"class":38}," @axon\u002Flinear\n",[28,778,779,781,783],{"class":30,"line":140},[28,780,35],{"class":34},[28,782,39],{"class":38},[28,784,785],{"class":38}," @axon\u002Fbrowser\n",[28,787,788,790,792],{"class":30,"line":149},[28,789,35],{"class":34},[28,791,39],{"class":38},[28,793,794],{"class":38}," @axon\u002Fpostgres\n",[14,796,797,798,57],{},"For authoring and publishing your own modules, see ",[799,800,5],"a",{"href":801},"\u002Fdocs\u002Fv2\u002Fmodules\u002Foverview",[803,804,805],"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 .scz_3, html code.shiki .scz_3{--shiki-default:#569CD6}html pre.shiki code .sTNBD, html code.shiki .sTNBD{--shiki-default:#D4D4D4}html pre.shiki code .s9McN, html code.shiki .s9McN{--shiki-default:#4FC1FF}html pre.shiki code .s3F5K, html code.shiki .s3F5K{--shiki-default:#9CDCFE}html pre.shiki code .sNl3T, html code.shiki .sNl3T{--shiki-default:#4EC9B0}html pre.shiki code .sYbnZ, html code.shiki .sYbnZ{--shiki-default:#C586C0}",{"title":23,"searchDepth":140,"depth":140,"links":807},[808,809,810,811,812,813],{"id":61,"depth":140,"text":62},{"id":119,"depth":140,"text":120},{"id":237,"depth":140,"text":238},{"id":251,"depth":140,"text":252},{"id":560,"depth":140,"text":561},{"id":758,"depth":140,"text":759},"md",{},"\u002Fdocs\u002Fv2\u002Fconcepts\u002Fmodules",{"title":5,"description":16},"docs\u002Fv2\u002Fconcepts\u002Fmodules","5Mpbxyy3flR4oqwjkgAwgsWes7_6Tg9t1A3Gc1PMSCY",1785671807770]