[{"data":1,"prerenderedAt":3061},["ShallowReactive",2],{"navigation":3,"content-tags:articles":150,"tag-claude-code":437},[4],{"title":5,"path":6,"stem":7,"children":8,"page":149},"Articles","\u002Farticles","articles",[9,13,17,21,25,29,33,37,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145],{"title":10,"path":11,"stem":12},"Building a Claude Code Plugin with Hooks","\u002Farticles\u002F2026-01-04-building-claude-code-plugin-with-hooks","articles\u002F2026-01-04-building-claude-code-plugin-with-hooks",{"title":14,"path":15,"stem":16},"Where should I validate? Everywhere, and for different reasons","\u002Farticles\u002F2026-04-18-validation-across-the-stack","articles\u002F2026-04-18-validation-across-the-stack",{"title":18,"path":19,"stem":20},"Error handling across the stack","\u002Farticles\u002F2026-04-23-error-handling-across-the-stack","articles\u002F2026-04-23-error-handling-across-the-stack",{"title":22,"path":23,"stem":24},"3 Ways to Run NestJS Cron Jobs When Running Multiple Instances","\u002Farticles\u002F3-ways-to-run-nestjs-cron-jobs-when-running-multiple-instances","articles\u002F3-ways-to-run-nestjs-cron-jobs-when-running-multiple-instances",{"title":26,"path":27,"stem":28},"Building a Custom Content Slider (Carousel) in Angular","\u002Farticles\u002Fbuilding-a-custom-content-slider-carousel-in-angular","articles\u002Fbuilding-a-custom-content-slider-carousel-in-angular",{"title":30,"path":31,"stem":32},"Building Jobven: Designing a Developer-Friendly API","\u002Farticles\u002Fbuilding-jobven-designing-a-developer-friendly-api","articles\u002Fbuilding-jobven-designing-a-developer-friendly-api",{"title":34,"path":35,"stem":36},"Building MapleStack: AWS S3 for Data Storage","\u002Farticles\u002Fbuilding-maplestack-aws-s3-for-data-storage","articles\u002Fbuilding-maplestack-aws-s3-for-data-storage",{"title":38,"path":39,"stem":40},"Building MapleStack: Enhancing Email Capabilities with Mailgun","\u002Farticles\u002Fbuilding-maplestack-enhancing-email-capabilities-with-mailgun","articles\u002Fbuilding-maplestack-enhancing-email-capabilities-with-mailgun",{"title":42,"path":43,"stem":44},"Building MapleStack: NestJS for Server-Side Operations","\u002Farticles\u002Fbuilding-maplestack-nestjs-for-server-side-operations","articles\u002Fbuilding-maplestack-nestjs-for-server-side-operations",{"title":46,"path":47,"stem":48},"Building MapleStack: PostgreSQL for Data Storage","\u002Farticles\u002Fbuilding-maplestack-postgresql-for-data-storage","articles\u002Fbuilding-maplestack-postgresql-for-data-storage",{"title":50,"path":51,"stem":52},"Building MapleStack: React for an interactive user interface","\u002Farticles\u002Fbuilding-maplestack-react-for-an-interactive-user-interface","articles\u002Fbuilding-maplestack-react-for-an-interactive-user-interface",{"title":54,"path":55,"stem":56},"Building MapleStack: Securing Connections with Let's Encrypt","\u002Farticles\u002Fbuilding-maplestack-securing-connections-with-lets-encrypt","articles\u002Fbuilding-maplestack-securing-connections-with-lets-encrypt",{"title":58,"path":59,"stem":60},"Building MapleStack: Simplifying User Authorization with AWS Cognito","\u002Farticles\u002Fbuilding-maplestack-simplifying-user-authorization-with-aws-cognito","articles\u002Fbuilding-maplestack-simplifying-user-authorization-with-aws-cognito",{"title":62,"path":63,"stem":64},"Building MapleStack: Tailwind CSS for Streamlined Styling","\u002Farticles\u002Fbuilding-maplestack-tailwind-css-for-streamlined-styling","articles\u002Fbuilding-maplestack-tailwind-css-for-streamlined-styling",{"title":66,"path":67,"stem":68},"Nigeria's Postcode API: How It Works and How to Test It","\u002Farticles\u002Fbuilding-on-nigerias-postcode-api","articles\u002Fbuilding-on-nigerias-postcode-api",{"title":70,"path":71,"stem":72},"Debugging Multiple NestJS Applications in VSCode","\u002Farticles\u002Fdebugging-multiple-nestjs-applications-in-vscode","articles\u002Fdebugging-multiple-nestjs-applications-in-vscode",{"title":74,"path":75,"stem":76},"Enums as arrays in PostgreSQL - Updated 2024","\u002Farticles\u002Fenums-as-arrays-in-postgresql","articles\u002Fenums-as-arrays-in-postgresql",{"title":78,"path":79,"stem":80},"FindChildcare.ca","\u002Farticles\u002Ffindchildcare-ca","articles\u002Ffindchildcare-ca",{"title":82,"path":83,"stem":84},"GraphQL Server - Apollo, KoaJS and Typescript implementation","\u002Farticles\u002Fgraphql-server-apollo-koajs-and-typescript-implementation","articles\u002Fgraphql-server-apollo-koajs-and-typescript-implementation",{"title":86,"path":87,"stem":88},"How I built MapleStack's waitlist with AI: ChatGPT vs Bard","\u002Farticles\u002Fhow-i-built-maplestacks-waitlist-with-ai-chatgpt-vs-bard","articles\u002Fhow-i-built-maplestacks-waitlist-with-ai-chatgpt-vs-bard",{"title":90,"path":91,"stem":92},"How to Integrate Google reCAPTCHA v3 with NestJS in 3 Easy Steps","\u002Farticles\u002Fhow-to-integrate-google-recaptcha-v3-with-nestjs-in-3-easy-steps","articles\u002Fhow-to-integrate-google-recaptcha-v3-with-nestjs-in-3-easy-steps",{"title":94,"path":95,"stem":96},"How to resolve a blacklisted domain","\u002Farticles\u002Fhow-to-resolve-a-blacklisted-domain","articles\u002Fhow-to-resolve-a-blacklisted-domain",{"title":98,"path":99,"stem":100},"Implementing WordPress-like Tags in Nuxt Content","\u002Farticles\u002Fimplementing-wordpress-like-tags-in-nuxt","articles\u002Fimplementing-wordpress-like-tags-in-nuxt",{"title":102,"path":103,"stem":104},"Jobven","\u002Farticles\u002Fjobven","articles\u002Fjobven",{"title":106,"path":107,"stem":108},"KidzLog","\u002Farticles\u002Fkidzlog","articles\u002Fkidzlog",{"title":110,"path":111,"stem":112},"MapleStack","\u002Farticles\u002Fmaplestack","articles\u002Fmaplestack",{"title":114,"path":115,"stem":116},"Migrating from WordPress to Nuxt","\u002Farticles\u002Fmigrating-from-wordpress-to-nuxt","articles\u002Fmigrating-from-wordpress-to-nuxt",{"title":118,"path":119,"stem":120},"My Initial Server Setup Checklist","\u002Farticles\u002Fmy-initial-server-setup-checklist","articles\u002Fmy-initial-server-setup-checklist",{"title":122,"path":123,"stem":124},"Pre-authorized transaction on the Stellar network","\u002Farticles\u002Fpre-authorized-transaction-on-the-stellar-network","articles\u002Fpre-authorized-transaction-on-the-stellar-network",{"title":126,"path":127,"stem":128},"Saza: Open Source mobile and desktop Stellar wallet release.","\u002Farticles\u002Fsaza-open-source-mobile-and-desktop-stellar-wallet-release","articles\u002Fsaza-open-source-mobile-and-desktop-stellar-wallet-release",{"title":130,"path":131,"stem":132},"SpellCheckMySite.com","\u002Farticles\u002Fspellcheckmysite-com","articles\u002Fspellcheckmysite-com",{"title":134,"path":135,"stem":136},"Using Check Constraints in PostgreSQL for Value Validation","\u002Farticles\u002Fusing-check-constraints-in-postgresql-for-value-validation","articles\u002Fusing-check-constraints-in-postgresql-for-value-validation",{"title":138,"path":139,"stem":140},"Using DataLoader in GraphQL","\u002Farticles\u002Fusing-dataloader-in-graphql","articles\u002Fusing-dataloader-in-graphql",{"title":142,"path":143,"stem":144},"Using Typescript in NodeJS development","\u002Farticles\u002Fusing-typescript-in-nodejs-development","articles\u002Fusing-typescript-in-nodejs-development",{"title":146,"path":147,"stem":148},"Welcome!","\u002Farticles\u002Fwelcome","articles\u002Fwelcome",false,[151,162,172,182,190,199,207,215,224,232,240,248,256,264,273,283,291,299,307,315,323,332,340,348,356,364,372,381,389,397,405,413,421,429],{"id":152,"color":153,"description":154,"extension":155,"meta":156,"name":157,"slug":158,"stem":159,"__hash__":160,"count":161},"tags\u002Ftags\u002Fai.yml","purple","Artificial Intelligence and machine learning topics","yml",{},"AI","ai","tags\u002Fai","3Kbwn1GafRMDqK3ErYiBohkqyMbs4y-gmPA5L0htrtI",2,{"id":163,"color":164,"description":165,"extension":155,"meta":166,"name":167,"slug":168,"stem":169,"__hash__":170,"count":171},"tags\u002Ftags\u002Fangular.yml","red","Angular framework tutorials and component development",{},"Angular","angular","tags\u002Fangular","4JdHB81zNrypA0P8D8gi97pj0Ds9E3_IW7YbLvnzs1k",1,{"id":173,"color":174,"description":175,"extension":155,"meta":176,"name":177,"slug":178,"stem":179,"__hash__":180,"count":181},"tags\u002Ftags\u002Fapi.yml","blue","Designing, building and consuming web APIs",{},"API","api","tags\u002Fapi","A0x8MlouPoSEbat0Yj1-_xytY1yBgyVkGIlY-bTzPUM",3,{"id":183,"color":184,"description":185,"extension":155,"meta":186,"name":5,"slug":7,"stem":187,"__hash__":188,"count":189},"tags\u002Ftags\u002Farticles.yml","gray","General articles and blog posts",{},"tags\u002Farticles","iT5XsTSsj5v9-aLrtgHxDyk_QCYfK8mlea2vVyCdcZM",8,{"id":191,"color":192,"description":193,"extension":155,"meta":194,"name":195,"slug":196,"stem":197,"__hash__":198,"count":181},"tags\u002Ftags\u002Faws.yml","orange","Amazon Web Services cloud platform tutorials and integrations",{},"AWS","aws","tags\u002Faws","i2eOUxfMNR5PbOtUVc7VAbZk5Y7LupicySpVtJY24_A",{"id":200,"color":174,"description":201,"extension":155,"meta":202,"name":203,"slug":204,"stem":205,"__hash__":206,"count":171},"tags\u002Ftags\u002Fbard.yml","Google Bard AI assistant",{},"Bard","bard","tags\u002Fbard","uy9j-VgMeapYwgVu98-Df6yqWCXCAwfLn5j8Sb15ZmE",{"id":208,"color":164,"description":209,"extension":155,"meta":210,"name":211,"slug":212,"stem":213,"__hash__":214,"count":189},"tags\u002Ftags\u002Fbuilding-maplestack.yml","Series on building the MapleStack platform",{},"Building MapleStack","building-maplestack","tags\u002Fbuilding-maplestack","hIpKigdKwKbxd8aqva_KMKT-hpxpLDOCnQ9qoRGyjPg",{"id":216,"color":217,"description":218,"extension":155,"meta":219,"name":220,"slug":221,"stem":222,"__hash__":223,"count":171},"tags\u002Ftags\u002Fchatgpt.yml","green","OpenAI ChatGPT integration and usage",{},"ChatGPT","chatgpt","tags\u002Fchatgpt","32dptlACBGlEhrLxxih3XBVQeeqayyl3nUn4xrjh6mM",{"id":225,"color":153,"description":226,"extension":155,"meta":227,"name":228,"slug":229,"stem":230,"__hash__":231,"count":171},"tags\u002Ftags\u002Fclaude-code.yml","Building with and extending Anthropic's Claude Code",{},"Claude Code","claude-code","tags\u002Fclaude-code","DILmAuTs9y1dm4L44wLW-52LfKAjbFlccJOJOpIBnD0",{"id":233,"color":192,"description":234,"extension":155,"meta":235,"name":236,"slug":237,"stem":238,"__hash__":239,"count":171},"tags\u002Ftags\u002Fdataloader.yml","DataLoader utility for batching and caching",{},"DataLoader","dataloader","tags\u002Fdataloader","LmXdDjUElkWFv52Zjjjs9iSl5ho6XzjgngiwhkAnlLk",{"id":241,"color":174,"description":242,"extension":155,"meta":243,"name":244,"slug":245,"stem":246,"__hash__":247,"count":171},"tags\u002Ftags\u002Fdns.yml","Domain Name System configuration and troubleshooting",{},"DNS","dns","tags\u002Fdns","-ouuVgZR4CIiCKyOp51RQoXCKDvhpBV0KMUf1zqLXNc",{"id":249,"color":174,"description":250,"extension":155,"meta":251,"name":252,"slug":253,"stem":254,"__hash__":255,"count":161},"tags\u002Ftags\u002Fengineering.yml","Software engineering practice, craft and technical decision making",{},"Engineering","engineering","tags\u002Fengineering","t3NT39qm9R9NCBT8lwSuG9cxZZZa4Xds-X7AINZw-3o",{"id":257,"color":164,"description":258,"extension":155,"meta":259,"name":260,"slug":261,"stem":262,"__hash__":263,"count":171},"tags\u002Ftags\u002Ferror-handling.yml","Handling, surfacing and recovering from failure across a stack",{},"Error Handling","error-handling","tags\u002Ferror-handling","jxCFis914HceisiNgt920hxUAe4KgCulUZGLzKcNspg",{"id":265,"color":266,"description":267,"extension":155,"meta":268,"name":269,"slug":270,"stem":271,"__hash__":272,"count":161},"tags\u002Ftags\u002Fgraphql.yml","pink","GraphQL API development, schema design, and implementation guides",{},"GraphQL","graphql","tags\u002Fgraphql","1wfWwIg4deU-5JedMVdkw9j9mualhUlJ1MZDgb6V7R0",{"id":274,"color":275,"description":276,"extension":155,"meta":277,"name":278,"slug":279,"stem":280,"__hash__":281,"count":282},"tags\u002Ftags\u002Fjavascript.yml","yellow","JavaScript programming language tutorials and best practices",{},"JavaScript","javascript","tags\u002Fjavascript","qZheXj7oAA3rukxJWCK5SLSe3-_mCwMq0OAi9BtEFRw",6,{"id":284,"color":184,"description":285,"extension":155,"meta":286,"name":287,"slug":288,"stem":289,"__hash__":290,"count":161},"tags\u002Ftags\u002Fkoajs.yml","Koa.js web framework for Node.js",{},"KoaJS","koajs","tags\u002Fkoajs","KVPDsU-wIMo46n6-bdbF-dRkiwlRbz3RJP7K9vSOrmQ",{"id":292,"color":217,"description":293,"extension":155,"meta":294,"name":295,"slug":296,"stem":297,"__hash__":298,"count":171},"tags\u002Ftags\u002Fletsencrypt.yml","Free SSL\u002FTLS certificates with Let's Encrypt",{},"Let's Encrypt","letsencrypt","tags\u002Fletsencrypt","0s8AZbiIKoWGwiCNeWEc_OIo3aDAJlkSB5fjQlgcGNk",{"id":300,"color":184,"description":301,"extension":155,"meta":302,"name":303,"slug":304,"stem":305,"__hash__":306,"count":171},"tags\u002Ftags\u002Flinux.yml","Linux server administration and command-line tools",{},"Linux","linux","tags\u002Flinux","YmvWMX2B2AdXzWfUycxqXt4m9jSgpLE8q7eW6FeiJPk",{"id":308,"color":164,"description":309,"extension":155,"meta":310,"name":110,"slug":311,"stem":312,"__hash__":313,"count":314},"tags\u002Ftags\u002Fmaplestack.yml","Building MapleStack job board platform",{},"maplestack","tags\u002Fmaplestack","v2dZpc6OuxQeK2KTQIC3RYfv4FwNzIAa0VDTzLjWjAA",9,{"id":316,"color":192,"description":317,"extension":155,"meta":318,"name":319,"slug":320,"stem":321,"__hash__":322,"count":171},"tags\u002Ftags\u002Fmigration.yml","Platform and data migration guides",{},"Migration","migration","tags\u002Fmigration","scw_ZTGUersSET1o4l_NAkZ3cDKiplB53LqtFRvE7Yc",{"id":324,"color":164,"description":325,"extension":155,"meta":326,"name":327,"slug":328,"stem":329,"__hash__":330,"count":331},"tags\u002Ftags\u002Fnestjs.yml","Articles about NestJS framework for building efficient, scalable Node.js server-side applications",{},"NestJS","nestjs","tags\u002Fnestjs","GQFi18GrTd6pSmws7rOsyKTbLATtQwywfsZpQwhCsI0",4,{"id":333,"color":217,"description":334,"extension":155,"meta":335,"name":336,"slug":337,"stem":338,"__hash__":339,"count":181},"tags\u002Ftags\u002Fnodejs.yml","Node.js runtime environment and server-side JavaScript",{},"Node.js","nodejs","tags\u002Fnodejs","lusY1Ii4Hd3O6gLdY2NbhHchd3YAT_Q1QOm0BqrfY_4",{"id":341,"color":217,"description":342,"extension":155,"meta":343,"name":344,"slug":345,"stem":346,"__hash__":347,"count":181},"tags\u002Ftags\u002Fnuxt.yml","Nuxt.js framework for Vue.js applications",{},"Nuxt","nuxt","tags\u002Fnuxt","QwQk7HOatKzP3xW3-ie3L7_OJ7O8hbqCT2E8AUtrV2o",{"id":349,"color":192,"description":350,"extension":155,"meta":351,"name":352,"slug":353,"stem":354,"__hash__":355,"count":171},"tags\u002Ftags\u002Fplugins.yml","Extending tools and frameworks through plugin systems",{},"Plugins","plugins","tags\u002Fplugins","gShR9UaVAM-OLItdfQRg89U_mFSX53KgzFge6eQGSaE",{"id":357,"color":174,"description":358,"extension":155,"meta":359,"name":360,"slug":361,"stem":362,"__hash__":363,"count":181},"tags\u002Ftags\u002Fpostgresql.yml","PostgreSQL database tutorials, tips, and best practices",{},"PostgreSQL","postgresql","tags\u002Fpostgresql","o-29A3fv27MHMpunvcXvumOEdfKJJ_Wu6s_Wdej2ynI",{"id":365,"color":153,"description":366,"extension":155,"meta":367,"name":368,"slug":369,"stem":370,"__hash__":371,"count":189},"tags\u002Ftags\u002Fprojects.yml","Articles about personal and professional projects",{},"Projects","projects","tags\u002Fprojects","L834U-TbUh7RZkMdabAGEHgsgGb1hUWpWeIomHD81sE",{"id":373,"color":374,"description":375,"extension":155,"meta":376,"name":377,"slug":378,"stem":379,"__hash__":380,"count":161},"tags\u002Ftags\u002Freact.yml","cyan","React library guides for building user interfaces",{},"React","react","tags\u002Freact","Cl0931Ka3nLB6sYwUevYf3q--ugJfBakfGOEXDpY6Mw",{"id":382,"color":374,"description":383,"extension":155,"meta":384,"name":385,"slug":386,"stem":387,"__hash__":388,"count":171},"tags\u002Ftags\u002Fsaas.yml","Building and running software as a service products",{},"SaaS","saas","tags\u002Fsaas","74u9GtZbJ7IF37YdnFP6JagBgw0PblIZK2mc3r8bbew",{"id":390,"color":174,"description":391,"extension":155,"meta":392,"name":393,"slug":394,"stem":395,"__hash__":396,"count":171},"tags\u002Ftags\u002Fstellar.yml","Stellar blockchain network and cryptocurrency development",{},"Stellar","stellar","tags\u002Fstellar","H71kcSAHbcG_q3Y5cFkgonNN5uH5JxVsXlZjLaotbnk",{"id":398,"color":374,"description":399,"extension":155,"meta":400,"name":401,"slug":402,"stem":403,"__hash__":404,"count":171},"tags\u002Ftags\u002Ftailwindcss.yml","Tailwind CSS utility-first styling framework",{},"Tailwind CSS","tailwindcss","tags\u002Ftailwindcss","_Q7hBntSUWoSWUcYMwmpz1kfCE7RVlSTR9U86k3av_g",{"id":406,"color":174,"description":407,"extension":155,"meta":408,"name":409,"slug":410,"stem":411,"__hash__":412,"count":189},"tags\u002Ftags\u002Ftypescript.yml","TypeScript language features, type safety, and development tips",{},"TypeScript","typescript","tags\u002Ftypescript","zv13aSlv3NhTqdsNRYQ0pKjE5j8rZZk5zv2kD6guG4c",{"id":414,"color":217,"description":415,"extension":155,"meta":416,"name":417,"slug":418,"stem":419,"__hash__":420,"count":171},"tags\u002Ftags\u002Fvalidation.yml","Validating input and data at every layer of an application",{},"Validation","validation","tags\u002Fvalidation","Y2whDaQYOSOUCRjs2TcEedcEvVA8a2b3kq_-xULT3gY",{"id":422,"color":217,"description":423,"extension":155,"meta":424,"name":425,"slug":426,"stem":427,"__hash__":428,"count":171},"tags\u002Ftags\u002Fvps.yml","Virtual Private Server setup and management",{},"VPS","vps","tags\u002Fvps","SOzIPECxOX5g_l0rF3QhJEWwMnOeRe0htUuhWc62PXE",{"id":430,"color":174,"description":431,"extension":155,"meta":432,"name":433,"slug":434,"stem":435,"__hash__":436,"count":161},"tags\u002Ftags\u002Fwordpress.yml","WordPress CMS and related topics",{},"WordPress","wordpress","tags\u002Fwordpress","FiVBFOXCbR45_HKOqwcZAu9dDru5YOemYUcilPwarYQ",{"tag":438,"articles":440,"relatedTags":3052},{"id":225,"color":153,"description":226,"extension":155,"meta":439,"name":228,"slug":229,"stem":230,"__hash__":231},{},[441],{"id":442,"title":10,"author":443,"body":447,"categories":3040,"date":3042,"description":3043,"extension":3044,"head":3045,"image":3046,"meta":3047,"minRead":767,"navigation":1115,"ogImage":3045,"path":11,"robots":3045,"schemaOrg":3045,"seo":3048,"sitemap":3049,"stem":12,"tags":3050,"__hash__":3051},"articles\u002Farticles\u002F2026-01-04-building-claude-code-plugin-with-hooks.md",{"name":444,"avatar":445},"Peter Oliha",{"src":446,"alt":444},"\u002Fassets\u002Fimages\u002Fauthors\u002Fpeter-oliha.jpg",{"type":448,"value":449,"toc":3025},"minimark",[450,454,465,468,473,476,487,494,581,584,603,607,610,633,639,1056,1062,1067,1070,1088,1091,1542,1549,1553,1556,1619,1622,1626,1629,1677,1680,1684,1687,1693,1978,1981,1984,1988,1998,2100,2103,2109,2113,2116,2119,2456,2459,2839,2842,2846,2849,2923,2927,2933,2942,2948,2954,2960,2964,2967,2973,2983,2989,2995,2998,3002,3008,3015,3018,3021],[451,452,453],"p",{},"Claude Code has a plugin system that lets you extend its behavior. Hooks run shell commands at specific points in a session, skills give Claude new capabilities, and commands let users trigger actions directly. The documentation covers each piece, but I wanted to see how they work together.",[451,455,456,457,464],{},"So I built ",[458,459,463],"a",{"href":460,"rel":461},"https:\u002F\u002Fgithub.com\u002Fpoliha\u002Fclaude-overflow",[462],"nofollow","Claude Overflow"," - a plugin that turns your AI conversations into a personal StackOverflow-style knowledge base. Every technical Q&A gets saved as a markdown file and served in a searchable web UI.",[451,466,467],{},"Is it practical? Debatable. But it uses every major plugin feature, so it's a good way to learn the system.",[469,470,472],"h2",{"id":471},"plugin-structure","Plugin Structure",[451,474,475],{},"A Claude Code plugin lives in a directory with a specific structure:",[477,478,483],"pre",{"className":479,"code":481,"language":482},[480],"language-text","claude-overflow\u002F\n└── plugin\u002F\n    ├── .claude-plugin\u002F\n    │   └── plugin.json          # Plugin manifest\n    ├── hooks\u002F\n    │   └── hooks.json           # Lifecycle hooks\n    ├── commands\u002F\n    │   └── overflow.md          # Slash command\n    ├── skills\u002F\n    │   └── overflow\u002F\n    │       └── SKILL.md         # Model-invoked skill\n    └── scripts\u002F\n        ├── setup.sh             # Called by SessionStart\n        └── cleanup.sh           # Called by SessionEnd\n","text",[484,485,481],"code",{"__ignoreMap":486},"",[451,488,489,490,493],{},"The ",[484,491,492],{},".claude-plugin\u002Fplugin.json"," is the manifest:",[477,495,499],{"className":496,"code":497,"language":498,"meta":486,"style":486},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"name\": \"claude-overflow\",\n  \"description\": \"StackOverflow-style Q&A archiving\",\n  \"version\": \"2.0.0\"\n}\n","json",[484,500,501,509,536,556,575],{"__ignoreMap":486},[502,503,505],"span",{"class":504,"line":171},"line",[502,506,508],{"class":507},"sMK4o","{\n",[502,510,511,514,518,521,524,527,531,533],{"class":504,"line":161},[502,512,513],{"class":507},"  \"",[502,515,517],{"class":516},"spNyl","name",[502,519,520],{"class":507},"\"",[502,522,523],{"class":507},":",[502,525,526],{"class":507}," \"",[502,528,530],{"class":529},"sfazB","claude-overflow",[502,532,520],{"class":507},[502,534,535],{"class":507},",\n",[502,537,538,540,543,545,547,549,552,554],{"class":504,"line":181},[502,539,513],{"class":507},[502,541,542],{"class":516},"description",[502,544,520],{"class":507},[502,546,523],{"class":507},[502,548,526],{"class":507},[502,550,551],{"class":529},"StackOverflow-style Q&A archiving",[502,553,520],{"class":507},[502,555,535],{"class":507},[502,557,558,560,563,565,567,569,572],{"class":504,"line":331},[502,559,513],{"class":507},[502,561,562],{"class":516},"version",[502,564,520],{"class":507},[502,566,523],{"class":507},[502,568,526],{"class":507},[502,570,571],{"class":529},"2.0.0",[502,573,574],{"class":507},"\"\n",[502,576,578],{"class":504,"line":577},5,[502,579,580],{"class":507},"}\n",[451,582,583],{},"You load the plugin with:",[477,585,589],{"className":586,"code":587,"language":588,"meta":486,"style":486},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","claude --plugin-dir \u002Fpath\u002Fto\u002Fclaude-overflow\u002Fplugin\n","bash",[484,590,591],{"__ignoreMap":486},[502,592,593,597,600],{"class":504,"line":171},[502,594,596],{"class":595},"sBMFI","claude",[502,598,599],{"class":529}," --plugin-dir",[502,601,602],{"class":529}," \u002Fpath\u002Fto\u002Fclaude-overflow\u002Fplugin\n",[469,604,606],{"id":605},"hooks-running-code-at-lifecycle-events","Hooks: Running Code at Lifecycle Events",[451,608,609],{},"Hooks let you run shell commands when specific events occur. Claude Code supports three hook types:",[611,612,613,621,627],"ul",{},[614,615,616,620],"li",{},[617,618,619],"strong",{},"SessionStart"," - Runs once when a session begins",[614,622,623,626],{},[617,624,625],{},"UserPromptSubmit"," - Runs every time the user sends a message",[614,628,629,632],{},[617,630,631],{},"SessionEnd"," - Runs when the session closes",[451,634,635,636,523],{},"Here's how Claude Overflow uses all three in ",[484,637,638],{},"hooks\u002Fhooks.json",[477,640,642],{"className":496,"code":641,"language":498,"meta":486,"style":486},"{\n  \"hooks\": {\n    \"SessionStart\": [\n      {\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"bash \\\"${CLAUDE_PLUGIN_ROOT}\u002Fscripts\u002Fsetup.sh\\\"\",\n            \"timeout\": 120\n          }\n        ]\n      }\n    ],\n    \"UserPromptSubmit\": [\n      {\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"echo '{\\\"hookSpecificOutput\\\":{\\\"hookEventName\\\":\\\"UserPromptSubmit\\\",\\\"additionalContext\\\":\\\"For technical questions, use the overflow skill.\\\"}}'\"\n          }\n        ]\n      }\n    ],\n    \"SessionEnd\": [\n      {\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"bash \\\"${CLAUDE_PLUGIN_ROOT}\u002Fscripts\u002Fcleanup.sh\\\"\",\n            \"timeout\": 10\n          }\n        ]\n      }\n    ]\n  }\n}\n",[484,643,644,648,662,676,681,695,700,723,751,765,771,777,783,789,802,807,820,825,844,909,914,919,924,929,942,947,960,965,984,1010,1024,1029,1034,1039,1045,1051],{"__ignoreMap":486},[502,645,646],{"class":504,"line":171},[502,647,508],{"class":507},[502,649,650,652,655,657,659],{"class":504,"line":161},[502,651,513],{"class":507},[502,653,654],{"class":516},"hooks",[502,656,520],{"class":507},[502,658,523],{"class":507},[502,660,661],{"class":507}," {\n",[502,663,664,667,669,671,673],{"class":504,"line":181},[502,665,666],{"class":507},"    \"",[502,668,619],{"class":595},[502,670,520],{"class":507},[502,672,523],{"class":507},[502,674,675],{"class":507}," [\n",[502,677,678],{"class":504,"line":331},[502,679,680],{"class":507},"      {\n",[502,682,683,686,689,691,693],{"class":504,"line":577},[502,684,685],{"class":507},"        \"",[502,687,654],{"class":688},"sbssI",[502,690,520],{"class":507},[502,692,523],{"class":507},[502,694,675],{"class":507},[502,696,697],{"class":504,"line":282},[502,698,699],{"class":507},"          {\n",[502,701,703,706,710,712,714,716,719,721],{"class":504,"line":702},7,[502,704,705],{"class":507},"            \"",[502,707,709],{"class":708},"swJcz","type",[502,711,520],{"class":507},[502,713,523],{"class":507},[502,715,526],{"class":507},[502,717,718],{"class":529},"command",[502,720,520],{"class":507},[502,722,535],{"class":507},[502,724,725,727,729,731,733,735,738,742,745,747,749],{"class":504,"line":189},[502,726,705],{"class":507},[502,728,718],{"class":708},[502,730,520],{"class":507},[502,732,523],{"class":507},[502,734,526],{"class":507},[502,736,737],{"class":529},"bash ",[502,739,741],{"class":740},"sTEyZ","\\\"",[502,743,744],{"class":529},"${CLAUDE_PLUGIN_ROOT}\u002Fscripts\u002Fsetup.sh",[502,746,741],{"class":740},[502,748,520],{"class":507},[502,750,535],{"class":507},[502,752,753,755,758,760,762],{"class":504,"line":314},[502,754,705],{"class":507},[502,756,757],{"class":708},"timeout",[502,759,520],{"class":507},[502,761,523],{"class":507},[502,763,764],{"class":688}," 120\n",[502,766,768],{"class":504,"line":767},10,[502,769,770],{"class":507},"          }\n",[502,772,774],{"class":504,"line":773},11,[502,775,776],{"class":507},"        ]\n",[502,778,780],{"class":504,"line":779},12,[502,781,782],{"class":507},"      }\n",[502,784,786],{"class":504,"line":785},13,[502,787,788],{"class":507},"    ],\n",[502,790,792,794,796,798,800],{"class":504,"line":791},14,[502,793,666],{"class":507},[502,795,625],{"class":595},[502,797,520],{"class":507},[502,799,523],{"class":507},[502,801,675],{"class":507},[502,803,805],{"class":504,"line":804},15,[502,806,680],{"class":507},[502,808,810,812,814,816,818],{"class":504,"line":809},16,[502,811,685],{"class":507},[502,813,654],{"class":688},[502,815,520],{"class":507},[502,817,523],{"class":507},[502,819,675],{"class":507},[502,821,823],{"class":504,"line":822},17,[502,824,699],{"class":507},[502,826,828,830,832,834,836,838,840,842],{"class":504,"line":827},18,[502,829,705],{"class":507},[502,831,709],{"class":708},[502,833,520],{"class":507},[502,835,523],{"class":507},[502,837,526],{"class":507},[502,839,718],{"class":529},[502,841,520],{"class":507},[502,843,535],{"class":507},[502,845,847,849,851,853,855,857,860,862,865,867,870,872,875,877,879,881,883,885,888,890,893,895,897,899,902,904,907],{"class":504,"line":846},19,[502,848,705],{"class":507},[502,850,718],{"class":708},[502,852,520],{"class":507},[502,854,523],{"class":507},[502,856,526],{"class":507},[502,858,859],{"class":529},"echo '{",[502,861,741],{"class":740},[502,863,864],{"class":529},"hookSpecificOutput",[502,866,741],{"class":740},[502,868,869],{"class":529},":{",[502,871,741],{"class":740},[502,873,874],{"class":529},"hookEventName",[502,876,741],{"class":740},[502,878,523],{"class":529},[502,880,741],{"class":740},[502,882,625],{"class":529},[502,884,741],{"class":740},[502,886,887],{"class":529},",",[502,889,741],{"class":740},[502,891,892],{"class":529},"additionalContext",[502,894,741],{"class":740},[502,896,523],{"class":529},[502,898,741],{"class":740},[502,900,901],{"class":529},"For technical questions, use the overflow skill.",[502,903,741],{"class":740},[502,905,906],{"class":529},"}}'",[502,908,574],{"class":507},[502,910,912],{"class":504,"line":911},20,[502,913,770],{"class":507},[502,915,917],{"class":504,"line":916},21,[502,918,776],{"class":507},[502,920,922],{"class":504,"line":921},22,[502,923,782],{"class":507},[502,925,927],{"class":504,"line":926},23,[502,928,788],{"class":507},[502,930,932,934,936,938,940],{"class":504,"line":931},24,[502,933,666],{"class":507},[502,935,631],{"class":595},[502,937,520],{"class":507},[502,939,523],{"class":507},[502,941,675],{"class":507},[502,943,945],{"class":504,"line":944},25,[502,946,680],{"class":507},[502,948,950,952,954,956,958],{"class":504,"line":949},26,[502,951,685],{"class":507},[502,953,654],{"class":688},[502,955,520],{"class":507},[502,957,523],{"class":507},[502,959,675],{"class":507},[502,961,963],{"class":504,"line":962},27,[502,964,699],{"class":507},[502,966,968,970,972,974,976,978,980,982],{"class":504,"line":967},28,[502,969,705],{"class":507},[502,971,709],{"class":708},[502,973,520],{"class":507},[502,975,523],{"class":507},[502,977,526],{"class":507},[502,979,718],{"class":529},[502,981,520],{"class":507},[502,983,535],{"class":507},[502,985,987,989,991,993,995,997,999,1001,1004,1006,1008],{"class":504,"line":986},29,[502,988,705],{"class":507},[502,990,718],{"class":708},[502,992,520],{"class":507},[502,994,523],{"class":507},[502,996,526],{"class":507},[502,998,737],{"class":529},[502,1000,741],{"class":740},[502,1002,1003],{"class":529},"${CLAUDE_PLUGIN_ROOT}\u002Fscripts\u002Fcleanup.sh",[502,1005,741],{"class":740},[502,1007,520],{"class":507},[502,1009,535],{"class":507},[502,1011,1013,1015,1017,1019,1021],{"class":504,"line":1012},30,[502,1014,705],{"class":507},[502,1016,757],{"class":708},[502,1018,520],{"class":507},[502,1020,523],{"class":507},[502,1022,1023],{"class":688}," 10\n",[502,1025,1027],{"class":504,"line":1026},31,[502,1028,770],{"class":507},[502,1030,1032],{"class":504,"line":1031},32,[502,1033,776],{"class":507},[502,1035,1037],{"class":504,"line":1036},33,[502,1038,782],{"class":507},[502,1040,1042],{"class":504,"line":1041},34,[502,1043,1044],{"class":507},"    ]\n",[502,1046,1048],{"class":504,"line":1047},35,[502,1049,1050],{"class":507},"  }\n",[502,1052,1054],{"class":504,"line":1053},36,[502,1055,580],{"class":507},[451,1057,489,1058,1061],{},[484,1059,1060],{},"${CLAUDE_PLUGIN_ROOT}"," variable points to your plugin directory.",[1063,1064,1066],"h3",{"id":1065},"sessionstart-setting-up-the-environment","SessionStart: Setting Up the Environment",[451,1068,1069],{},"When a session starts, I need to:",[1071,1072,1073,1076,1079,1082,1085],"ol",{},[614,1074,1075],{},"Create a temp directory for this session",[614,1077,1078],{},"Copy the Nuxt template",[614,1080,1081],{},"Install dependencies",[614,1083,1084],{},"Start the dev server",[614,1086,1087],{},"Tell Claude where to save files",[451,1089,1090],{},"The setup script handles this:",[477,1092,1094],{"className":586,"code":1093,"language":588,"meta":486,"style":486},"#!\u002Fbin\u002Fbash\nset -e\n\n# Parse session_id from stdin JSON\nINPUT=$(cat)\nSESSION_ID=$(echo \"$INPUT\" | grep -o '\"session_id\"[[:space:]]*:[[:space:]]*\"[^\"]*\"' | sed 's\u002F.*\"session_id\"[[:space:]]*:[[:space:]]*\"\\([^\"]*\\)\".*\u002F\\1\u002F')\n\nSESSION_ID=\"${SESSION_ID:-$$}\"\nOVERFLOW_DIR=\"\u002Ftmp\u002Fclaude-overflow-${SESSION_ID}\"\nPLUGIN_ROOT=\"${CLAUDE_PLUGIN_ROOT:-$(dirname \"$(dirname \"$0\")\")}\"\nPORT=4242\n\n# Find available port\nwhile ! is_port_available $PORT; do\n    PORT=$((PORT + 1))\ndone\n\n# Create directory and copy template\nmkdir -p \"$OVERFLOW_DIR\"\ncp -r \"$PLUGIN_ROOT\u002Ftemplate\u002F\"* \"$OVERFLOW_DIR\u002F\"\nmkdir -p \"$OVERFLOW_DIR\u002Fcontent\u002Fanswers\"\n\n# Install and start\ncd \"$OVERFLOW_DIR\"\npnpm install --silent\nnohup pnpm dev > \u002Ftmp\u002Fclaude-overflow-${SESSION_ID}.log 2>&1 &\nsleep 3\n\n# Output config for Claude's context\ncat \u003C\u003C EOF\n{\n  \"hookSpecificOutput\": {\n    \"hookEventName\": \"SessionStart\",\n    \"additionalContext\": \"[CLAUDE OVERFLOW CONFIG] Content path: ${OVERFLOW_DIR}\u002Fcontent\u002Fanswers | Server URL: http:\u002F\u002Flocalhost:${PORT}\"\n  }\n}\nEOF\n",[484,1095,1096,1102,1111,1117,1122,1136,1185,1189,1210,1229,1268,1278,1282,1287,1308,1327,1332,1336,1341,1356,1386,1401,1405,1410,1421,1432,1465,1473,1477,1482,1492,1496,1501,1506,1528,1532,1536],{"__ignoreMap":486},[502,1097,1098],{"class":504,"line":171},[502,1099,1101],{"class":1100},"sHwdD","#!\u002Fbin\u002Fbash\n",[502,1103,1104,1108],{"class":504,"line":161},[502,1105,1107],{"class":1106},"s2Zo4","set",[502,1109,1110],{"class":529}," -e\n",[502,1112,1113],{"class":504,"line":181},[502,1114,1116],{"emptyLinePlaceholder":1115},true,"\n",[502,1118,1119],{"class":504,"line":331},[502,1120,1121],{"class":1100},"# Parse session_id from stdin JSON\n",[502,1123,1124,1127,1130,1133],{"class":504,"line":577},[502,1125,1126],{"class":740},"INPUT",[502,1128,1129],{"class":507},"=$(",[502,1131,1132],{"class":595},"cat",[502,1134,1135],{"class":507},")\n",[502,1137,1138,1141,1143,1146,1148,1151,1153,1156,1159,1162,1165,1168,1171,1173,1176,1178,1181,1183],{"class":504,"line":282},[502,1139,1140],{"class":740},"SESSION_ID",[502,1142,1129],{"class":507},[502,1144,1145],{"class":1106},"echo",[502,1147,526],{"class":507},[502,1149,1150],{"class":740},"$INPUT",[502,1152,520],{"class":507},[502,1154,1155],{"class":507}," |",[502,1157,1158],{"class":595}," grep",[502,1160,1161],{"class":529}," -o",[502,1163,1164],{"class":507}," '",[502,1166,1167],{"class":529},"\"session_id\"[[:space:]]*:[[:space:]]*\"[^\"]*\"",[502,1169,1170],{"class":507},"'",[502,1172,1155],{"class":507},[502,1174,1175],{"class":595}," sed",[502,1177,1164],{"class":507},[502,1179,1180],{"class":529},"s\u002F.*\"session_id\"[[:space:]]*:[[:space:]]*\"\\([^\"]*\\)\".*\u002F\\1\u002F",[502,1182,1170],{"class":507},[502,1184,1135],{"class":507},[502,1186,1187],{"class":504,"line":702},[502,1188,1116],{"emptyLinePlaceholder":1115},[502,1190,1191,1193,1196,1199,1201,1204,1207],{"class":504,"line":189},[502,1192,1140],{"class":740},[502,1194,1195],{"class":507},"=",[502,1197,1198],{"class":507},"\"${",[502,1200,1140],{"class":740},[502,1202,1203],{"class":507},":-",[502,1205,1206],{"class":740},"$$",[502,1208,1209],{"class":507},"}\"\n",[502,1211,1212,1215,1217,1219,1222,1225,1227],{"class":504,"line":314},[502,1213,1214],{"class":740},"OVERFLOW_DIR",[502,1216,1195],{"class":507},[502,1218,520],{"class":507},[502,1220,1221],{"class":529},"\u002Ftmp\u002Fclaude-overflow-",[502,1223,1224],{"class":507},"${",[502,1226,1140],{"class":740},[502,1228,1209],{"class":507},[502,1230,1231,1234,1236,1238,1241,1243,1246,1249,1252,1254,1256,1260,1263,1266],{"class":504,"line":767},[502,1232,1233],{"class":740},"PLUGIN_ROOT",[502,1235,1195],{"class":507},[502,1237,1198],{"class":507},[502,1239,1240],{"class":740},"CLAUDE_PLUGIN_ROOT",[502,1242,1203],{"class":507},[502,1244,1245],{"class":529},"$(",[502,1247,1248],{"class":740},"dirname",[502,1250,1251],{"class":507}," \"$(",[502,1253,1248],{"class":595},[502,1255,526],{"class":507},[502,1257,1259],{"class":1258},"sHdIc","$0",[502,1261,1262],{"class":507},"\")\"",[502,1264,1265],{"class":529},")",[502,1267,1209],{"class":507},[502,1269,1270,1273,1275],{"class":504,"line":773},[502,1271,1272],{"class":740},"PORT",[502,1274,1195],{"class":507},[502,1276,1277],{"class":529},"4242\n",[502,1279,1280],{"class":504,"line":779},[502,1281,1116],{"emptyLinePlaceholder":1115},[502,1283,1284],{"class":504,"line":785},[502,1285,1286],{"class":1100},"# Find available port\n",[502,1288,1289,1293,1296,1299,1302,1305],{"class":504,"line":791},[502,1290,1292],{"class":1291},"s7zQu","while",[502,1294,1295],{"class":507}," !",[502,1297,1298],{"class":595}," is_port_available",[502,1300,1301],{"class":740}," $PORT",[502,1303,1304],{"class":507},";",[502,1306,1307],{"class":1291}," do\n",[502,1309,1310,1313,1316,1318,1321,1324],{"class":504,"line":804},[502,1311,1312],{"class":740},"    PORT",[502,1314,1315],{"class":507},"=$((",[502,1317,1272],{"class":595},[502,1319,1320],{"class":529}," +",[502,1322,1323],{"class":688}," 1",[502,1325,1326],{"class":507},"))\n",[502,1328,1329],{"class":504,"line":809},[502,1330,1331],{"class":1291},"done\n",[502,1333,1334],{"class":504,"line":822},[502,1335,1116],{"emptyLinePlaceholder":1115},[502,1337,1338],{"class":504,"line":827},[502,1339,1340],{"class":1100},"# Create directory and copy template\n",[502,1342,1343,1346,1349,1351,1354],{"class":504,"line":846},[502,1344,1345],{"class":595},"mkdir",[502,1347,1348],{"class":529}," -p",[502,1350,526],{"class":507},[502,1352,1353],{"class":740},"$OVERFLOW_DIR",[502,1355,574],{"class":507},[502,1357,1358,1361,1364,1366,1369,1372,1374,1377,1379,1381,1384],{"class":504,"line":911},[502,1359,1360],{"class":595},"cp",[502,1362,1363],{"class":529}," -r",[502,1365,526],{"class":507},[502,1367,1368],{"class":740},"$PLUGIN_ROOT",[502,1370,1371],{"class":529},"\u002Ftemplate\u002F",[502,1373,520],{"class":507},[502,1375,1376],{"class":740},"*",[502,1378,526],{"class":507},[502,1380,1353],{"class":740},[502,1382,1383],{"class":529},"\u002F",[502,1385,574],{"class":507},[502,1387,1388,1390,1392,1394,1396,1399],{"class":504,"line":916},[502,1389,1345],{"class":595},[502,1391,1348],{"class":529},[502,1393,526],{"class":507},[502,1395,1353],{"class":740},[502,1397,1398],{"class":529},"\u002Fcontent\u002Fanswers",[502,1400,574],{"class":507},[502,1402,1403],{"class":504,"line":921},[502,1404,1116],{"emptyLinePlaceholder":1115},[502,1406,1407],{"class":504,"line":926},[502,1408,1409],{"class":1100},"# Install and start\n",[502,1411,1412,1415,1417,1419],{"class":504,"line":931},[502,1413,1414],{"class":1106},"cd",[502,1416,526],{"class":507},[502,1418,1353],{"class":740},[502,1420,574],{"class":507},[502,1422,1423,1426,1429],{"class":504,"line":944},[502,1424,1425],{"class":595},"pnpm",[502,1427,1428],{"class":529}," install",[502,1430,1431],{"class":529}," --silent\n",[502,1433,1434,1437,1440,1443,1446,1449,1451,1453,1456,1459,1462],{"class":504,"line":949},[502,1435,1436],{"class":595},"nohup",[502,1438,1439],{"class":529}," pnpm",[502,1441,1442],{"class":529}," dev",[502,1444,1445],{"class":507}," >",[502,1447,1448],{"class":529}," \u002Ftmp\u002Fclaude-overflow-",[502,1450,1224],{"class":507},[502,1452,1140],{"class":740},[502,1454,1455],{"class":507},"}",[502,1457,1458],{"class":529},".log",[502,1460,1461],{"class":507}," 2>&1",[502,1463,1464],{"class":507}," &\n",[502,1466,1467,1470],{"class":504,"line":962},[502,1468,1469],{"class":595},"sleep",[502,1471,1472],{"class":688}," 3\n",[502,1474,1475],{"class":504,"line":967},[502,1476,1116],{"emptyLinePlaceholder":1115},[502,1478,1479],{"class":504,"line":986},[502,1480,1481],{"class":1100},"# Output config for Claude's context\n",[502,1483,1484,1486,1489],{"class":504,"line":1012},[502,1485,1132],{"class":595},[502,1487,1488],{"class":507}," \u003C\u003C",[502,1490,1491],{"class":507}," EOF\n",[502,1493,1494],{"class":504,"line":1026},[502,1495,508],{"class":529},[502,1497,1498],{"class":504,"line":1031},[502,1499,1500],{"class":529},"  \"hookSpecificOutput\": {\n",[502,1502,1503],{"class":504,"line":1036},[502,1504,1505],{"class":529},"    \"hookEventName\": \"SessionStart\",\n",[502,1507,1508,1511,1513,1515,1517,1520,1522,1524,1526],{"class":504,"line":1041},[502,1509,1510],{"class":529},"    \"additionalContext\": \"[CLAUDE OVERFLOW CONFIG] Content path: ",[502,1512,1224],{"class":507},[502,1514,1214],{"class":740},[502,1516,1455],{"class":507},[502,1518,1519],{"class":529},"\u002Fcontent\u002Fanswers | Server URL: http:\u002F\u002Flocalhost:",[502,1521,1224],{"class":507},[502,1523,1272],{"class":740},[502,1525,1455],{"class":507},[502,1527,574],{"class":529},[502,1529,1530],{"class":504,"line":1047},[502,1531,1050],{"class":529},[502,1533,1534],{"class":504,"line":1053},[502,1535,580],{"class":529},[502,1537,1539],{"class":504,"line":1538},37,[502,1540,1541],{"class":507},"EOF\n",[451,1543,1544,1545,1548],{},"The key is the JSON output at the end. The ",[484,1546,1547],{},"hookSpecificOutput.additionalContext"," gets injected into Claude's context, so it knows where to write files.",[1063,1550,1552],{"id":1551},"userpromptsubmit-injecting-reminders","UserPromptSubmit: Injecting Reminders",[451,1554,1555],{},"Every time the user sends a message, I inject a reminder:",[477,1557,1559],{"className":496,"code":1558,"language":498,"meta":486,"style":486},"{\n  \"hookSpecificOutput\": {\n    \"hookEventName\": \"UserPromptSubmit\",\n    \"additionalContext\": \"For technical questions, use the overflow skill.\"\n  }\n}\n",[484,1560,1561,1565,1577,1595,1611,1615],{"__ignoreMap":486},[502,1562,1563],{"class":504,"line":171},[502,1564,508],{"class":507},[502,1566,1567,1569,1571,1573,1575],{"class":504,"line":161},[502,1568,513],{"class":507},[502,1570,864],{"class":516},[502,1572,520],{"class":507},[502,1574,523],{"class":507},[502,1576,661],{"class":507},[502,1578,1579,1581,1583,1585,1587,1589,1591,1593],{"class":504,"line":181},[502,1580,666],{"class":507},[502,1582,874],{"class":595},[502,1584,520],{"class":507},[502,1586,523],{"class":507},[502,1588,526],{"class":507},[502,1590,625],{"class":529},[502,1592,520],{"class":507},[502,1594,535],{"class":507},[502,1596,1597,1599,1601,1603,1605,1607,1609],{"class":504,"line":331},[502,1598,666],{"class":507},[502,1600,892],{"class":595},[502,1602,520],{"class":507},[502,1604,523],{"class":507},[502,1606,526],{"class":507},[502,1608,901],{"class":529},[502,1610,574],{"class":507},[502,1612,1613],{"class":504,"line":577},[502,1614,1050],{"class":507},[502,1616,1617],{"class":504,"line":282},[502,1618,580],{"class":507},[451,1620,1621],{},"This nudges Claude to use the skill for technical Q&A. Without it, Claude answers normally but doesn't save anything.",[1063,1623,1625],{"id":1624},"sessionend-cleanup","SessionEnd: Cleanup",[451,1627,1628],{},"When the session ends, kill the dev server:",[477,1630,1632],{"className":586,"code":1631,"language":588,"meta":486,"style":486},"#!\u002Fbin\u002Fbash\npkill -f \"\u002Ftmp\u002Fclaude-overflow-.*\u002Fnode_modules\" 2>\u002Fdev\u002Fnull || true\necho '{\"message\": \"Claude Overflow server stopped\"}'\n",[484,1633,1634,1638,1665],{"__ignoreMap":486},[502,1635,1636],{"class":504,"line":171},[502,1637,1101],{"class":1100},[502,1639,1640,1643,1646,1648,1651,1653,1656,1659,1662],{"class":504,"line":161},[502,1641,1642],{"class":595},"pkill",[502,1644,1645],{"class":529}," -f",[502,1647,526],{"class":507},[502,1649,1650],{"class":529},"\u002Ftmp\u002Fclaude-overflow-.*\u002Fnode_modules",[502,1652,520],{"class":507},[502,1654,1655],{"class":507}," 2>",[502,1657,1658],{"class":529},"\u002Fdev\u002Fnull",[502,1660,1661],{"class":507}," ||",[502,1663,1664],{"class":1106}," true\n",[502,1666,1667,1669,1671,1674],{"class":504,"line":181},[502,1668,1145],{"class":1106},[502,1670,1164],{"class":507},[502,1672,1673],{"class":529},"{\"message\": \"Claude Overflow server stopped\"}",[502,1675,1676],{"class":507},"'\n",[451,1678,1679],{},"Each session is isolated in its own temp directory, so cleanup is straightforward.",[469,1681,1683],{"id":1682},"skills-giving-claude-new-capabilities","Skills: Giving Claude New Capabilities",[451,1685,1686],{},"Skills are markdown files that define capabilities Claude can invoke. They're different from commands - skills are for Claude to use programmatically, commands are for users to trigger directly.",[451,1688,1689,1690,523],{},"Here's the overflow skill in ",[484,1691,1692],{},"skills\u002Foverflow\u002FSKILL.md",[477,1694,1698],{"className":1695,"code":1696,"language":1697,"meta":486,"style":486},"language-markdown shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","---\nname: overflow\ndescription: Write technical Q&A responses as markdown files to Claude Overflow.\n---\n\n# Claude Overflow Workflow\n\nWrite your response as a markdown file to the Claude Overflow content directory.\n\n## Step 1: Get Config from Context\n\nLook for the `[CLAUDE OVERFLOW CONFIG]` message from session start. It contains:\n\n- **Content path**: Where to write markdown files\n- **Server URL**: Where answers are viewable\n\n## Step 2: Generate File Details\n\n- **slug**: URL-friendly version of the question (lowercase, hyphens, max 50 chars)\n- **author**: Random dev username (e.g., `code_ninja_42`, `vim_wizard`)\n- **votes**: Random number 5-200\n\n## Step 3: Write the File\n\nWrite to: `{content_path}\u002F{slug}.md`\n\nFormat:\n\\```markdown\n\n---\n\ntitle: \"The user's question here\"\ndescription: \"Brief summary\"\nslug: \"the-slug\"\ncreatedAt: \"2024-01-15T10:30:00Z\"\nauthor: \"random_username\"\nvotes: 42\ntags:\n\n- javascript\n- async\n  comments:\n- username: \"another_dev\"\n  content: \"Great explanation!\"\n  timestamp: \"2024-01-15T11:00:00Z\"\n\n---\n\nYour complete answer here with code examples.\n\\```\n\n## Step 4: Confirm\n\nAfter writing, tell the user:\n\n> Answer archived! View at {server_url}\u002Fanswers\u002F{slug}\n","markdown",[484,1699,1700,1705,1710,1715,1719,1723,1728,1732,1737,1741,1746,1750,1755,1759,1764,1769,1773,1778,1782,1787,1792,1797,1801,1806,1810,1815,1819,1824,1829,1833,1837,1841,1846,1851,1856,1861,1866,1871,1877,1882,1888,1894,1900,1906,1912,1918,1923,1928,1933,1939,1945,1950,1956,1961,1967,1972],{"__ignoreMap":486},[502,1701,1702],{"class":504,"line":171},[502,1703,1704],{},"---\n",[502,1706,1707],{"class":504,"line":161},[502,1708,1709],{},"name: overflow\n",[502,1711,1712],{"class":504,"line":181},[502,1713,1714],{},"description: Write technical Q&A responses as markdown files to Claude Overflow.\n",[502,1716,1717],{"class":504,"line":331},[502,1718,1704],{},[502,1720,1721],{"class":504,"line":577},[502,1722,1116],{"emptyLinePlaceholder":1115},[502,1724,1725],{"class":504,"line":282},[502,1726,1727],{},"# Claude Overflow Workflow\n",[502,1729,1730],{"class":504,"line":702},[502,1731,1116],{"emptyLinePlaceholder":1115},[502,1733,1734],{"class":504,"line":189},[502,1735,1736],{},"Write your response as a markdown file to the Claude Overflow content directory.\n",[502,1738,1739],{"class":504,"line":314},[502,1740,1116],{"emptyLinePlaceholder":1115},[502,1742,1743],{"class":504,"line":767},[502,1744,1745],{},"## Step 1: Get Config from Context\n",[502,1747,1748],{"class":504,"line":773},[502,1749,1116],{"emptyLinePlaceholder":1115},[502,1751,1752],{"class":504,"line":779},[502,1753,1754],{},"Look for the `[CLAUDE OVERFLOW CONFIG]` message from session start. It contains:\n",[502,1756,1757],{"class":504,"line":785},[502,1758,1116],{"emptyLinePlaceholder":1115},[502,1760,1761],{"class":504,"line":791},[502,1762,1763],{},"- **Content path**: Where to write markdown files\n",[502,1765,1766],{"class":504,"line":804},[502,1767,1768],{},"- **Server URL**: Where answers are viewable\n",[502,1770,1771],{"class":504,"line":809},[502,1772,1116],{"emptyLinePlaceholder":1115},[502,1774,1775],{"class":504,"line":822},[502,1776,1777],{},"## Step 2: Generate File Details\n",[502,1779,1780],{"class":504,"line":827},[502,1781,1116],{"emptyLinePlaceholder":1115},[502,1783,1784],{"class":504,"line":846},[502,1785,1786],{},"- **slug**: URL-friendly version of the question (lowercase, hyphens, max 50 chars)\n",[502,1788,1789],{"class":504,"line":911},[502,1790,1791],{},"- **author**: Random dev username (e.g., `code_ninja_42`, `vim_wizard`)\n",[502,1793,1794],{"class":504,"line":916},[502,1795,1796],{},"- **votes**: Random number 5-200\n",[502,1798,1799],{"class":504,"line":921},[502,1800,1116],{"emptyLinePlaceholder":1115},[502,1802,1803],{"class":504,"line":926},[502,1804,1805],{},"## Step 3: Write the File\n",[502,1807,1808],{"class":504,"line":931},[502,1809,1116],{"emptyLinePlaceholder":1115},[502,1811,1812],{"class":504,"line":944},[502,1813,1814],{},"Write to: `{content_path}\u002F{slug}.md`\n",[502,1816,1817],{"class":504,"line":949},[502,1818,1116],{"emptyLinePlaceholder":1115},[502,1820,1821],{"class":504,"line":962},[502,1822,1823],{},"Format:\n",[502,1825,1826],{"class":504,"line":967},[502,1827,1828],{},"\\```markdown\n",[502,1830,1831],{"class":504,"line":986},[502,1832,1116],{"emptyLinePlaceholder":1115},[502,1834,1835],{"class":504,"line":1012},[502,1836,1704],{},[502,1838,1839],{"class":504,"line":1026},[502,1840,1116],{"emptyLinePlaceholder":1115},[502,1842,1843],{"class":504,"line":1031},[502,1844,1845],{},"title: \"The user's question here\"\n",[502,1847,1848],{"class":504,"line":1036},[502,1849,1850],{},"description: \"Brief summary\"\n",[502,1852,1853],{"class":504,"line":1041},[502,1854,1855],{},"slug: \"the-slug\"\n",[502,1857,1858],{"class":504,"line":1047},[502,1859,1860],{},"createdAt: \"2024-01-15T10:30:00Z\"\n",[502,1862,1863],{"class":504,"line":1053},[502,1864,1865],{},"author: \"random_username\"\n",[502,1867,1868],{"class":504,"line":1538},[502,1869,1870],{},"votes: 42\n",[502,1872,1874],{"class":504,"line":1873},38,[502,1875,1876],{},"tags:\n",[502,1878,1880],{"class":504,"line":1879},39,[502,1881,1116],{"emptyLinePlaceholder":1115},[502,1883,1885],{"class":504,"line":1884},40,[502,1886,1887],{},"- javascript\n",[502,1889,1891],{"class":504,"line":1890},41,[502,1892,1893],{},"- async\n",[502,1895,1897],{"class":504,"line":1896},42,[502,1898,1899],{},"  comments:\n",[502,1901,1903],{"class":504,"line":1902},43,[502,1904,1905],{},"- username: \"another_dev\"\n",[502,1907,1909],{"class":504,"line":1908},44,[502,1910,1911],{},"  content: \"Great explanation!\"\n",[502,1913,1915],{"class":504,"line":1914},45,[502,1916,1917],{},"  timestamp: \"2024-01-15T11:00:00Z\"\n",[502,1919,1921],{"class":504,"line":1920},46,[502,1922,1116],{"emptyLinePlaceholder":1115},[502,1924,1926],{"class":504,"line":1925},47,[502,1927,1704],{},[502,1929,1931],{"class":504,"line":1930},48,[502,1932,1116],{"emptyLinePlaceholder":1115},[502,1934,1936],{"class":504,"line":1935},49,[502,1937,1938],{},"Your complete answer here with code examples.\n",[502,1940,1942],{"class":504,"line":1941},50,[502,1943,1944],{},"\\```\n",[502,1946,1948],{"class":504,"line":1947},51,[502,1949,1116],{"emptyLinePlaceholder":1115},[502,1951,1953],{"class":504,"line":1952},52,[502,1954,1955],{},"## Step 4: Confirm\n",[502,1957,1959],{"class":504,"line":1958},53,[502,1960,1116],{"emptyLinePlaceholder":1115},[502,1962,1964],{"class":504,"line":1963},54,[502,1965,1966],{},"After writing, tell the user:\n",[502,1968,1970],{"class":504,"line":1969},55,[502,1971,1116],{"emptyLinePlaceholder":1115},[502,1973,1975],{"class":504,"line":1974},56,[502,1976,1977],{},"> Answer archived! View at {server_url}\u002Fanswers\u002F{slug}\n",[451,1979,1980],{},"The skill tells Claude exactly what to do: read the config from context, generate metadata, write a markdown file with specific frontmatter, and confirm to the user.",[451,1982,1983],{},"Claude uses its native Write tool to create the file - no MCP server needed.",[469,1985,1987],{"id":1986},"commands-user-triggered-actions","Commands: User-Triggered Actions",[451,1989,1990,1991,1994,1995,523],{},"Commands let users explicitly trigger skills with ",[484,1992,1993],{},"\u002Fcommand",". Here's ",[484,1996,1997],{},"commands\u002Foverflow.md",[477,1999,2001],{"className":1695,"code":2000,"language":1697,"meta":486,"style":486},"---\nname: overflow\ndescription: Answer a technical question and save it to Claude Overflow\narguments:\n  - name: question\n    description: The technical question to answer\n    required: true\n---\n\nAnswer the user's technical question and save it to the Claude Overflow archive.\n\n## Steps\n\n1. Get config from the `[CLAUDE OVERFLOW CONFIG]` context message\n2. Generate a URL-friendly slug from the question\n3. Write a markdown file with the answer\n4. Tell the user where to view it\n\n## Question\n\n$ARGUMENTS\n",[484,2002,2003,2007,2011,2016,2021,2026,2031,2036,2040,2044,2049,2053,2058,2062,2067,2072,2077,2082,2086,2091,2095],{"__ignoreMap":486},[502,2004,2005],{"class":504,"line":171},[502,2006,1704],{},[502,2008,2009],{"class":504,"line":161},[502,2010,1709],{},[502,2012,2013],{"class":504,"line":181},[502,2014,2015],{},"description: Answer a technical question and save it to Claude Overflow\n",[502,2017,2018],{"class":504,"line":331},[502,2019,2020],{},"arguments:\n",[502,2022,2023],{"class":504,"line":577},[502,2024,2025],{},"  - name: question\n",[502,2027,2028],{"class":504,"line":282},[502,2029,2030],{},"    description: The technical question to answer\n",[502,2032,2033],{"class":504,"line":702},[502,2034,2035],{},"    required: true\n",[502,2037,2038],{"class":504,"line":189},[502,2039,1704],{},[502,2041,2042],{"class":504,"line":314},[502,2043,1116],{"emptyLinePlaceholder":1115},[502,2045,2046],{"class":504,"line":767},[502,2047,2048],{},"Answer the user's technical question and save it to the Claude Overflow archive.\n",[502,2050,2051],{"class":504,"line":773},[502,2052,1116],{"emptyLinePlaceholder":1115},[502,2054,2055],{"class":504,"line":779},[502,2056,2057],{},"## Steps\n",[502,2059,2060],{"class":504,"line":785},[502,2061,1116],{"emptyLinePlaceholder":1115},[502,2063,2064],{"class":504,"line":791},[502,2065,2066],{},"1. Get config from the `[CLAUDE OVERFLOW CONFIG]` context message\n",[502,2068,2069],{"class":504,"line":804},[502,2070,2071],{},"2. Generate a URL-friendly slug from the question\n",[502,2073,2074],{"class":504,"line":809},[502,2075,2076],{},"3. Write a markdown file with the answer\n",[502,2078,2079],{"class":504,"line":822},[502,2080,2081],{},"4. Tell the user where to view it\n",[502,2083,2084],{"class":504,"line":827},[502,2085,1116],{"emptyLinePlaceholder":1115},[502,2087,2088],{"class":504,"line":846},[502,2089,2090],{},"## Question\n",[502,2092,2093],{"class":504,"line":911},[502,2094,1116],{"emptyLinePlaceholder":1115},[502,2096,2097],{"class":504,"line":916},[502,2098,2099],{},"$ARGUMENTS\n",[451,2101,2102],{},"Now users can explicitly save answers:",[477,2104,2107],{"className":2105,"code":2106,"language":482},[480],"\u002Foverflow What is the difference between map and filter in JavaScript?\n",[484,2108,2106],{"__ignoreMap":486},[469,2110,2112],{"id":2111},"the-web-ui-nuxt-content","The Web UI: Nuxt Content",[451,2114,2115],{},"The template is a simple Nuxt 4 app with Nuxt Content. When Claude writes a markdown file to the content directory, Nuxt Content picks it up immediately via hot reload.",[451,2117,2118],{},"The questions list page queries all answers:",[477,2120,2124],{"className":2121,"code":2122,"language":2123,"meta":486,"style":486},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript setup lang=\"ts\">\nconst { data: answers } = await useAsyncData('answers', () =>\n  queryCollection('answers').order('createdAt', 'DESC').all()\n);\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"space-y-4\">\n    \u003CNuxtLink\n      v-for=\"answer in answers\"\n      :key=\"answer.slug\"\n      :to=\"`\u002Fanswers\u002F${answer.slug}`\"\n      class=\"block p-4 border rounded hover:bg-gray-50\"\n    >\n      \u003Ch2 class=\"text-lg font-medium\">{{ answer.title }}\u003C\u002Fh2>\n      \u003Cdiv class=\"text-sm text-gray-500\">\n        {{ answer.author }} · {{ answer.votes }} votes\n      \u003C\u002Fdiv>\n    \u003C\u002FNuxtLink>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n","vue",[484,2125,2126,2152,2197,2246,2253,2262,2266,2275,2297,2305,2319,2333,2347,2361,2366,2396,2415,2420,2429,2439,2448],{"__ignoreMap":486},[502,2127,2128,2131,2134,2137,2140,2142,2144,2147,2149],{"class":504,"line":171},[502,2129,2130],{"class":507},"\u003C",[502,2132,2133],{"class":708},"script",[502,2135,2136],{"class":516}," setup",[502,2138,2139],{"class":516}," lang",[502,2141,1195],{"class":507},[502,2143,520],{"class":507},[502,2145,2146],{"class":529},"ts",[502,2148,520],{"class":507},[502,2150,2151],{"class":507},">\n",[502,2153,2154,2157,2160,2163,2165,2168,2170,2173,2176,2179,2182,2184,2187,2189,2191,2194],{"class":504,"line":161},[502,2155,2156],{"class":516},"const",[502,2158,2159],{"class":507}," {",[502,2161,2162],{"class":708}," data",[502,2164,523],{"class":507},[502,2166,2167],{"class":740}," answers ",[502,2169,1455],{"class":507},[502,2171,2172],{"class":507}," =",[502,2174,2175],{"class":1291}," await",[502,2177,2178],{"class":1106}," useAsyncData",[502,2180,2181],{"class":740},"(",[502,2183,1170],{"class":507},[502,2185,2186],{"class":529},"answers",[502,2188,1170],{"class":507},[502,2190,887],{"class":507},[502,2192,2193],{"class":507}," ()",[502,2195,2196],{"class":516}," =>\n",[502,2198,2199,2202,2204,2206,2208,2210,2212,2215,2218,2220,2222,2225,2227,2229,2231,2234,2236,2238,2240,2243],{"class":504,"line":181},[502,2200,2201],{"class":1106},"  queryCollection",[502,2203,2181],{"class":740},[502,2205,1170],{"class":507},[502,2207,2186],{"class":529},[502,2209,1170],{"class":507},[502,2211,1265],{"class":740},[502,2213,2214],{"class":507},".",[502,2216,2217],{"class":1106},"order",[502,2219,2181],{"class":740},[502,2221,1170],{"class":507},[502,2223,2224],{"class":529},"createdAt",[502,2226,1170],{"class":507},[502,2228,887],{"class":507},[502,2230,1164],{"class":507},[502,2232,2233],{"class":529},"DESC",[502,2235,1170],{"class":507},[502,2237,1265],{"class":740},[502,2239,2214],{"class":507},[502,2241,2242],{"class":1106},"all",[502,2244,2245],{"class":740},"()\n",[502,2247,2248,2250],{"class":504,"line":331},[502,2249,1265],{"class":740},[502,2251,2252],{"class":507},";\n",[502,2254,2255,2258,2260],{"class":504,"line":577},[502,2256,2257],{"class":507},"\u003C\u002F",[502,2259,2133],{"class":708},[502,2261,2151],{"class":507},[502,2263,2264],{"class":504,"line":282},[502,2265,1116],{"emptyLinePlaceholder":1115},[502,2267,2268,2270,2273],{"class":504,"line":702},[502,2269,2130],{"class":507},[502,2271,2272],{"class":708},"template",[502,2274,2151],{"class":507},[502,2276,2277,2280,2283,2286,2288,2290,2293,2295],{"class":504,"line":189},[502,2278,2279],{"class":507},"  \u003C",[502,2281,2282],{"class":708},"div",[502,2284,2285],{"class":516}," class",[502,2287,1195],{"class":507},[502,2289,520],{"class":507},[502,2291,2292],{"class":529},"space-y-4",[502,2294,520],{"class":507},[502,2296,2151],{"class":507},[502,2298,2299,2302],{"class":504,"line":314},[502,2300,2301],{"class":507},"    \u003C",[502,2303,2304],{"class":708},"NuxtLink\n",[502,2306,2307,2310,2312,2314,2317],{"class":504,"line":767},[502,2308,2309],{"class":516},"      v-for",[502,2311,1195],{"class":507},[502,2313,520],{"class":507},[502,2315,2316],{"class":529},"answer in answers",[502,2318,574],{"class":507},[502,2320,2321,2324,2326,2328,2331],{"class":504,"line":773},[502,2322,2323],{"class":516},"      :key",[502,2325,1195],{"class":507},[502,2327,520],{"class":507},[502,2329,2330],{"class":529},"answer.slug",[502,2332,574],{"class":507},[502,2334,2335,2338,2340,2342,2345],{"class":504,"line":779},[502,2336,2337],{"class":516},"      :to",[502,2339,1195],{"class":507},[502,2341,520],{"class":507},[502,2343,2344],{"class":529},"`\u002Fanswers\u002F${answer.slug}`",[502,2346,574],{"class":507},[502,2348,2349,2352,2354,2356,2359],{"class":504,"line":785},[502,2350,2351],{"class":516},"      class",[502,2353,1195],{"class":507},[502,2355,520],{"class":507},[502,2357,2358],{"class":529},"block p-4 border rounded hover:bg-gray-50",[502,2360,574],{"class":507},[502,2362,2363],{"class":504,"line":791},[502,2364,2365],{"class":507},"    >\n",[502,2367,2368,2371,2373,2375,2377,2379,2382,2384,2387,2390,2392,2394],{"class":504,"line":804},[502,2369,2370],{"class":507},"      \u003C",[502,2372,469],{"class":708},[502,2374,2285],{"class":516},[502,2376,1195],{"class":507},[502,2378,520],{"class":507},[502,2380,2381],{"class":529},"text-lg font-medium",[502,2383,520],{"class":507},[502,2385,2386],{"class":507},">",[502,2388,2389],{"class":740},"{{ answer.title }}",[502,2391,2257],{"class":507},[502,2393,469],{"class":708},[502,2395,2151],{"class":507},[502,2397,2398,2400,2402,2404,2406,2408,2411,2413],{"class":504,"line":809},[502,2399,2370],{"class":507},[502,2401,2282],{"class":708},[502,2403,2285],{"class":516},[502,2405,1195],{"class":507},[502,2407,520],{"class":507},[502,2409,2410],{"class":529},"text-sm text-gray-500",[502,2412,520],{"class":507},[502,2414,2151],{"class":507},[502,2416,2417],{"class":504,"line":822},[502,2418,2419],{"class":740},"        {{ answer.author }} · {{ answer.votes }} votes\n",[502,2421,2422,2425,2427],{"class":504,"line":827},[502,2423,2424],{"class":507},"      \u003C\u002F",[502,2426,2282],{"class":708},[502,2428,2151],{"class":507},[502,2430,2431,2434,2437],{"class":504,"line":846},[502,2432,2433],{"class":507},"    \u003C\u002F",[502,2435,2436],{"class":708},"NuxtLink",[502,2438,2151],{"class":507},[502,2440,2441,2444,2446],{"class":504,"line":911},[502,2442,2443],{"class":507},"  \u003C\u002F",[502,2445,2282],{"class":708},[502,2447,2151],{"class":507},[502,2449,2450,2452,2454],{"class":504,"line":916},[502,2451,2257],{"class":507},[502,2453,2272],{"class":708},[502,2455,2151],{"class":507},[451,2457,2458],{},"The detail page renders the markdown content with generated comments:",[477,2460,2462],{"className":2121,"code":2461,"language":2123,"meta":486,"style":486},"\u003Cscript setup lang=\"ts\">\nconst route = useRoute();\nconst { data: answer } = await useAsyncData(`answer-${route.params.slug}`, () =>\n  queryCollection('answers').path(`\u002Fanswers\u002F${route.params.slug}`).first()\n);\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Carticle v-if=\"answer\">\n    \u003Ch1>{{ answer.title }}\u003C\u002Fh1>\n    \u003Cdiv class=\"meta\">{{ answer.author }} · {{ answer.votes }} votes\u003C\u002Fdiv>\n    \u003CContentRenderer :value=\"answer\" \u002F>\n\n    \u003Cdiv class=\"comments\" v-if=\"answer.comments?.length\">\n      \u003Cdiv v-for=\"comment in answer.comments\" :key=\"comment.timestamp\">\n        \u003Cstrong>{{ comment.username }}\u003C\u002Fstrong\n        >: {{ comment.content }}\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  \u003C\u002Farticle>\n\u003C\u002Ftemplate>\n",[484,2463,2464,2484,2501,2554,2603,2609,2617,2621,2629,2650,2667,2695,2716,2720,2750,2782,2799,2807,2815,2823,2831],{"__ignoreMap":486},[502,2465,2466,2468,2470,2472,2474,2476,2478,2480,2482],{"class":504,"line":171},[502,2467,2130],{"class":507},[502,2469,2133],{"class":708},[502,2471,2136],{"class":516},[502,2473,2139],{"class":516},[502,2475,1195],{"class":507},[502,2477,520],{"class":507},[502,2479,2146],{"class":529},[502,2481,520],{"class":507},[502,2483,2151],{"class":507},[502,2485,2486,2488,2491,2493,2496,2499],{"class":504,"line":161},[502,2487,2156],{"class":516},[502,2489,2490],{"class":740}," route ",[502,2492,1195],{"class":507},[502,2494,2495],{"class":1106}," useRoute",[502,2497,2498],{"class":740},"()",[502,2500,2252],{"class":507},[502,2502,2503,2505,2507,2509,2511,2514,2516,2518,2520,2522,2524,2527,2530,2532,2535,2537,2540,2542,2545,2548,2550,2552],{"class":504,"line":181},[502,2504,2156],{"class":516},[502,2506,2159],{"class":507},[502,2508,2162],{"class":708},[502,2510,523],{"class":507},[502,2512,2513],{"class":740}," answer ",[502,2515,1455],{"class":507},[502,2517,2172],{"class":507},[502,2519,2175],{"class":1291},[502,2521,2178],{"class":1106},[502,2523,2181],{"class":740},[502,2525,2526],{"class":507},"`",[502,2528,2529],{"class":529},"answer-",[502,2531,1224],{"class":507},[502,2533,2534],{"class":740},"route",[502,2536,2214],{"class":507},[502,2538,2539],{"class":740},"params",[502,2541,2214],{"class":507},[502,2543,2544],{"class":740},"slug",[502,2546,2547],{"class":507},"}`",[502,2549,887],{"class":507},[502,2551,2193],{"class":507},[502,2553,2196],{"class":516},[502,2555,2556,2558,2560,2562,2564,2566,2568,2570,2573,2575,2577,2580,2582,2584,2586,2588,2590,2592,2594,2596,2598,2601],{"class":504,"line":331},[502,2557,2201],{"class":1106},[502,2559,2181],{"class":740},[502,2561,1170],{"class":507},[502,2563,2186],{"class":529},[502,2565,1170],{"class":507},[502,2567,1265],{"class":740},[502,2569,2214],{"class":507},[502,2571,2572],{"class":1106},"path",[502,2574,2181],{"class":740},[502,2576,2526],{"class":507},[502,2578,2579],{"class":529},"\u002Fanswers\u002F",[502,2581,1224],{"class":507},[502,2583,2534],{"class":740},[502,2585,2214],{"class":507},[502,2587,2539],{"class":740},[502,2589,2214],{"class":507},[502,2591,2544],{"class":740},[502,2593,2547],{"class":507},[502,2595,1265],{"class":740},[502,2597,2214],{"class":507},[502,2599,2600],{"class":1106},"first",[502,2602,2245],{"class":740},[502,2604,2605,2607],{"class":504,"line":577},[502,2606,1265],{"class":740},[502,2608,2252],{"class":507},[502,2610,2611,2613,2615],{"class":504,"line":282},[502,2612,2257],{"class":507},[502,2614,2133],{"class":708},[502,2616,2151],{"class":507},[502,2618,2619],{"class":504,"line":702},[502,2620,1116],{"emptyLinePlaceholder":1115},[502,2622,2623,2625,2627],{"class":504,"line":189},[502,2624,2130],{"class":507},[502,2626,2272],{"class":708},[502,2628,2151],{"class":507},[502,2630,2631,2633,2636,2639,2641,2643,2646,2648],{"class":504,"line":314},[502,2632,2279],{"class":507},[502,2634,2635],{"class":708},"article",[502,2637,2638],{"class":516}," v-if",[502,2640,1195],{"class":507},[502,2642,520],{"class":507},[502,2644,2645],{"class":529},"answer",[502,2647,520],{"class":507},[502,2649,2151],{"class":507},[502,2651,2652,2654,2657,2659,2661,2663,2665],{"class":504,"line":767},[502,2653,2301],{"class":507},[502,2655,2656],{"class":708},"h1",[502,2658,2386],{"class":507},[502,2660,2389],{"class":740},[502,2662,2257],{"class":507},[502,2664,2656],{"class":708},[502,2666,2151],{"class":507},[502,2668,2669,2671,2673,2675,2677,2679,2682,2684,2686,2689,2691,2693],{"class":504,"line":773},[502,2670,2301],{"class":507},[502,2672,2282],{"class":708},[502,2674,2285],{"class":516},[502,2676,1195],{"class":507},[502,2678,520],{"class":507},[502,2680,2681],{"class":529},"meta",[502,2683,520],{"class":507},[502,2685,2386],{"class":507},[502,2687,2688],{"class":740},"{{ answer.author }} · {{ answer.votes }} votes",[502,2690,2257],{"class":507},[502,2692,2282],{"class":708},[502,2694,2151],{"class":507},[502,2696,2697,2699,2702,2705,2707,2709,2711,2713],{"class":504,"line":779},[502,2698,2301],{"class":507},[502,2700,2701],{"class":708},"ContentRenderer",[502,2703,2704],{"class":516}," :value",[502,2706,1195],{"class":507},[502,2708,520],{"class":507},[502,2710,2645],{"class":529},[502,2712,520],{"class":507},[502,2714,2715],{"class":507}," \u002F>\n",[502,2717,2718],{"class":504,"line":785},[502,2719,1116],{"emptyLinePlaceholder":1115},[502,2721,2722,2724,2726,2728,2730,2732,2735,2737,2739,2741,2743,2746,2748],{"class":504,"line":791},[502,2723,2301],{"class":507},[502,2725,2282],{"class":708},[502,2727,2285],{"class":516},[502,2729,1195],{"class":507},[502,2731,520],{"class":507},[502,2733,2734],{"class":529},"comments",[502,2736,520],{"class":507},[502,2738,2638],{"class":516},[502,2740,1195],{"class":507},[502,2742,520],{"class":507},[502,2744,2745],{"class":529},"answer.comments?.length",[502,2747,520],{"class":507},[502,2749,2151],{"class":507},[502,2751,2752,2754,2756,2759,2761,2763,2766,2768,2771,2773,2775,2778,2780],{"class":504,"line":804},[502,2753,2370],{"class":507},[502,2755,2282],{"class":708},[502,2757,2758],{"class":516}," v-for",[502,2760,1195],{"class":507},[502,2762,520],{"class":507},[502,2764,2765],{"class":529},"comment in answer.comments",[502,2767,520],{"class":507},[502,2769,2770],{"class":516}," :key",[502,2772,1195],{"class":507},[502,2774,520],{"class":507},[502,2776,2777],{"class":529},"comment.timestamp",[502,2779,520],{"class":507},[502,2781,2151],{"class":507},[502,2783,2784,2787,2789,2791,2794,2796],{"class":504,"line":809},[502,2785,2786],{"class":507},"        \u003C",[502,2788,617],{"class":708},[502,2790,2386],{"class":507},[502,2792,2793],{"class":740},"{{ comment.username }}",[502,2795,2257],{"class":507},[502,2797,2798],{"class":708},"strong\n",[502,2800,2801,2804],{"class":504,"line":822},[502,2802,2803],{"class":507},"        >",[502,2805,2806],{"class":740},": {{ comment.content }}\n",[502,2808,2809,2811,2813],{"class":504,"line":827},[502,2810,2424],{"class":507},[502,2812,2282],{"class":708},[502,2814,2151],{"class":507},[502,2816,2817,2819,2821],{"class":504,"line":846},[502,2818,2433],{"class":507},[502,2820,2282],{"class":708},[502,2822,2151],{"class":507},[502,2824,2825,2827,2829],{"class":504,"line":911},[502,2826,2443],{"class":507},[502,2828,2635],{"class":708},[502,2830,2151],{"class":507},[502,2832,2833,2835,2837],{"class":504,"line":916},[502,2834,2257],{"class":507},[502,2836,2272],{"class":708},[502,2838,2151],{"class":507},[451,2840,2841],{},"The UI looks like a simplified StackOverflow - questions list, answer detail with votes and comments.",[469,2843,2845],{"id":2844},"how-it-all-fits-together","How It All Fits Together",[451,2847,2848],{},"Here's the flow when you ask a technical question:",[1071,2850,2851,2877,2883,2889,2908,2914],{},[614,2852,2853,2856,2857,2860],{},[617,2854,2855],{},"SessionStart hook"," runs ",[484,2858,2859],{},"setup.sh",[611,2861,2862,2868,2871,2874],{},[614,2863,2864,2865],{},"Creates ",[484,2866,2867],{},"\u002Ftmp\u002Fclaude-overflow-{session}\u002F",[614,2869,2870],{},"Copies Nuxt template",[614,2872,2873],{},"Starts dev server on port 4242",[614,2875,2876],{},"Injects config into Claude's context",[614,2878,2879,2882],{},[617,2880,2881],{},"UserPromptSubmit hook"," injects the reminder about the overflow skill",[614,2884,2885,2888],{},[617,2886,2887],{},"Claude sees the reminder"," and decides to use the skill for technical questions",[614,2890,2891,2894],{},[617,2892,2893],{},"The skill executes",[611,2895,2896,2899,2902,2905],{},[614,2897,2898],{},"Claude reads the config from its context",[614,2900,2901],{},"Generates slug, author, votes, comments",[614,2903,2904],{},"Uses the Write tool to create a markdown file",[614,2906,2907],{},"Tells the user the URL",[614,2909,2910,2913],{},[617,2911,2912],{},"Nuxt Content hot-reloads"," and the answer appears in the web UI",[614,2915,2916,2856,2919,2922],{},[617,2917,2918],{},"SessionEnd hook",[484,2920,2921],{},"cleanup.sh"," to stop the server",[469,2924,2926],{"id":2925},"what-i-learned","What I Learned",[451,2928,2929,2932],{},[617,2930,2931],{},"Hooks are powerful but limited to shell commands."," You can't run arbitrary code - everything goes through bash. For complex logic, write a script and call it.",[451,2934,2935,2938,2939,2941],{},[617,2936,2937],{},"The hookSpecificOutput JSON is how you communicate with Claude."," Whatever you put in ",[484,2940,892],{}," gets added to Claude's context. This is how SessionStart passes config that skills use later.",[451,2943,2944,2947],{},[617,2945,2946],{},"Skills vs Commands:"," Skills are for Claude to invoke programmatically. Commands are for users to trigger explicitly. You often want both pointing to the same capability.",[451,2949,2950,2953],{},[617,2951,2952],{},"No MCP server needed for file operations."," Claude has a native Write tool. Skills can just tell Claude what to write and where.",[451,2955,2956,2959],{},[617,2957,2958],{},"Session isolation matters."," Each session gets its own temp directory and server port. This prevents conflicts when running multiple sessions.",[469,2961,2963],{"id":2962},"ways-to-extend","Ways to Extend",[451,2965,2966],{},"The current implementation is session-scoped - each session gets its own temp directory and server, and everything disappears when the session ends. But there are some interesting directions to take this:",[451,2968,2969,2972],{},[617,2970,2971],{},"System-wide server"," - Instead of spinning up a new server per session, run a single persistent server that all sessions write to. Every Claude conversation across your machine contributes to the same knowledge base.",[451,2974,2975,2978,2979,2982],{},[617,2976,2977],{},"Persistence mode"," - Add a flag to save content to a permanent directory instead of ",[484,2980,2981],{},"\u002Ftmp",". Your Q&A archive survives across sessions and machine restarts.",[451,2984,2985,2988],{},[617,2986,2987],{},"Custom directory"," - Let users specify where content gets saved. Point it at a git repo and you've got version-controlled knowledge.",[451,2990,2991,2994],{},[617,2992,2993],{},"Team knowledge base"," - This is where it gets interesting. An org could run a shared Claude Overflow instance. Every developer's AI conversations contribute to a collective knowledge base. Junior devs browse answers from senior devs' sessions. Onboarding gets easier because common questions are already answered.",[451,2996,2997],{},"The plugin system is flexible enough to support all of these. The SessionStart hook just needs different logic for where to write and whether to start a server.",[469,2999,3001],{"id":3000},"try-it","Try It",[451,3003,3004,3005],{},"The full code is on GitHub: ",[458,3006,530],{"href":460,"rel":3007},[462],[451,3009,3010,3011,3014],{},"Clone it, run ",[484,3012,3013],{},"claude --plugin-dir \u002Fpath\u002Fto\u002Fplugin",", and ask some technical questions. The answers accumulate in a local knowledge base you can browse.",[451,3016,3017],{},"Most of us \"figured things out\" by copying from StackOverflow. You'd find an answer, read it, understand it, then write it yourself. That process taught you something.",[451,3019,3020],{},"With AI doing everything now, that step gets skipped. This brings it back - a knowledge base you can browse, copy from, and actually learn from.",[3022,3023,3024],"style",{},"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 .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}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}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 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}",{"title":486,"searchDepth":161,"depth":161,"links":3026},[3027,3028,3033,3034,3035,3036,3037,3038,3039],{"id":471,"depth":161,"text":472},{"id":605,"depth":161,"text":606,"children":3029},[3030,3031,3032],{"id":1065,"depth":181,"text":1066},{"id":1551,"depth":181,"text":1552},{"id":1624,"depth":181,"text":1625},{"id":1682,"depth":161,"text":1683},{"id":1986,"depth":161,"text":1987},{"id":2111,"depth":161,"text":2112},{"id":2844,"depth":161,"text":2845},{"id":2925,"depth":161,"text":2926},{"id":2962,"depth":161,"text":2963},{"id":3000,"depth":161,"text":3001},[3041],"Web Development","2026-01-04","A practical guide to Claude Code's plugin system - hooks, skills, and commands. I built Claude Overflow to learn how it all fits together.","md",null,"\u002Fassets\u002Fimages\u002Fblog\u002Fclaude-code-hooks.jpg",{},{"title":10,"description":3043},{"loc":11},[229,158,353,345,369],"Uj9BH6r9OFZRsSWEKrte6ewbrSUlnoHQIVNhW8jYMLw",[3053,3055,3057,3059],{"id":152,"color":153,"description":154,"extension":155,"meta":3054,"name":157,"slug":158,"stem":159,"__hash__":160},{},{"id":349,"color":192,"description":350,"extension":155,"meta":3056,"name":352,"slug":353,"stem":354,"__hash__":355},{},{"id":341,"color":217,"description":342,"extension":155,"meta":3058,"name":344,"slug":345,"stem":346,"__hash__":347},{},{"id":365,"color":153,"description":366,"extension":155,"meta":3060,"name":368,"slug":369,"stem":370,"__hash__":371},{},1792716693290]