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