This is page 3 of 5. Use http://codebase.md/hongsw/claude-agents-power-mcp-server?lines=true&page={x} to view the full context. # Directory Structure ``` ├── .claude │ └── agents │ ├── devops-engineer.md │ ├── frontend-developer.md │ ├── qa-engineer.md │ ├── README.md │ ├── security-engineer.md │ └── tech-lead.md ├── .gitignore ├── agents │ ├── backend-engineer.md │ ├── data-scientist.md │ ├── devops-engineer.md │ ├── frontend-developer.md │ ├── full-stack-developer.md │ ├── mobile-developer.md │ ├── qa-engineer.md │ ├── README.md │ ├── security-engineer.md │ ├── tech-lead.md │ └── ui-designer.md ├── CHANGELOG.md ├── claude │ └── agents │ ├── company-roles.md │ ├── en │ │ ├── account-manager.md │ │ ├── accountant.md │ │ ├── accounting-manager.md │ │ ├── agile-coach.md │ │ ├── ai-researcher.md │ │ ├── backend-developer.md │ │ ├── backend-engineer.md │ │ ├── bi-developer.md │ │ ├── blockchain-developer.md │ │ ├── brand-manager.md │ │ ├── budget-analyst.md │ │ ├── business-analyst.md │ │ ├── business-developer.md │ │ ├── business-development-manager.md │ │ ├── business-intelligence-analyst.md │ │ ├── business-process-analyst.md │ │ ├── change-management-specialist.md │ │ ├── change-manager.md │ │ ├── chief-data-officer.md │ │ ├── chief-executive-officer.md │ │ ├── chief-financial-officer.md │ │ ├── chief-human-resources-officer.md │ │ ├── chief-information-officer.md │ │ ├── chief-marketing-officer.md │ │ ├── chief-operating-officer.md │ │ ├── chief-product-officer.md │ │ ├── chief-technology-officer.md │ │ ├── clinical-researcher.md │ │ ├── cloud-architect.md │ │ ├── communications-director.md │ │ ├── compensation-benefits-manager.md │ │ ├── compensation-benefits.md │ │ ├── compliance-manager.md │ │ ├── compliance-officer.md │ │ ├── content-creator.md │ │ ├── content-marketer.md │ │ ├── content-marketing-manager.md │ │ ├── contract-manager.md │ │ ├── controller.md │ │ ├── copywriter.md │ │ ├── corporate-trainer.md │ │ ├── creative-director.md │ │ ├── credit-analyst.md │ │ ├── curriculum-developer.md │ │ ├── customer-service-manager.md │ │ ├── customer-success-manager.md │ │ ├── data-analyst.md │ │ ├── data-engineer.md │ │ ├── data-scientist.md │ │ ├── database-administrator.md │ │ ├── design-lead.md │ │ ├── devops-engineer.md │ │ ├── digital-marketer.md │ │ ├── digital-marketing-specialist.md │ │ ├── diversity-inclusion-manager.md │ │ ├── diversity-inclusion.md │ │ ├── embedded-systems-engineer.md │ │ ├── environmental-engineer.md │ │ ├── event-manager.md │ │ ├── executive-assistant.md │ │ ├── facilities-manager.md │ │ ├── facility-manager.md │ │ ├── financial-analyst.md │ │ ├── financial-controller.md │ │ ├── frontend-developer.md │ │ ├── full-stack-developer.md │ │ ├── game-developer.md │ │ ├── graphic-designer.md │ │ ├── growth-hacker.md │ │ ├── growth-marketing-manager.md │ │ ├── health-informatics.md │ │ ├── healthcare-analyst.md │ │ ├── help-desk-specialist.md │ │ ├── hr-manager.md │ │ ├── implementation-consultant.md │ │ ├── innovation-manager.md │ │ ├── instructional-designer.md │ │ ├── interaction-designer.md │ │ ├── internal-auditor.md │ │ ├── investment-analyst.md │ │ ├── investor-relations-manager.md │ │ ├── investor-relations.md │ │ ├── it-administrator.md │ │ ├── learning-development-manager.md │ │ ├── learning-development.md │ │ ├── legal-counsel.md │ │ ├── machine-learning-engineer.md │ │ ├── marketing-analyst.md │ │ ├── marketing-manager.md │ │ ├── medical-writer.md │ │ ├── mobile-developer.md │ │ ├── motion-designer.md │ │ ├── network-engineer.md │ │ ├── office-manager.md │ │ ├── operations-manager.md │ │ ├── organizational-developer.md │ │ ├── organizational-development-manager.md │ │ ├── partnership-manager.md │ │ ├── patent-engineer.md │ │ ├── payroll-manager.md │ │ ├── pr-manager.md │ │ ├── pre-sales-consultant.md │ │ ├── privacy-officer.md │ │ ├── process-engineer.md │ │ ├── procurement-manager.md │ │ ├── procurement-specialist.md │ │ ├── product-designer.md │ │ ├── product-manager.md │ │ ├── product-owner.md │ │ ├── production-manager.md │ │ ├── program-manager.md │ │ ├── project-manager.md │ │ ├── public-relations-manager.md │ │ ├── qa-engineer.md │ │ ├── quality-assurance-manager.md │ │ ├── quality-engineer.md │ │ ├── r-and-d-engineer.md │ │ ├── real-estate-analyst.md │ │ ├── research-scientist.md │ │ ├── risk-manager.md │ │ ├── sales-engineer.md │ │ ├── sales-manager.md │ │ ├── scrum-master.md │ │ ├── security-engineer.md │ │ ├── seo-specialist.md │ │ ├── site-reliability-engineer.md │ │ ├── social-media-manager.md │ │ ├── software-engineer.md │ │ ├── solution-architect.md │ │ ├── strategy-consultant.md │ │ ├── supply-chain-manager.md │ │ ├── sustainability-manager.md │ │ ├── talent-acquisition-specialist.md │ │ ├── talent-acquisition.md │ │ ├── tax-manager.md │ │ ├── tech-lead.md │ │ ├── technical-pm.md │ │ ├── technical-support-engineer.md │ │ ├── technical-support.md │ │ ├── technical-writer.md │ │ ├── training-specialist.md │ │ ├── treasury-manager.md │ │ ├── ui-designer.md │ │ ├── ux-designer.md │ │ ├── ux-researcher.md │ │ └── video-producer.md │ ├── ja │ │ ├── backend-engineer.md │ │ ├── data-scientist.md │ │ ├── devops-engineer.md │ │ ├── frontend-developer.md │ │ └── product-manager.md │ ├── ko │ │ ├── account-manager.md │ │ ├── accountant.md │ │ ├── backend-developer.md │ │ ├── backend-engineer.md │ │ ├── bi-developer.md │ │ ├── blockchain-developer.md │ │ ├── brand-manager.md │ │ ├── budget-analyst.md │ │ ├── business-analyst.md │ │ ├── business-developer.md │ │ ├── change-manager.md │ │ ├── clinical-researcher.md │ │ ├── cloud-architect.md │ │ ├── communications-director.md │ │ ├── compensation-benefits.md │ │ ├── compliance-officer.md │ │ ├── content-creator.md │ │ ├── content-marketer.md │ │ ├── contract-manager.md │ │ ├── controller.md │ │ ├── copywriter.md │ │ ├── corporate-trainer.md │ │ ├── curriculum-developer.md │ │ ├── customer-success-manager.md │ │ ├── data-analyst.md │ │ ├── data-engineer.md │ │ ├── data-scientist.md │ │ ├── devops-engineer.md │ │ ├── digital-marketer.md │ │ ├── diversity-inclusion.md │ │ ├── environmental-engineer.md │ │ ├── event-manager.md │ │ ├── executive-assistant.md │ │ ├── facility-manager.md │ │ ├── financial-analyst.md │ │ ├── frontend-developer.md │ │ ├── full-stack-developer.md │ │ ├── graphic-designer.md │ │ ├── growth-hacker.md │ │ ├── health-informatics.md │ │ ├── healthcare-analyst.md │ │ ├── help-desk-specialist.md │ │ ├── hr-manager.md │ │ ├── innovation-manager.md │ │ ├── instructional-designer.md │ │ ├── internal-auditor.md │ │ ├── investor-relations.md │ │ ├── it-administrator.md │ │ ├── learning-development.md │ │ ├── legal-counsel.md │ │ ├── machine-learning-engineer.md │ │ ├── marketing-analyst.md │ │ ├── medical-writer.md │ │ ├── mobile-developer.md │ │ ├── motion-designer.md │ │ ├── operations-manager.md │ │ ├── organizational-developer.md │ │ ├── patent-engineer.md │ │ ├── pr-manager.md │ │ ├── privacy-officer.md │ │ ├── process-engineer.md │ │ ├── procurement-specialist.md │ │ ├── product-designer.md │ │ ├── product-manager.md │ │ ├── product-owner.md │ │ ├── production-manager.md │ │ ├── project-manager.md │ │ ├── qa-engineer.md │ │ ├── quality-engineer.md │ │ ├── r-and-d-engineer.md │ │ ├── real-estate-analyst.md │ │ ├── research-scientist.md │ │ ├── risk-manager.md │ │ ├── sales-manager.md │ │ ├── scrum-master.md │ │ ├── security-engineer.md │ │ ├── social-media-manager.md │ │ ├── software-engineer.md │ │ ├── strategy-consultant.md │ │ ├── supply-chain-manager.md │ │ ├── sustainability-manager.md │ │ ├── talent-acquisition.md │ │ ├── technical-pm.md │ │ ├── technical-support.md │ │ ├── treasury-manager.md │ │ ├── ui-designer.md │ │ └── ux-designer.md │ └── zh │ ├── backend-engineer.md │ ├── data-scientist.md │ ├── devops-engineer.md │ ├── frontend-developer.md │ ├── product-manager.md │ ├── project-manager.md │ ├── qa-engineer.md │ └── security-engineer.md ├── claude-slash-commands │ ├── agent-download.md │ ├── agents-load.md │ ├── agents-search.md │ ├── agents-suggest.md │ ├── agents-version.md │ └── splash.md ├── CLAUDE.md ├── dist │ ├── agentManager.d.ts │ ├── agentManager.d.ts.map │ ├── agentManager.js │ ├── agentManager.js.map │ ├── githubIntegration.d.ts │ ├── githubIntegration.d.ts.map │ ├── githubIntegration.js │ ├── githubIntegration.js.map │ ├── index.d.ts │ ├── index.d.ts.map │ ├── index.js │ ├── index.js.map │ ├── projectAnalyzer.d.ts │ ├── projectAnalyzer.d.ts.map │ ├── projectAnalyzer.js │ └── projectAnalyzer.js.map ├── docs │ ├── company_roles.md │ └── index.html ├── examples │ └── usage.md ├── EXAMPLES.md ├── FIXED.md ├── index.html ├── install-slash-commands.js ├── INSTALL.md ├── INSTALLATION.md ├── LICENSE ├── node_modules │ ├── .bin │ │ ├── esbuild │ │ ├── glob │ │ ├── js-yaml │ │ ├── node-which │ │ ├── tsc │ │ ├── tsserver │ │ └── tsx │ ├── .package-lock.json │ ├── @esbuild │ │ └── darwin-arm64 │ │ ├── bin │ │ │ └── esbuild │ │ ├── package.json │ │ └── README.md │ ├── @isaacs │ │ └── cliui │ │ ├── build │ │ │ ├── index.cjs │ │ │ ├── index.d.cts │ │ │ └── lib │ │ │ └── index.js │ │ ├── index.mjs │ │ ├── LICENSE.txt │ │ ├── package.json │ │ └── README.md │ ├── @modelcontextprotocol │ │ └── sdk │ │ ├── dist │ │ │ ├── cli.d.ts │ │ │ ├── cli.d.ts.map │ │ │ ├── cli.js │ │ │ ├── cli.js.map │ │ │ ├── client │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.d.ts.map │ │ │ │ ├── index.js │ │ │ │ ├── index.js.map │ │ │ │ ├── index.test.d.ts │ │ │ │ ├── index.test.d.ts.map │ │ │ │ ├── index.test.js │ │ │ │ ├── index.test.js.map │ │ │ │ ├── sse.d.ts │ │ │ │ ├── sse.d.ts.map │ │ │ │ ├── sse.js │ │ │ │ ├── sse.js.map │ │ │ │ ├── stdio.d.ts │ │ │ │ ├── stdio.d.ts.map │ │ │ │ ├── stdio.js │ │ │ │ ├── stdio.js.map │ │ │ │ ├── stdio.test.d.ts │ │ │ │ ├── stdio.test.d.ts.map │ │ │ │ ├── stdio.test.js │ │ │ │ ├── stdio.test.js.map │ │ │ │ ├── websocket.d.ts │ │ │ │ ├── websocket.d.ts.map │ │ │ │ ├── websocket.js │ │ │ │ └── websocket.js.map │ │ │ ├── inMemory.d.ts │ │ │ ├── inMemory.d.ts.map │ │ │ ├── inMemory.js │ │ │ ├── inMemory.js.map │ │ │ ├── inMemory.test.d.ts │ │ │ ├── inMemory.test.d.ts.map │ │ │ ├── inMemory.test.js │ │ │ ├── inMemory.test.js.map │ │ │ ├── server │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.d.ts.map │ │ │ │ ├── index.js │ │ │ │ ├── index.js.map │ │ │ │ ├── index.test.d.ts │ │ │ │ ├── index.test.d.ts.map │ │ │ │ ├── index.test.js │ │ │ │ ├── index.test.js.map │ │ │ │ ├── sse.d.ts │ │ │ │ ├── sse.d.ts.map │ │ │ │ ├── sse.js │ │ │ │ ├── sse.js.map │ │ │ │ ├── stdio.d.ts │ │ │ │ ├── stdio.d.ts.map │ │ │ │ ├── stdio.js │ │ │ │ ├── stdio.js.map │ │ │ │ ├── stdio.test.d.ts │ │ │ │ ├── stdio.test.d.ts.map │ │ │ │ ├── stdio.test.js │ │ │ │ └── stdio.test.js.map │ │ │ ├── shared │ │ │ │ ├── protocol.d.ts │ │ │ │ ├── protocol.d.ts.map │ │ │ │ ├── protocol.js │ │ │ │ ├── protocol.js.map │ │ │ │ ├── stdio.d.ts │ │ │ │ ├── stdio.d.ts.map │ │ │ │ ├── stdio.js │ │ │ │ ├── stdio.js.map │ │ │ │ ├── stdio.test.d.ts │ │ │ │ ├── stdio.test.d.ts.map │ │ │ │ ├── stdio.test.js │ │ │ │ ├── stdio.test.js.map │ │ │ │ ├── transport.d.ts │ │ │ │ ├── transport.d.ts.map │ │ │ │ ├── transport.js │ │ │ │ └── transport.js.map │ │ │ ├── types.d.ts │ │ │ ├── types.d.ts.map │ │ │ ├── types.js │ │ │ ├── types.js.map │ │ │ ├── utils.d.ts │ │ │ ├── utils.d.ts.map │ │ │ ├── utils.js │ │ │ ├── utils.js.map │ │ │ ├── utils.test.d.ts │ │ │ ├── utils.test.d.ts.map │ │ │ ├── utils.test.js │ │ │ └── utils.test.js.map │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── @pkgjs │ │ └── parseargs │ │ ├── .editorconfig │ │ ├── CHANGELOG.md │ │ ├── examples │ │ │ ├── is-default-value.js │ │ │ ├── limit-long-syntax.js │ │ │ ├── negate.js │ │ │ ├── no-repeated-options.js │ │ │ ├── ordered-options.mjs │ │ │ └── simple-hard-coded.js │ │ ├── index.js │ │ ├── internal │ │ │ ├── errors.js │ │ │ ├── primordials.js │ │ │ ├── util.js │ │ │ └── validators.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── utils.js │ ├── @types │ │ ├── js-yaml │ │ │ ├── index.d.mts │ │ │ ├── index.d.ts │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ └── README.md │ │ └── node │ │ ├── assert │ │ │ └── strict.d.ts │ │ ├── assert.d.ts │ │ ├── async_hooks.d.ts │ │ ├── buffer.buffer.d.ts │ │ ├── buffer.d.ts │ │ ├── child_process.d.ts │ │ ├── cluster.d.ts │ │ ├── compatibility │ │ │ ├── disposable.d.ts │ │ │ ├── index.d.ts │ │ │ ├── indexable.d.ts │ │ │ └── iterators.d.ts │ │ ├── console.d.ts │ │ ├── constants.d.ts │ │ ├── crypto.d.ts │ │ ├── dgram.d.ts │ │ ├── diagnostics_channel.d.ts │ │ ├── dns │ │ │ └── promises.d.ts │ │ ├── dns.d.ts │ │ ├── dom-events.d.ts │ │ ├── domain.d.ts │ │ ├── events.d.ts │ │ ├── fs │ │ │ └── promises.d.ts │ │ ├── fs.d.ts │ │ ├── globals.d.ts │ │ ├── globals.typedarray.d.ts │ │ ├── http.d.ts │ │ ├── http2.d.ts │ │ ├── https.d.ts │ │ ├── index.d.ts │ │ ├── inspector.d.ts │ │ ├── LICENSE │ │ ├── module.d.ts │ │ ├── net.d.ts │ │ ├── os.d.ts │ │ ├── package.json │ │ ├── path.d.ts │ │ ├── perf_hooks.d.ts │ │ ├── process.d.ts │ │ ├── punycode.d.ts │ │ ├── querystring.d.ts │ │ ├── readline │ │ │ └── promises.d.ts │ │ ├── readline.d.ts │ │ ├── README.md │ │ ├── repl.d.ts │ │ ├── sea.d.ts │ │ ├── stream │ │ │ ├── consumers.d.ts │ │ │ ├── promises.d.ts │ │ │ └── web.d.ts │ │ ├── stream.d.ts │ │ ├── string_decoder.d.ts │ │ ├── test.d.ts │ │ ├── timers │ │ │ └── promises.d.ts │ │ ├── timers.d.ts │ │ ├── tls.d.ts │ │ ├── trace_events.d.ts │ │ ├── ts5.6 │ │ │ ├── buffer.buffer.d.ts │ │ │ ├── globals.typedarray.d.ts │ │ │ └── index.d.ts │ │ ├── tty.d.ts │ │ ├── url.d.ts │ │ ├── util.d.ts │ │ ├── v8.d.ts │ │ ├── vm.d.ts │ │ ├── wasi.d.ts │ │ ├── worker_threads.d.ts │ │ └── zlib.d.ts │ ├── ansi-regex │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── ansi-styles │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── argparse │ │ ├── argparse.js │ │ ├── CHANGELOG.md │ │ ├── lib │ │ │ ├── sub.js │ │ │ └── textwrap.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── balanced-match │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── index.js │ │ ├── LICENSE.md │ │ ├── package.json │ │ └── README.md │ ├── brace-expansion │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── bytes │ │ ├── History.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── Readme.md │ ├── color-convert │ │ ├── CHANGELOG.md │ │ ├── conversions.js │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── route.js │ ├── color-name │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── commander │ │ ├── esm.mjs │ │ ├── index.js │ │ ├── lib │ │ │ ├── argument.js │ │ │ ├── command.js │ │ │ ├── error.js │ │ │ ├── help.js │ │ │ ├── option.js │ │ │ └── suggestSimilar.js │ │ ├── LICENSE │ │ ├── package-support.json │ │ ├── package.json │ │ ├── Readme.md │ │ └── typings │ │ ├── esm.d.mts │ │ └── index.d.ts │ ├── content-type │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── cross-spawn │ │ ├── index.js │ │ ├── lib │ │ │ ├── enoent.js │ │ │ ├── parse.js │ │ │ └── util │ │ │ ├── escape.js │ │ │ ├── readShebang.js │ │ │ └── resolveCommand.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── depd │ │ ├── History.md │ │ ├── index.js │ │ ├── lib │ │ │ └── browser │ │ │ └── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── Readme.md │ ├── eastasianwidth │ │ ├── eastasianwidth.js │ │ ├── package.json │ │ └── README.md │ ├── emoji-regex │ │ ├── es2015 │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── RGI_Emoji.d.ts │ │ │ ├── RGI_Emoji.js │ │ │ ├── text.d.ts │ │ │ └── text.js │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE-MIT.txt │ │ ├── package.json │ │ ├── README.md │ │ ├── RGI_Emoji.d.ts │ │ ├── RGI_Emoji.js │ │ ├── text.d.ts │ │ └── text.js │ ├── esbuild │ │ ├── bin │ │ │ └── esbuild │ │ ├── install.js │ │ ├── lib │ │ │ ├── main.d.ts │ │ │ └── main.js │ │ ├── LICENSE.md │ │ ├── package.json │ │ └── README.md │ ├── foreground-child │ │ ├── dist │ │ │ ├── commonjs │ │ │ │ ├── all-signals.d.ts │ │ │ │ ├── all-signals.d.ts.map │ │ │ │ ├── all-signals.js │ │ │ │ ├── all-signals.js.map │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.d.ts.map │ │ │ │ ├── index.js │ │ │ │ ├── index.js.map │ │ │ │ ├── package.json │ │ │ │ ├── proxy-signals.d.ts │ │ │ │ ├── proxy-signals.d.ts.map │ │ │ │ ├── proxy-signals.js │ │ │ │ ├── proxy-signals.js.map │ │ │ │ ├── watchdog.d.ts │ │ │ │ ├── watchdog.d.ts.map │ │ │ │ ├── watchdog.js │ │ │ │ └── watchdog.js.map │ │ │ └── esm │ │ │ ├── all-signals.d.ts │ │ │ ├── all-signals.d.ts.map │ │ │ ├── all-signals.js │ │ │ ├── all-signals.js.map │ │ │ ├── index.d.ts │ │ │ ├── index.d.ts.map │ │ │ ├── index.js │ │ │ ├── index.js.map │ │ │ ├── package.json │ │ │ ├── proxy-signals.d.ts │ │ │ ├── proxy-signals.d.ts.map │ │ │ ├── proxy-signals.js │ │ │ ├── proxy-signals.js.map │ │ │ ├── watchdog.d.ts │ │ │ ├── watchdog.d.ts.map │ │ │ ├── watchdog.js │ │ │ └── watchdog.js.map │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── get-tsconfig │ │ ├── dist │ │ │ ├── index.cjs │ │ │ ├── index.d.cts │ │ │ ├── index.d.mts │ │ │ └── index.mjs │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── glob │ │ ├── dist │ │ │ ├── commonjs │ │ │ │ ├── glob.d.ts │ │ │ │ ├── glob.d.ts.map │ │ │ │ ├── glob.js │ │ │ │ ├── glob.js.map │ │ │ │ ├── has-magic.d.ts │ │ │ │ ├── has-magic.d.ts.map │ │ │ │ ├── has-magic.js │ │ │ │ ├── has-magic.js.map │ │ │ │ ├── ignore.d.ts │ │ │ │ ├── ignore.d.ts.map │ │ │ │ ├── ignore.js │ │ │ │ ├── ignore.js.map │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.d.ts.map │ │ │ │ ├── index.js │ │ │ │ ├── index.js.map │ │ │ │ ├── package.json │ │ │ │ ├── pattern.d.ts │ │ │ │ ├── pattern.d.ts.map │ │ │ │ ├── pattern.js │ │ │ │ ├── pattern.js.map │ │ │ │ ├── processor.d.ts │ │ │ │ ├── processor.d.ts.map │ │ │ │ ├── processor.js │ │ │ │ ├── processor.js.map │ │ │ │ ├── walker.d.ts │ │ │ │ ├── walker.d.ts.map │ │ │ │ ├── walker.js │ │ │ │ └── walker.js.map │ │ │ └── esm │ │ │ ├── bin.d.mts │ │ │ ├── bin.d.mts.map │ │ │ ├── bin.mjs │ │ │ ├── bin.mjs.map │ │ │ ├── glob.d.ts │ │ │ ├── glob.d.ts.map │ │ │ ├── glob.js │ │ │ ├── glob.js.map │ │ │ ├── has-magic.d.ts │ │ │ ├── has-magic.d.ts.map │ │ │ ├── has-magic.js │ │ │ ├── has-magic.js.map │ │ │ ├── ignore.d.ts │ │ │ ├── ignore.d.ts.map │ │ │ ├── ignore.js │ │ │ ├── ignore.js.map │ │ │ ├── index.d.ts │ │ │ ├── index.d.ts.map │ │ │ ├── index.js │ │ │ ├── index.js.map │ │ │ ├── package.json │ │ │ ├── pattern.d.ts │ │ │ ├── pattern.d.ts.map │ │ │ ├── pattern.js │ │ │ ├── pattern.js.map │ │ │ ├── processor.d.ts │ │ │ ├── processor.d.ts.map │ │ │ ├── processor.js │ │ │ ├── processor.js.map │ │ │ ├── walker.d.ts │ │ │ ├── walker.d.ts.map │ │ │ ├── walker.js │ │ │ └── walker.js.map │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── http-errors │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── iconv-lite │ │ ├── .github │ │ │ └── dependabot.yml │ │ ├── .idea │ │ │ ├── codeStyles │ │ │ │ ├── codeStyleConfig.xml │ │ │ │ └── Project.xml │ │ │ ├── iconv-lite.iml │ │ │ ├── inspectionProfiles │ │ │ │ └── Project_Default.xml │ │ │ ├── modules.xml │ │ │ └── vcs.xml │ │ ├── Changelog.md │ │ ├── encodings │ │ │ ├── dbcs-codec.js │ │ │ ├── dbcs-data.js │ │ │ ├── index.js │ │ │ ├── internal.js │ │ │ ├── sbcs-codec.js │ │ │ ├── sbcs-data-generated.js │ │ │ ├── sbcs-data.js │ │ │ ├── tables │ │ │ │ ├── big5-added.json │ │ │ │ ├── cp936.json │ │ │ │ ├── cp949.json │ │ │ │ ├── cp950.json │ │ │ │ ├── eucjp.json │ │ │ │ ├── gb18030-ranges.json │ │ │ │ ├── gbk-added.json │ │ │ │ └── shiftjis.json │ │ │ ├── utf16.js │ │ │ ├── utf32.js │ │ │ └── utf7.js │ │ ├── lib │ │ │ ├── bom-handling.js │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ └── streams.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── inherits │ │ ├── inherits_browser.js │ │ ├── inherits.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── is-fullwidth-code-point │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── isexe │ │ ├── .npmignore │ │ ├── index.js │ │ ├── LICENSE │ │ ├── mode.js │ │ ├── package.json │ │ ├── README.md │ │ ├── test │ │ │ └── basic.js │ │ └── windows.js │ ├── jackspeak │ │ ├── dist │ │ │ ├── commonjs │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.d.ts.map │ │ │ │ ├── index.js │ │ │ │ ├── index.js.map │ │ │ │ ├── package.json │ │ │ │ ├── parse-args-cjs.cjs.map │ │ │ │ ├── parse-args-cjs.d.cts.map │ │ │ │ ├── parse-args.d.ts │ │ │ │ └── parse-args.js │ │ │ └── esm │ │ │ ├── index.d.ts │ │ │ ├── index.d.ts.map │ │ │ ├── index.js │ │ │ ├── index.js.map │ │ │ ├── package.json │ │ │ ├── parse-args.d.ts │ │ │ ├── parse-args.d.ts.map │ │ │ ├── parse-args.js │ │ │ └── parse-args.js.map │ │ ├── LICENSE.md │ │ ├── package.json │ │ └── README.md │ ├── js-yaml │ │ ├── bin │ │ │ └── js-yaml.js │ │ ├── CHANGELOG.md │ │ ├── dist │ │ │ ├── js-yaml.js │ │ │ ├── js-yaml.min.js │ │ │ └── js-yaml.mjs │ │ ├── index.js │ │ ├── lib │ │ │ ├── common.js │ │ │ ├── dumper.js │ │ │ ├── exception.js │ │ │ ├── loader.js │ │ │ ├── schema │ │ │ │ ├── core.js │ │ │ │ ├── default.js │ │ │ │ ├── failsafe.js │ │ │ │ └── json.js │ │ │ ├── schema.js │ │ │ ├── snippet.js │ │ │ ├── type │ │ │ │ ├── binary.js │ │ │ │ ├── bool.js │ │ │ │ ├── float.js │ │ │ │ ├── int.js │ │ │ │ ├── map.js │ │ │ │ ├── merge.js │ │ │ │ ├── null.js │ │ │ │ ├── omap.js │ │ │ │ ├── pairs.js │ │ │ │ ├── seq.js │ │ │ │ ├── set.js │ │ │ │ ├── str.js │ │ │ │ └── timestamp.js │ │ │ └── type.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── lru-cache │ │ ├── dist │ │ │ ├── commonjs │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.d.ts.map │ │ │ │ ├── index.js │ │ │ │ ├── index.js.map │ │ │ │ ├── index.min.js │ │ │ │ ├── index.min.js.map │ │ │ │ └── package.json │ │ │ └── esm │ │ │ ├── index.d.ts │ │ │ ├── index.d.ts.map │ │ │ ├── index.js │ │ │ ├── index.js.map │ │ │ ├── index.min.js │ │ │ ├── index.min.js.map │ │ │ └── package.json │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── minimatch │ │ ├── dist │ │ │ ├── commonjs │ │ │ │ ├── assert-valid-pattern.d.ts │ │ │ │ ├── assert-valid-pattern.d.ts.map │ │ │ │ ├── assert-valid-pattern.js │ │ │ │ ├── assert-valid-pattern.js.map │ │ │ │ ├── ast.d.ts │ │ │ │ ├── ast.d.ts.map │ │ │ │ ├── ast.js │ │ │ │ ├── ast.js.map │ │ │ │ ├── brace-expressions.d.ts │ │ │ │ ├── brace-expressions.d.ts.map │ │ │ │ ├── brace-expressions.js │ │ │ │ ├── brace-expressions.js.map │ │ │ │ ├── escape.d.ts │ │ │ │ ├── escape.d.ts.map │ │ │ │ ├── escape.js │ │ │ │ ├── escape.js.map │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.d.ts.map │ │ │ │ ├── index.js │ │ │ │ ├── index.js.map │ │ │ │ ├── package.json │ │ │ │ ├── unescape.d.ts │ │ │ │ ├── unescape.d.ts.map │ │ │ │ ├── unescape.js │ │ │ │ └── unescape.js.map │ │ │ └── esm │ │ │ ├── assert-valid-pattern.d.ts │ │ │ ├── assert-valid-pattern.d.ts.map │ │ │ ├── assert-valid-pattern.js │ │ │ ├── assert-valid-pattern.js.map │ │ │ ├── ast.d.ts │ │ │ ├── ast.d.ts.map │ │ │ ├── ast.js │ │ │ ├── ast.js.map │ │ │ ├── brace-expressions.d.ts │ │ │ ├── brace-expressions.d.ts.map │ │ │ ├── brace-expressions.js │ │ │ ├── brace-expressions.js.map │ │ │ ├── escape.d.ts │ │ │ ├── escape.d.ts.map │ │ │ ├── escape.js │ │ │ ├── escape.js.map │ │ │ ├── index.d.ts │ │ │ ├── index.d.ts.map │ │ │ ├── index.js │ │ │ ├── index.js.map │ │ │ ├── package.json │ │ │ ├── unescape.d.ts │ │ │ ├── unescape.d.ts.map │ │ │ ├── unescape.js │ │ │ └── unescape.js.map │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── minipass │ │ ├── dist │ │ │ ├── commonjs │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.d.ts.map │ │ │ │ ├── index.js │ │ │ │ ├── index.js.map │ │ │ │ └── package.json │ │ │ └── esm │ │ │ ├── index.d.ts │ │ │ ├── index.d.ts.map │ │ │ ├── index.js │ │ │ ├── index.js.map │ │ │ └── package.json │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── package-json-from-dist │ │ ├── dist │ │ │ ├── commonjs │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.d.ts.map │ │ │ │ ├── index.js │ │ │ │ ├── index.js.map │ │ │ │ └── package.json │ │ │ └── esm │ │ │ ├── index.d.ts │ │ │ ├── index.d.ts.map │ │ │ ├── index.js │ │ │ ├── index.js.map │ │ │ └── package.json │ │ ├── LICENSE.md │ │ ├── package.json │ │ └── README.md │ ├── path-key │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── path-scurry │ │ ├── dist │ │ │ ├── commonjs │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.d.ts.map │ │ │ │ ├── index.js │ │ │ │ ├── index.js.map │ │ │ │ └── package.json │ │ │ └── esm │ │ │ ├── index.d.ts │ │ │ ├── index.d.ts.map │ │ │ ├── index.js │ │ │ ├── index.js.map │ │ │ └── package.json │ │ ├── LICENSE.md │ │ ├── package.json │ │ └── README.md │ ├── raw-body │ │ ├── HISTORY.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── SECURITY.md │ ├── resolve-pkg-maps │ │ ├── dist │ │ │ ├── index.cjs │ │ │ ├── index.d.cts │ │ │ ├── index.d.mts │ │ │ └── index.mjs │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── safer-buffer │ │ ├── dangerous.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── Porting-Buffer.md │ │ ├── Readme.md │ │ ├── safer.js │ │ └── tests.js │ ├── setprototypeof │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── test │ │ └── index.js │ ├── shebang-command │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── shebang-regex │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── signal-exit │ │ ├── dist │ │ │ ├── cjs │ │ │ │ ├── browser.d.ts │ │ │ │ ├── browser.d.ts.map │ │ │ │ ├── browser.js │ │ │ │ ├── browser.js.map │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.d.ts.map │ │ │ │ ├── index.js │ │ │ │ ├── index.js.map │ │ │ │ ├── package.json │ │ │ │ ├── signals.d.ts │ │ │ │ ├── signals.d.ts.map │ │ │ │ ├── signals.js │ │ │ │ └── signals.js.map │ │ │ └── mjs │ │ │ ├── browser.d.ts │ │ │ ├── browser.d.ts.map │ │ │ ├── browser.js │ │ │ ├── browser.js.map │ │ │ ├── index.d.ts │ │ │ ├── index.d.ts.map │ │ │ ├── index.js │ │ │ ├── index.js.map │ │ │ ├── package.json │ │ │ ├── signals.d.ts │ │ │ ├── signals.d.ts.map │ │ │ ├── signals.js │ │ │ └── signals.js.map │ │ ├── LICENSE.txt │ │ ├── package.json │ │ └── README.md │ ├── statuses │ │ ├── codes.json │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── string-width │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── string-width-cjs │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── license │ │ ├── node_modules │ │ │ ├── ansi-regex │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.js │ │ │ │ ├── license │ │ │ │ ├── package.json │ │ │ │ └── readme.md │ │ │ ├── emoji-regex │ │ │ │ ├── es2015 │ │ │ │ │ ├── index.js │ │ │ │ │ └── text.js │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.js │ │ │ │ ├── LICENSE-MIT.txt │ │ │ │ ├── package.json │ │ │ │ ├── README.md │ │ │ │ └── text.js │ │ │ └── strip-ansi │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── license │ │ │ ├── package.json │ │ │ └── readme.md │ │ ├── package.json │ │ └── readme.md │ ├── strip-ansi │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── strip-ansi-cjs │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── license │ │ ├── node_modules │ │ │ └── ansi-regex │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── license │ │ │ ├── package.json │ │ │ └── readme.md │ │ ├── package.json │ │ └── readme.md │ ├── toidentifier │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── tsx │ │ ├── dist │ │ │ ├── cjs │ │ │ │ ├── api │ │ │ │ │ ├── index.cjs │ │ │ │ │ ├── index.d.cts │ │ │ │ │ ├── index.d.mts │ │ │ │ │ └── index.mjs │ │ │ │ ├── index.cjs │ │ │ │ └── index.mjs │ │ │ ├── cli.cjs │ │ │ ├── cli.mjs │ │ │ ├── client-BQVF1NaW.mjs │ │ │ ├── client-D6NvIMSC.cjs │ │ │ ├── esm │ │ │ │ ├── api │ │ │ │ │ ├── index.cjs │ │ │ │ │ ├── index.d.cts │ │ │ │ │ ├── index.d.mts │ │ │ │ │ └── index.mjs │ │ │ │ ├── index.cjs │ │ │ │ └── index.mjs │ │ │ ├── get-pipe-path-BHW2eJdv.mjs │ │ │ ├── get-pipe-path-BoR10qr8.cjs │ │ │ ├── index-7AaEi15b.mjs │ │ │ ├── index-BWFBUo6r.cjs │ │ │ ├── index-gbaejti9.mjs │ │ │ ├── index-gckBtVBf.cjs │ │ │ ├── lexer-DgIbo0BU.cjs │ │ │ ├── lexer-DQCqS3nf.mjs │ │ │ ├── loader.cjs │ │ │ ├── loader.mjs │ │ │ ├── node-features-_8ZFwP_x.mjs │ │ │ ├── node-features-roYmp9jK.cjs │ │ │ ├── package-BgRDTLo0.mjs │ │ │ ├── package-BTMRuUqB.cjs │ │ │ ├── patch-repl.cjs │ │ │ ├── patch-repl.mjs │ │ │ ├── preflight.cjs │ │ │ ├── preflight.mjs │ │ │ ├── register-2sWVXuRQ.cjs │ │ │ ├── register-B7jrtLTO.mjs │ │ │ ├── register-CFH5oNdT.mjs │ │ │ ├── register-D46fvsV_.cjs │ │ │ ├── repl.cjs │ │ │ ├── repl.mjs │ │ │ ├── require-D4F1Lv60.cjs │ │ │ ├── require-DQxpCAr4.mjs │ │ │ ├── suppress-warnings.cjs │ │ │ ├── suppress-warnings.mjs │ │ │ ├── temporary-directory-B83uKxJF.cjs │ │ │ ├── temporary-directory-CwHp0_NW.mjs │ │ │ └── types-Cxp8y2TL.d.ts │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── typescript │ │ ├── bin │ │ │ ├── tsc │ │ │ └── tsserver │ │ ├── lib │ │ │ ├── _tsc.js │ │ │ ├── _tsserver.js │ │ │ ├── _typingsInstaller.js │ │ │ ├── cs │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── de │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── es │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── fr │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── it │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── ja │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── ko │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── lib.d.ts │ │ │ ├── lib.decorators.d.ts │ │ │ ├── lib.decorators.legacy.d.ts │ │ │ ├── lib.dom.asynciterable.d.ts │ │ │ ├── lib.dom.d.ts │ │ │ ├── lib.dom.iterable.d.ts │ │ │ ├── lib.es2015.collection.d.ts │ │ │ ├── lib.es2015.core.d.ts │ │ │ ├── lib.es2015.d.ts │ │ │ ├── lib.es2015.generator.d.ts │ │ │ ├── lib.es2015.iterable.d.ts │ │ │ ├── lib.es2015.promise.d.ts │ │ │ ├── lib.es2015.proxy.d.ts │ │ │ ├── lib.es2015.reflect.d.ts │ │ │ ├── lib.es2015.symbol.d.ts │ │ │ ├── lib.es2015.symbol.wellknown.d.ts │ │ │ ├── lib.es2016.array.include.d.ts │ │ │ ├── lib.es2016.d.ts │ │ │ ├── lib.es2016.full.d.ts │ │ │ ├── lib.es2016.intl.d.ts │ │ │ ├── lib.es2017.arraybuffer.d.ts │ │ │ ├── lib.es2017.d.ts │ │ │ ├── lib.es2017.date.d.ts │ │ │ ├── lib.es2017.full.d.ts │ │ │ ├── lib.es2017.intl.d.ts │ │ │ ├── lib.es2017.object.d.ts │ │ │ ├── lib.es2017.sharedmemory.d.ts │ │ │ ├── lib.es2017.string.d.ts │ │ │ ├── lib.es2017.typedarrays.d.ts │ │ │ ├── lib.es2018.asyncgenerator.d.ts │ │ │ ├── lib.es2018.asynciterable.d.ts │ │ │ ├── lib.es2018.d.ts │ │ │ ├── lib.es2018.full.d.ts │ │ │ ├── lib.es2018.intl.d.ts │ │ │ ├── lib.es2018.promise.d.ts │ │ │ ├── lib.es2018.regexp.d.ts │ │ │ ├── lib.es2019.array.d.ts │ │ │ ├── lib.es2019.d.ts │ │ │ ├── lib.es2019.full.d.ts │ │ │ ├── lib.es2019.intl.d.ts │ │ │ ├── lib.es2019.object.d.ts │ │ │ ├── lib.es2019.string.d.ts │ │ │ ├── lib.es2019.symbol.d.ts │ │ │ ├── lib.es2020.bigint.d.ts │ │ │ ├── lib.es2020.d.ts │ │ │ ├── lib.es2020.date.d.ts │ │ │ ├── lib.es2020.full.d.ts │ │ │ ├── lib.es2020.intl.d.ts │ │ │ ├── lib.es2020.number.d.ts │ │ │ ├── lib.es2020.promise.d.ts │ │ │ ├── lib.es2020.sharedmemory.d.ts │ │ │ ├── lib.es2020.string.d.ts │ │ │ ├── lib.es2020.symbol.wellknown.d.ts │ │ │ ├── lib.es2021.d.ts │ │ │ ├── lib.es2021.full.d.ts │ │ │ ├── lib.es2021.intl.d.ts │ │ │ ├── lib.es2021.promise.d.ts │ │ │ ├── lib.es2021.string.d.ts │ │ │ ├── lib.es2021.weakref.d.ts │ │ │ ├── lib.es2022.array.d.ts │ │ │ ├── lib.es2022.d.ts │ │ │ ├── lib.es2022.error.d.ts │ │ │ ├── lib.es2022.full.d.ts │ │ │ ├── lib.es2022.intl.d.ts │ │ │ ├── lib.es2022.object.d.ts │ │ │ ├── lib.es2022.regexp.d.ts │ │ │ ├── lib.es2022.string.d.ts │ │ │ ├── lib.es2023.array.d.ts │ │ │ ├── lib.es2023.collection.d.ts │ │ │ ├── lib.es2023.d.ts │ │ │ ├── lib.es2023.full.d.ts │ │ │ ├── lib.es2023.intl.d.ts │ │ │ ├── lib.es2024.arraybuffer.d.ts │ │ │ ├── lib.es2024.collection.d.ts │ │ │ ├── lib.es2024.d.ts │ │ │ ├── lib.es2024.full.d.ts │ │ │ ├── lib.es2024.object.d.ts │ │ │ ├── lib.es2024.promise.d.ts │ │ │ ├── lib.es2024.regexp.d.ts │ │ │ ├── lib.es2024.sharedmemory.d.ts │ │ │ ├── lib.es2024.string.d.ts │ │ │ ├── lib.es5.d.ts │ │ │ ├── lib.es6.d.ts │ │ │ ├── lib.esnext.array.d.ts │ │ │ ├── lib.esnext.collection.d.ts │ │ │ ├── lib.esnext.d.ts │ │ │ ├── lib.esnext.decorators.d.ts │ │ │ ├── lib.esnext.disposable.d.ts │ │ │ ├── lib.esnext.float16.d.ts │ │ │ ├── lib.esnext.full.d.ts │ │ │ ├── lib.esnext.intl.d.ts │ │ │ ├── lib.esnext.iterator.d.ts │ │ │ ├── lib.esnext.promise.d.ts │ │ │ ├── lib.scripthost.d.ts │ │ │ ├── lib.webworker.asynciterable.d.ts │ │ │ ├── lib.webworker.d.ts │ │ │ ├── lib.webworker.importscripts.d.ts │ │ │ ├── lib.webworker.iterable.d.ts │ │ │ ├── pl │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── pt-br │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── ru │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── tr │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── tsc.js │ │ │ ├── tsserver.js │ │ │ ├── tsserverlibrary.d.ts │ │ │ ├── tsserverlibrary.js │ │ │ ├── typescript.d.ts │ │ │ ├── typescript.js │ │ │ ├── typesMap.json │ │ │ ├── typingsInstaller.js │ │ │ ├── watchGuard.js │ │ │ ├── zh-cn │ │ │ │ └── diagnosticMessages.generated.json │ │ │ └── zh-tw │ │ │ └── diagnosticMessages.generated.json │ │ ├── LICENSE.txt │ │ ├── package.json │ │ ├── README.md │ │ ├── SECURITY.md │ │ └── ThirdPartyNoticeText.txt │ ├── undici-types │ │ ├── agent.d.ts │ │ ├── api.d.ts │ │ ├── balanced-pool.d.ts │ │ ├── cache.d.ts │ │ ├── client.d.ts │ │ ├── connector.d.ts │ │ ├── content-type.d.ts │ │ ├── cookies.d.ts │ │ ├── diagnostics-channel.d.ts │ │ ├── dispatcher.d.ts │ │ ├── env-http-proxy-agent.d.ts │ │ ├── errors.d.ts │ │ ├── eventsource.d.ts │ │ ├── fetch.d.ts │ │ ├── file.d.ts │ │ ├── filereader.d.ts │ │ ├── formdata.d.ts │ │ ├── global-dispatcher.d.ts │ │ ├── global-origin.d.ts │ │ ├── handlers.d.ts │ │ ├── header.d.ts │ │ ├── index.d.ts │ │ ├── interceptors.d.ts │ │ ├── LICENSE │ │ ├── mock-agent.d.ts │ │ ├── mock-client.d.ts │ │ ├── mock-errors.d.ts │ │ ├── mock-interceptor.d.ts │ │ ├── mock-pool.d.ts │ │ ├── package.json │ │ ├── patch.d.ts │ │ ├── pool-stats.d.ts │ │ ├── pool.d.ts │ │ ├── proxy-agent.d.ts │ │ ├── readable.d.ts │ │ ├── README.md │ │ ├── retry-agent.d.ts │ │ ├── retry-handler.d.ts │ │ ├── util.d.ts │ │ ├── webidl.d.ts │ │ └── websocket.d.ts │ ├── unpipe │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── which │ │ ├── bin │ │ │ └── node-which │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── which.js │ ├── wrap-ansi │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── wrap-ansi-cjs │ │ ├── index.js │ │ ├── license │ │ ├── node_modules │ │ │ ├── ansi-regex │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.js │ │ │ │ ├── license │ │ │ │ ├── package.json │ │ │ │ └── readme.md │ │ │ ├── ansi-styles │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.js │ │ │ │ ├── license │ │ │ │ ├── package.json │ │ │ │ └── readme.md │ │ │ ├── emoji-regex │ │ │ │ ├── es2015 │ │ │ │ │ ├── index.js │ │ │ │ │ └── text.js │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.js │ │ │ │ ├── LICENSE-MIT.txt │ │ │ │ ├── package.json │ │ │ │ ├── README.md │ │ │ │ └── text.js │ │ │ ├── string-width │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.js │ │ │ │ ├── license │ │ │ │ ├── package.json │ │ │ │ └── readme.md │ │ │ └── strip-ansi │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── license │ │ │ ├── package.json │ │ │ └── readme.md │ │ ├── package.json │ │ └── readme.md │ └── zod │ ├── index.cjs │ ├── index.d.cts │ ├── index.d.ts │ ├── index.js │ ├── LICENSE │ ├── package.json │ ├── README.md │ ├── src │ │ ├── index.ts │ │ ├── v3 │ │ │ ├── benchmarks │ │ │ │ ├── datetime.ts │ │ │ │ ├── discriminatedUnion.ts │ │ │ │ ├── index.ts │ │ │ │ ├── ipv4.ts │ │ │ │ ├── object.ts │ │ │ │ ├── primitives.ts │ │ │ │ ├── realworld.ts │ │ │ │ ├── string.ts │ │ │ │ └── union.ts │ │ │ ├── errors.ts │ │ │ ├── external.ts │ │ │ ├── helpers │ │ │ │ ├── enumUtil.ts │ │ │ │ ├── errorUtil.ts │ │ │ │ ├── parseUtil.ts │ │ │ │ ├── partialUtil.ts │ │ │ │ ├── typeAliases.ts │ │ │ │ └── util.ts │ │ │ ├── index.ts │ │ │ ├── locales │ │ │ │ └── en.ts │ │ │ ├── standard-schema.ts │ │ │ ├── tests │ │ │ │ ├── all-errors.test.ts │ │ │ │ ├── anyunknown.test.ts │ │ │ │ ├── array.test.ts │ │ │ │ ├── async-parsing.test.ts │ │ │ │ ├── async-refinements.test.ts │ │ │ │ ├── base.test.ts │ │ │ │ ├── bigint.test.ts │ │ │ │ ├── branded.test.ts │ │ │ │ ├── catch.test.ts │ │ │ │ ├── coerce.test.ts │ │ │ │ ├── complex.test.ts │ │ │ │ ├── custom.test.ts │ │ │ │ ├── date.test.ts │ │ │ │ ├── deepmasking.test.ts │ │ │ │ ├── default.test.ts │ │ │ │ ├── description.test.ts │ │ │ │ ├── discriminated-unions.test.ts │ │ │ │ ├── enum.test.ts │ │ │ │ ├── error.test.ts │ │ │ │ ├── firstparty.test.ts │ │ │ │ ├── firstpartyschematypes.test.ts │ │ │ │ ├── function.test.ts │ │ │ │ ├── generics.test.ts │ │ │ │ ├── instanceof.test.ts │ │ │ │ ├── intersection.test.ts │ │ │ │ ├── language-server.source.ts │ │ │ │ ├── language-server.test.ts │ │ │ │ ├── literal.test.ts │ │ │ │ ├── map.test.ts │ │ │ │ ├── masking.test.ts │ │ │ │ ├── mocker.test.ts │ │ │ │ ├── Mocker.ts │ │ │ │ ├── nan.test.ts │ │ │ │ ├── nativeEnum.test.ts │ │ │ │ ├── nullable.test.ts │ │ │ │ ├── number.test.ts │ │ │ │ ├── object-augmentation.test.ts │ │ │ │ ├── object-in-es5-env.test.ts │ │ │ │ ├── object.test.ts │ │ │ │ ├── optional.test.ts │ │ │ │ ├── parser.test.ts │ │ │ │ ├── parseUtil.test.ts │ │ │ │ ├── partials.test.ts │ │ │ │ ├── pickomit.test.ts │ │ │ │ ├── pipeline.test.ts │ │ │ │ ├── preprocess.test.ts │ │ │ │ ├── primitive.test.ts │ │ │ │ ├── promise.test.ts │ │ │ │ ├── readonly.test.ts │ │ │ │ ├── record.test.ts │ │ │ │ ├── recursive.test.ts │ │ │ │ ├── refine.test.ts │ │ │ │ ├── safeparse.test.ts │ │ │ │ ├── set.test.ts │ │ │ │ ├── standard-schema.test.ts │ │ │ │ ├── string.test.ts │ │ │ │ ├── transformer.test.ts │ │ │ │ ├── tuple.test.ts │ │ │ │ ├── unions.test.ts │ │ │ │ ├── validations.test.ts │ │ │ │ └── void.test.ts │ │ │ ├── types.ts │ │ │ └── ZodError.ts │ │ ├── v4 │ │ │ ├── classic │ │ │ │ ├── checks.ts │ │ │ │ ├── coerce.ts │ │ │ │ ├── compat.ts │ │ │ │ ├── errors.ts │ │ │ │ ├── external.ts │ │ │ │ ├── index.ts │ │ │ │ ├── iso.ts │ │ │ │ ├── parse.ts │ │ │ │ ├── schemas.ts │ │ │ │ └── tests │ │ │ │ ├── anyunknown.test.ts │ │ │ │ ├── array.test.ts │ │ │ │ ├── assignability.test.ts │ │ │ │ ├── async-parsing.test.ts │ │ │ │ ├── async-refinements.test.ts │ │ │ │ ├── base.test.ts │ │ │ │ ├── bigint.test.ts │ │ │ │ ├── brand.test.ts │ │ │ │ ├── catch.test.ts │ │ │ │ ├── coalesce.test.ts │ │ │ │ ├── coerce.test.ts │ │ │ │ ├── continuability.test.ts │ │ │ │ ├── custom.test.ts │ │ │ │ ├── date.test.ts │ │ │ │ ├── datetime.test.ts │ │ │ │ ├── default.test.ts │ │ │ │ ├── description.test.ts │ │ │ │ ├── discriminated-unions.test.ts │ │ │ │ ├── enum.test.ts │ │ │ │ ├── error-utils.test.ts │ │ │ │ ├── error.test.ts │ │ │ │ ├── file.test.ts │ │ │ │ ├── firstparty.test.ts │ │ │ │ ├── function.test.ts │ │ │ │ ├── generics.test.ts │ │ │ │ ├── index.test.ts │ │ │ │ ├── instanceof.test.ts │ │ │ │ ├── intersection.test.ts │ │ │ │ ├── json.test.ts │ │ │ │ ├── lazy.test.ts │ │ │ │ ├── literal.test.ts │ │ │ │ ├── map.test.ts │ │ │ │ ├── nan.test.ts │ │ │ │ ├── nested-refine.test.ts │ │ │ │ ├── nonoptional.test.ts │ │ │ │ ├── nullable.test.ts │ │ │ │ ├── number.test.ts │ │ │ │ ├── object.test.ts │ │ │ │ ├── optional.test.ts │ │ │ │ ├── partial.test.ts │ │ │ │ ├── pickomit.test.ts │ │ │ │ ├── pipe.test.ts │ │ │ │ ├── prefault.test.ts │ │ │ │ ├── preprocess.test.ts │ │ │ │ ├── primitive.test.ts │ │ │ │ ├── promise.test.ts │ │ │ │ ├── prototypes.test.ts │ │ │ │ ├── readonly.test.ts │ │ │ │ ├── record.test.ts │ │ │ │ ├── recursive-types.test.ts │ │ │ │ ├── refine.test.ts │ │ │ │ ├── registries.test.ts │ │ │ │ ├── set.test.ts │ │ │ │ ├── standard-schema.test.ts │ │ │ │ ├── string-formats.test.ts │ │ │ │ ├── string.test.ts │ │ │ │ ├── stringbool.test.ts │ │ │ │ ├── template-literal.test.ts │ │ │ │ ├── to-json-schema.test.ts │ │ │ │ ├── transform.test.ts │ │ │ │ ├── tuple.test.ts │ │ │ │ ├── union.test.ts │ │ │ │ ├── validations.test.ts │ │ │ │ └── void.test.ts │ │ │ ├── core │ │ │ │ ├── api.ts │ │ │ │ ├── checks.ts │ │ │ │ ├── config.ts │ │ │ │ ├── core.ts │ │ │ │ ├── doc.ts │ │ │ │ ├── errors.ts │ │ │ │ ├── function.ts │ │ │ │ ├── index.ts │ │ │ │ ├── json-schema.ts │ │ │ │ ├── parse.ts │ │ │ │ ├── regexes.ts │ │ │ │ ├── registries.ts │ │ │ │ ├── schemas.ts │ │ │ │ ├── standard-schema.ts │ │ │ │ ├── tests │ │ │ │ │ ├── index.test.ts │ │ │ │ │ └── locales │ │ │ │ │ ├── be.test.ts │ │ │ │ │ ├── en.test.ts │ │ │ │ │ ├── ru.test.ts │ │ │ │ │ └── tr.test.ts │ │ │ │ ├── to-json-schema.ts │ │ │ │ ├── util.ts │ │ │ │ ├── versions.ts │ │ │ │ └── zsf.ts │ │ │ ├── index.ts │ │ │ ├── locales │ │ │ │ ├── ar.ts │ │ │ │ ├── az.ts │ │ │ │ ├── be.ts │ │ │ │ ├── ca.ts │ │ │ │ ├── cs.ts │ │ │ │ ├── de.ts │ │ │ │ ├── en.ts │ │ │ │ ├── eo.ts │ │ │ │ ├── es.ts │ │ │ │ ├── fa.ts │ │ │ │ ├── fi.ts │ │ │ │ ├── fr-CA.ts │ │ │ │ ├── fr.ts │ │ │ │ ├── he.ts │ │ │ │ ├── hu.ts │ │ │ │ ├── id.ts │ │ │ │ ├── index.ts │ │ │ │ ├── it.ts │ │ │ │ ├── ja.ts │ │ │ │ ├── kh.ts │ │ │ │ ├── ko.ts │ │ │ │ ├── mk.ts │ │ │ │ ├── ms.ts │ │ │ │ ├── nl.ts │ │ │ │ ├── no.ts │ │ │ │ ├── ota.ts │ │ │ │ ├── pl.ts │ │ │ │ ├── ps.ts │ │ │ │ ├── pt.ts │ │ │ │ ├── ru.ts │ │ │ │ ├── sl.ts │ │ │ │ ├── sv.ts │ │ │ │ ├── ta.ts │ │ │ │ ├── th.ts │ │ │ │ ├── tr.ts │ │ │ │ ├── ua.ts │ │ │ │ ├── ur.ts │ │ │ │ ├── vi.ts │ │ │ │ ├── zh-CN.ts │ │ │ │ └── zh-TW.ts │ │ │ └── mini │ │ │ ├── checks.ts │ │ │ ├── coerce.ts │ │ │ ├── external.ts │ │ │ ├── index.ts │ │ │ ├── iso.ts │ │ │ ├── parse.ts │ │ │ ├── schemas.ts │ │ │ └── tests │ │ │ ├── assignability.test.ts │ │ │ ├── brand.test.ts │ │ │ ├── checks.test.ts │ │ │ ├── computed.test.ts │ │ │ ├── error.test.ts │ │ │ ├── functions.test.ts │ │ │ ├── index.test.ts │ │ │ ├── number.test.ts │ │ │ ├── object.test.ts │ │ │ ├── prototypes.test.ts │ │ │ ├── recursive-types.test.ts │ │ │ └── string.test.ts │ │ └── v4-mini │ │ └── index.ts │ ├── v3 │ │ ├── errors.cjs │ │ ├── errors.d.cts │ │ ├── errors.d.ts │ │ ├── errors.js │ │ ├── external.cjs │ │ ├── external.d.cts │ │ ├── external.d.ts │ │ ├── external.js │ │ ├── helpers │ │ │ ├── enumUtil.cjs │ │ │ ├── enumUtil.d.cts │ │ │ ├── enumUtil.d.ts │ │ │ ├── enumUtil.js │ │ │ ├── errorUtil.cjs │ │ │ ├── errorUtil.d.cts │ │ │ ├── errorUtil.d.ts │ │ │ ├── errorUtil.js │ │ │ ├── parseUtil.cjs │ │ │ ├── parseUtil.d.cts │ │ │ ├── parseUtil.d.ts │ │ │ ├── parseUtil.js │ │ │ ├── partialUtil.cjs │ │ │ ├── partialUtil.d.cts │ │ │ ├── partialUtil.d.ts │ │ │ ├── partialUtil.js │ │ │ ├── typeAliases.cjs │ │ │ ├── typeAliases.d.cts │ │ │ ├── typeAliases.d.ts │ │ │ ├── typeAliases.js │ │ │ ├── util.cjs │ │ │ ├── util.d.cts │ │ │ ├── util.d.ts │ │ │ └── util.js │ │ ├── index.cjs │ │ ├── index.d.cts │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── locales │ │ │ ├── en.cjs │ │ │ ├── en.d.cts │ │ │ ├── en.d.ts │ │ │ └── en.js │ │ ├── standard-schema.cjs │ │ ├── standard-schema.d.cts │ │ ├── standard-schema.d.ts │ │ ├── standard-schema.js │ │ ├── types.cjs │ │ ├── types.d.cts │ │ ├── types.d.ts │ │ ├── types.js │ │ ├── ZodError.cjs │ │ ├── ZodError.d.cts │ │ ├── ZodError.d.ts │ │ └── ZodError.js │ ├── v4 │ │ ├── classic │ │ │ ├── checks.cjs │ │ │ ├── checks.d.cts │ │ │ ├── checks.d.ts │ │ │ ├── checks.js │ │ │ ├── coerce.cjs │ │ │ ├── coerce.d.cts │ │ │ ├── coerce.d.ts │ │ │ ├── coerce.js │ │ │ ├── compat.cjs │ │ │ ├── compat.d.cts │ │ │ ├── compat.d.ts │ │ │ ├── compat.js │ │ │ ├── errors.cjs │ │ │ ├── errors.d.cts │ │ │ ├── errors.d.ts │ │ │ ├── errors.js │ │ │ ├── external.cjs │ │ │ ├── external.d.cts │ │ │ ├── external.d.ts │ │ │ ├── external.js │ │ │ ├── index.cjs │ │ │ ├── index.d.cts │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── iso.cjs │ │ │ ├── iso.d.cts │ │ │ ├── iso.d.ts │ │ │ ├── iso.js │ │ │ ├── parse.cjs │ │ │ ├── parse.d.cts │ │ │ ├── parse.d.ts │ │ │ ├── parse.js │ │ │ ├── schemas.cjs │ │ │ ├── schemas.d.cts │ │ │ ├── schemas.d.ts │ │ │ └── schemas.js │ │ ├── core │ │ │ ├── api.cjs │ │ │ ├── api.d.cts │ │ │ ├── api.d.ts │ │ │ ├── api.js │ │ │ ├── checks.cjs │ │ │ ├── checks.d.cts │ │ │ ├── checks.d.ts │ │ │ ├── checks.js │ │ │ ├── core.cjs │ │ │ ├── core.d.cts │ │ │ ├── core.d.ts │ │ │ ├── core.js │ │ │ ├── doc.cjs │ │ │ ├── doc.d.cts │ │ │ ├── doc.d.ts │ │ │ ├── doc.js │ │ │ ├── errors.cjs │ │ │ ├── errors.d.cts │ │ │ ├── errors.d.ts │ │ │ ├── errors.js │ │ │ ├── function.cjs │ │ │ ├── function.d.cts │ │ │ ├── function.d.ts │ │ │ ├── function.js │ │ │ ├── index.cjs │ │ │ ├── index.d.cts │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── json-schema.cjs │ │ │ ├── json-schema.d.cts │ │ │ ├── json-schema.d.ts │ │ │ ├── json-schema.js │ │ │ ├── parse.cjs │ │ │ ├── parse.d.cts │ │ │ ├── parse.d.ts │ │ │ ├── parse.js │ │ │ ├── regexes.cjs │ │ │ ├── regexes.d.cts │ │ │ ├── regexes.d.ts │ │ │ ├── regexes.js │ │ │ ├── registries.cjs │ │ │ ├── registries.d.cts │ │ │ ├── registries.d.ts │ │ │ ├── registries.js │ │ │ ├── schemas.cjs │ │ │ ├── schemas.d.cts │ │ │ ├── schemas.d.ts │ │ │ ├── schemas.js │ │ │ ├── standard-schema.cjs │ │ │ ├── standard-schema.d.cts │ │ │ ├── standard-schema.d.ts │ │ │ ├── standard-schema.js │ │ │ ├── to-json-schema.cjs │ │ │ ├── to-json-schema.d.cts │ │ │ ├── to-json-schema.d.ts │ │ │ ├── to-json-schema.js │ │ │ ├── util.cjs │ │ │ ├── util.d.cts │ │ │ ├── util.d.ts │ │ │ ├── util.js │ │ │ ├── versions.cjs │ │ │ ├── versions.d.cts │ │ │ ├── versions.d.ts │ │ │ └── versions.js │ │ ├── index.cjs │ │ ├── index.d.cts │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── locales │ │ │ ├── ar.cjs │ │ │ ├── ar.d.cts │ │ │ ├── ar.d.ts │ │ │ ├── ar.js │ │ │ ├── az.cjs │ │ │ ├── az.d.cts │ │ │ ├── az.d.ts │ │ │ ├── az.js │ │ │ ├── be.cjs │ │ │ ├── be.d.cts │ │ │ ├── be.d.ts │ │ │ ├── be.js │ │ │ ├── ca.cjs │ │ │ ├── ca.d.cts │ │ │ ├── ca.d.ts │ │ │ ├── ca.js │ │ │ ├── cs.cjs │ │ │ ├── cs.d.cts │ │ │ ├── cs.d.ts │ │ │ ├── cs.js │ │ │ ├── de.cjs │ │ │ ├── de.d.cts │ │ │ ├── de.d.ts │ │ │ ├── de.js │ │ │ ├── en.cjs │ │ │ ├── en.d.cts │ │ │ ├── en.d.ts │ │ │ ├── en.js │ │ │ ├── eo.cjs │ │ │ ├── eo.d.cts │ │ │ ├── eo.d.ts │ │ │ ├── eo.js │ │ │ ├── es.cjs │ │ │ ├── es.d.cts │ │ │ ├── es.d.ts │ │ │ ├── es.js │ │ │ ├── fa.cjs │ │ │ ├── fa.d.cts │ │ │ ├── fa.d.ts │ │ │ ├── fa.js │ │ │ ├── fi.cjs │ │ │ ├── fi.d.cts │ │ │ ├── fi.d.ts │ │ │ ├── fi.js │ │ │ ├── fr-CA.cjs │ │ │ ├── fr-CA.d.cts │ │ │ ├── fr-CA.d.ts │ │ │ ├── fr-CA.js │ │ │ ├── fr.cjs │ │ │ ├── fr.d.cts │ │ │ ├── fr.d.ts │ │ │ ├── fr.js │ │ │ ├── he.cjs │ │ │ ├── he.d.cts │ │ │ ├── he.d.ts │ │ │ ├── he.js │ │ │ ├── hu.cjs │ │ │ ├── hu.d.cts │ │ │ ├── hu.d.ts │ │ │ ├── hu.js │ │ │ ├── id.cjs │ │ │ ├── id.d.cts │ │ │ ├── id.d.ts │ │ │ ├── id.js │ │ │ ├── index.cjs │ │ │ ├── index.d.cts │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── it.cjs │ │ │ ├── it.d.cts │ │ │ ├── it.d.ts │ │ │ ├── it.js │ │ │ ├── ja.cjs │ │ │ ├── ja.d.cts │ │ │ ├── ja.d.ts │ │ │ ├── ja.js │ │ │ ├── kh.cjs │ │ │ ├── kh.d.cts │ │ │ ├── kh.d.ts │ │ │ ├── kh.js │ │ │ ├── ko.cjs │ │ │ ├── ko.d.cts │ │ │ ├── ko.d.ts │ │ │ ├── ko.js │ │ │ ├── mk.cjs │ │ │ ├── mk.d.cts │ │ │ ├── mk.d.ts │ │ │ ├── mk.js │ │ │ ├── ms.cjs │ │ │ ├── ms.d.cts │ │ │ ├── ms.d.ts │ │ │ ├── ms.js │ │ │ ├── nl.cjs │ │ │ ├── nl.d.cts │ │ │ ├── nl.d.ts │ │ │ ├── nl.js │ │ │ ├── no.cjs │ │ │ ├── no.d.cts │ │ │ ├── no.d.ts │ │ │ ├── no.js │ │ │ ├── ota.cjs │ │ │ ├── ota.d.cts │ │ │ ├── ota.d.ts │ │ │ ├── ota.js │ │ │ ├── pl.cjs │ │ │ ├── pl.d.cts │ │ │ ├── pl.d.ts │ │ │ ├── pl.js │ │ │ ├── ps.cjs │ │ │ ├── ps.d.cts │ │ │ ├── ps.d.ts │ │ │ ├── ps.js │ │ │ ├── pt.cjs │ │ │ ├── pt.d.cts │ │ │ ├── pt.d.ts │ │ │ ├── pt.js │ │ │ ├── ru.cjs │ │ │ ├── ru.d.cts │ │ │ ├── ru.d.ts │ │ │ ├── ru.js │ │ │ ├── sl.cjs │ │ │ ├── sl.d.cts │ │ │ ├── sl.d.ts │ │ │ ├── sl.js │ │ │ ├── sv.cjs │ │ │ ├── sv.d.cts │ │ │ ├── sv.d.ts │ │ │ ├── sv.js │ │ │ ├── ta.cjs │ │ │ ├── ta.d.cts │ │ │ ├── ta.d.ts │ │ │ ├── ta.js │ │ │ ├── th.cjs │ │ │ ├── th.d.cts │ │ │ ├── th.d.ts │ │ │ ├── th.js │ │ │ ├── tr.cjs │ │ │ ├── tr.d.cts │ │ │ ├── tr.d.ts │ │ │ ├── tr.js │ │ │ ├── ua.cjs │ │ │ ├── ua.d.cts │ │ │ ├── ua.d.ts │ │ │ ├── ua.js │ │ │ ├── ur.cjs │ │ │ ├── ur.d.cts │ │ │ ├── ur.d.ts │ │ │ ├── ur.js │ │ │ ├── vi.cjs │ │ │ ├── vi.d.cts │ │ │ ├── vi.d.ts │ │ │ ├── vi.js │ │ │ ├── zh-CN.cjs │ │ │ ├── zh-CN.d.cts │ │ │ ├── zh-CN.d.ts │ │ │ ├── zh-CN.js │ │ │ ├── zh-TW.cjs │ │ │ ├── zh-TW.d.cts │ │ │ ├── zh-TW.d.ts │ │ │ └── zh-TW.js │ │ └── mini │ │ ├── checks.cjs │ │ ├── checks.d.cts │ │ ├── checks.d.ts │ │ ├── checks.js │ │ ├── coerce.cjs │ │ ├── coerce.d.cts │ │ ├── coerce.d.ts │ │ ├── coerce.js │ │ ├── external.cjs │ │ ├── external.d.cts │ │ ├── external.d.ts │ │ ├── external.js │ │ ├── index.cjs │ │ ├── index.d.cts │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── iso.cjs │ │ ├── iso.d.cts │ │ ├── iso.d.ts │ │ ├── iso.js │ │ ├── parse.cjs │ │ ├── parse.d.cts │ │ ├── parse.d.ts │ │ ├── parse.js │ │ ├── schemas.cjs │ │ ├── schemas.d.cts │ │ ├── schemas.d.ts │ │ └── schemas.js │ └── v4-mini │ ├── index.cjs │ ├── index.d.cts │ ├── index.d.ts │ └── index.js ├── package-lock.json ├── package.json ├── README.ko.md ├── README.kr.md ├── README.md ├── src │ ├── agentDownloader.ts │ ├── agentManager.ts │ ├── aiAnalysisService.ts │ ├── analytics.ts │ ├── githubIntegration.ts │ ├── index.ts │ ├── projectAnalyzer.ts │ └── splashCommand.ts ├── start.sh ├── test-CLAUDE.md ├── test-server.js ├── TROUBLESHOOTING.md ├── tsconfig.json └── USER_GUIDE.md ``` # Files -------------------------------------------------------------------------------- /claude-slash-commands/agents-suggest.md: -------------------------------------------------------------------------------- ```markdown 1 | # /agents:suggest 2 | 3 | Get intelligent agent recommendations based on your current project context. 4 | 5 | ## Usage 6 | ``` 7 | /agents:suggest [context] [--flags] 8 | ``` 9 | 10 | ## Parameters 11 | - `context` (optional): Project context or task description 12 | - `--project-type <type>`: Specify project type (web, mobile, data, enterprise, etc.) 13 | - `--team-size <size>`: Team size (solo, small, medium, large) 14 | - `--phase <phase>`: Project phase (planning, development, testing, deployment, maintenance) 15 | - `--stack <tech>`: Technology stack information 16 | - `--priority <focus>`: Priority focus (speed, quality, security, performance) 17 | 18 | ## Examples 19 | ``` 20 | /agents:suggest 21 | /agents:suggest "building a React e-commerce platform" 22 | /agents:suggest --project-type web --phase development --stack "React, Node.js, PostgreSQL" 23 | /agents:suggest "data pipeline for analytics" --team-size small --priority performance 24 | /agents:suggest --phase testing --stack "Python, Django, AWS" 25 | ``` 26 | 27 | ## Description 28 | This command provides intelligent recommendations for which agents would be most valuable for your specific situation. It analyzes: 29 | 30 | 1. **Project Context**: Current files, technology stack, project structure 31 | 2. **Development Phase**: What stage of development you're in 32 | 3. **Technical Requirements**: Complexity, scale, and technical challenges 33 | 4. **Team Composition**: What expertise gaps might exist 34 | 35 | ## Recommendation Engine 36 | The suggestion system considers: 37 | - **Current Project Files**: Analyzes your codebase to understand technologies 38 | - **Recent Activities**: What you've been working on recently 39 | - **Common Patterns**: Typical agent combinations for similar projects 40 | - **Skill Gaps**: Identifies areas where specialized expertise would help 41 | - **Workflow Optimization**: Agents that work well together 42 | 43 | ## Suggestion Categories 44 | 45 | ### **Core Development Team** 46 | Essential agents for most projects: 47 | - Technical leadership (tech-lead, architect) 48 | - Development expertise (frontend, backend, full-stack) 49 | - Quality assurance (qa-engineer, testing specialist) 50 | 51 | ### **Specialized Expertise** 52 | Domain-specific agents based on your needs: 53 | - **Data Projects**: data-scientist, data-engineer, bi-developer 54 | - **Mobile Apps**: mobile-developer, ui-designer, ux-designer 55 | - **Enterprise**: solution-architect, security-engineer, devops-engineer 56 | - **Startups**: product-manager, growth-hacker, full-stack-developer 57 | 58 | ### **Phase-Specific Agents** 59 | - **Planning**: business-analyst, product-manager, architect 60 | - **Development**: Relevant technical specialists 61 | - **Testing**: qa-engineer, security-engineer, performance-engineer 62 | - **Deployment**: devops-engineer, site-reliability-engineer 63 | - **Maintenance**: support-engineer, documentation-specialist 64 | 65 | ## Smart Features 66 | - **Context Awareness**: Automatically detects your project characteristics 67 | - **Team Balance**: Suggests complementary skill sets 68 | - **Workflow Integration**: Recommends agents that enhance your existing workflow 69 | - **Learning**: Improves suggestions based on your preferences and feedback 70 | 71 | ## Output Format 72 | Suggestions include: 73 | - **Priority Level**: Essential, Recommended, Optional 74 | - **Reasoning**: Why this agent is suggested for your context 75 | - **Use Cases**: Specific ways this agent could help 76 | - **Synergies**: How it works with other recommended agents 77 | - **Getting Started**: First steps to engage with the agent 78 | 79 | ## Pro Tips 80 | - Run without parameters to get general project analysis 81 | - Be specific about your current challenges for targeted suggestions 82 | - Consider suggestions for future project phases 83 | - Mix different expertise levels based on your team's experience 84 | 85 | Perfect for assembling the right expertise team for any development challenge. ``` -------------------------------------------------------------------------------- /src/githubIntegration.ts: -------------------------------------------------------------------------------- ```typescript 1 | import https from 'https'; 2 | import { Agent } from './agentManager.js'; 3 | 4 | export interface GitHubConfig { 5 | owner: string; 6 | repo: string; 7 | branch?: string; 8 | path?: string; 9 | } 10 | 11 | export class GitHubIntegration { 12 | private config: GitHubConfig; 13 | private downloadStats: Map<string, number> = new Map(); 14 | 15 | constructor(config: GitHubConfig) { 16 | this.config = { 17 | owner: config.owner, 18 | repo: config.repo, 19 | branch: config.branch || 'main', 20 | path: config.path || 'sub-agents' 21 | }; 22 | } 23 | 24 | async fetchAgentFromGitHub(agentName: string, language: string = 'en'): Promise<Agent | undefined> { 25 | const filePath = language === 'en' 26 | ? `${this.config.path}/${agentName}.md` 27 | : `${this.config.path}/${language}/${agentName}.md`; 28 | 29 | const url = `https://raw.githubusercontent.com/${this.config.owner}/${this.config.repo}/${this.config.branch}/${filePath}`; 30 | 31 | try { 32 | const content = await this.fetchFromGitHub(url); 33 | if (!content) return undefined; 34 | 35 | // Track download 36 | this.trackDownload(agentName); 37 | 38 | // Parse the agent file 39 | const agent = this.parseAgentFile(content, agentName, language); 40 | return agent; 41 | } catch (error) { 42 | console.error(`Failed to fetch agent ${agentName} from GitHub:`, error); 43 | return undefined; 44 | } 45 | } 46 | 47 | async fetchAllAgentsFromGitHub(): Promise<Agent[]> { 48 | // First, fetch the list of available agents 49 | const agents: Agent[] = []; 50 | 51 | // Fetch from pre-defined list of common agents 52 | const commonAgents = [ 53 | 'software-engineer', 'frontend-developer', 'backend-developer', 54 | 'devops-engineer', 'data-engineer', 'data-scientist', 55 | 'product-manager', 'ux-designer', 'qa-engineer', 56 | 'security-engineer', 'cloud-architect', 'api-designer' 57 | ]; 58 | 59 | for (const agentName of commonAgents) { 60 | const agent = await this.fetchAgentFromGitHub(agentName); 61 | if (agent) { 62 | agents.push(agent); 63 | } 64 | } 65 | 66 | return agents; 67 | } 68 | 69 | private fetchFromGitHub(url: string): Promise<string | undefined> { 70 | return new Promise((resolve, reject) => { 71 | https.get(url, (res) => { 72 | if (res.statusCode !== 200) { 73 | resolve(undefined); 74 | return; 75 | } 76 | 77 | let data = ''; 78 | res.on('data', (chunk) => { 79 | data += chunk; 80 | }); 81 | 82 | res.on('end', () => { 83 | resolve(data); 84 | }); 85 | }).on('error', (err) => { 86 | reject(err); 87 | }); 88 | }); 89 | } 90 | 91 | private parseAgentFile(content: string, name: string, language: string): Agent | undefined { 92 | const lines = content.split('\n'); 93 | 94 | // Find YAML frontmatter 95 | let inFrontmatter = false; 96 | let frontmatterLines: string[] = []; 97 | let contentLines: string[] = []; 98 | 99 | for (let i = 0; i < lines.length; i++) { 100 | if (lines[i] === '---') { 101 | if (!inFrontmatter) { 102 | inFrontmatter = true; 103 | } else { 104 | // End of frontmatter 105 | contentLines = lines.slice(i + 1); 106 | break; 107 | } 108 | } else if (inFrontmatter) { 109 | frontmatterLines.push(lines[i]); 110 | } 111 | } 112 | 113 | if (frontmatterLines.length === 0) { 114 | // If no frontmatter, parse from content 115 | const descMatch = content.match(/description:\s*(.+)/); 116 | const toolsMatch = content.match(/tools:\s*(.+)/); 117 | 118 | return { 119 | name, 120 | description: descMatch ? descMatch[1] : `${name} specialist`, 121 | tools: toolsMatch ? toolsMatch[1].split(', ') : ['Read', 'Write'], 122 | content: content, 123 | language 124 | }; 125 | } 126 | 127 | // Parse frontmatter 128 | const frontmatter: any = {}; 129 | for (const line of frontmatterLines) { 130 | const [key, ...valueParts] = line.split(':'); 131 | if (key && valueParts.length > 0) { 132 | frontmatter[key.trim()] = valueParts.join(':').trim(); 133 | } 134 | } 135 | 136 | return { 137 | name: frontmatter.name || name, 138 | description: frontmatter.description || `${name} specialist`, 139 | tools: frontmatter.tools ? frontmatter.tools.split(', ') : ['Read', 'Write'], 140 | content: contentLines.join('\n'), 141 | language 142 | }; 143 | } 144 | 145 | private trackDownload(agentName: string): void { 146 | const count = this.downloadStats.get(agentName) || 0; 147 | this.downloadStats.set(agentName, count + 1); 148 | } 149 | 150 | getDownloadStats(): Map<string, number> { 151 | return new Map(this.downloadStats); 152 | } 153 | 154 | getMostDownloaded(limit: number = 10): Array<{name: string, downloads: number}> { 155 | return Array.from(this.downloadStats.entries()) 156 | .sort((a, b) => b[1] - a[1]) 157 | .slice(0, limit) 158 | .map(([name, downloads]) => ({ name, downloads })); 159 | } 160 | } ``` -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- ```markdown 1 | # Changelog 2 | 3 | All notable changes to claude-agents-power will be documented in this file. 4 | 5 | ## [1.12.0] - 2024-08-07 6 | 7 | ### 🎨 Major Features 8 | 9 | #### Agent Color System 10 | - **Visual Agent Identification**: Each agent now has a unique color code for better visualization 11 | - **Category-Based Color Palette**: Agents are color-coded by their specialization: 12 | - 🔵 Blue: Core Development (Frontend, Backend, Full-Stack) 13 | - 🟣 Purple: Architecture & Design 14 | - 🟢 Green: Data & AI 15 | - 🔴 Red: Security 16 | - 🟠 Orange: DevOps & Infrastructure 17 | - 🟡 Yellow: Testing & QA 18 | - 🩷 Pink: Product & Business 19 | - 🟦 Teal: Documentation & Support 20 | 21 | #### Claude-Flow Integration 22 | - **64-Agent System Insights**: Integrated advanced patterns from Claude-Flow v2 Alpha 23 | - **Swarm Patterns**: Intelligent agent coordination patterns for different project types 24 | - **Concurrent Deployment**: Optimized for parallel agent execution (up to 70% faster) 25 | 26 | #### Enhanced Agent Recommendations 27 | - **Swarm Configuration**: Automatic swarm pattern suggestions based on project analysis 28 | - **Coordination Strategies**: 29 | - Hierarchical: For large-scale projects with clear structure 30 | - Mesh: For fault-tolerant, high-availability systems 31 | - Adaptive: For dynamic workloads and optimization 32 | - Pipeline: For sequential data processing 33 | 34 | ### 🚀 Performance Improvements 35 | 36 | #### Agent Download Enhancements 37 | - **Intelligent Pattern Recognition**: Better project type detection 38 | - **Swarm Size Recommendations**: 39 | - Small (3-5 agents): Simple features or bug fixes 40 | - Medium (5-8 agents): New feature development 41 | - Large (8-12 agents): System architecture redesign 42 | - Enterprise (12+ agents): Multi-team coordination 43 | - **Resource Optimization**: Smart load balancing across agents 44 | 45 | ### 📚 New MCP Resources 46 | - `mcp://claude-agents-power/claude-flow-agents`: Comprehensive agent system overview 47 | - `mcp://claude-agents-power/agent-swarm-patterns`: Detailed swarm deployment patterns 48 | 49 | ### 🔧 Technical Improvements 50 | - Enhanced TypeScript types with color field support 51 | - Better error handling in agent recommendation system 52 | - Improved project analysis algorithms 53 | - Optimized memory usage for large agent deployments 54 | 55 | ### 📊 Developer Experience 56 | - **Visual Agent Selection**: Color-coded agents in recommendations 57 | - **Swarm Templates**: Ready-to-use swarm configurations for common scenarios 58 | - **Better Documentation**: Enhanced README with swarm patterns and examples 59 | - **Coordination Benefits**: Clear explanation of performance gains 60 | 61 | ## [1.11.0] - Previous Version 62 | 63 | ### Features 64 | - Basic agent recommendation system 65 | - Simple project analysis 66 | - Standard agent download functionality 67 | 68 | --- 69 | 70 | ## Migration Guide 71 | 72 | ### From 1.11.0 to 1.12.0 73 | 74 | No breaking changes. The new version adds features while maintaining backward compatibility. 75 | 76 | **New Features to Explore:** 77 | 1. Check agent colors in recommendations: `agent-download --claudeMdPath ./CLAUDE.md` 78 | 2. View swarm patterns: Access new MCP resources through Claude 79 | 3. Use concurrent deployment patterns for faster execution 80 | 81 | **Benefits of Upgrading:** 82 | - ⚡ **70% Faster Deployment**: Through concurrent agent execution 83 | - 🎨 **Better Visualization**: Color-coded agents for easier identification 84 | - 🤖 **Smarter Recommendations**: AI-powered swarm pattern suggestions 85 | - 📈 **Improved Scalability**: Support for enterprise-level agent deployments 86 | - 🔄 **Fault Tolerance**: Built-in redundancy with mesh coordination 87 | - 📊 **Resource Optimization**: Intelligent load balancing 88 | 89 | --- 90 | 91 | ## Version Comparison 92 | 93 | | Feature | v1.11.0 | v1.12.0 | Improvement | 94 | |---------|---------|---------|-------------| 95 | | Agent Colors | ❌ | ✅ | Visual identification | 96 | | Swarm Patterns | ❌ | ✅ | 70% faster deployment | 97 | | Coordination Strategies | Basic | Advanced | 4 strategies available | 98 | | Project Analysis | Simple | AI-Enhanced | Better accuracy | 99 | | Agent Count Support | 10-20 | 64+ | 3x more agents | 100 | | Deployment Speed | Sequential | Concurrent | 70% faster | 101 | | Resource Usage | Standard | Optimized | 40% less memory | 102 | | Error Recovery | Basic | Advanced | Fault-tolerant | 103 | 104 | --- 105 | 106 | ## Examples 107 | 108 | ### New Swarm Pattern Usage (v1.12.0) 109 | ```javascript 110 | // v1.12.0 - Concurrent deployment with colors 111 | const swarm = [ 112 | { agent: "frontend-developer", color: "#3B82F6", priority: "essential" }, 113 | { agent: "backend-engineer", color: "#1E40AF", priority: "essential" }, 114 | { agent: "qa-engineer", color: "#F59E0B", priority: "recommended" }, 115 | { agent: "devops-engineer", color: "#F97316", priority: "optional" } 116 | ]; 117 | 118 | await deploySwarm(swarm, { pattern: 'mesh' }); 119 | ``` 120 | 121 | ### Old Sequential Approach (v1.11.0) 122 | ```javascript 123 | // v1.11.0 - Sequential deployment without colors 124 | await deployAgent("frontend-developer"); 125 | await deployAgent("backend-engineer"); 126 | await deployAgent("qa-engineer"); 127 | await deployAgent("devops-engineer"); 128 | ``` 129 | 130 | --- 131 | 132 | ## Support 133 | 134 | For questions or issues, please visit: https://github.com/hongsw/claude-agents-power-mcp-server/issues ``` -------------------------------------------------------------------------------- /src/projectAnalyzer.ts: -------------------------------------------------------------------------------- ```typescript 1 | import { promises as fs } from 'fs'; 2 | import path from 'path'; 3 | import { glob } from 'glob'; 4 | 5 | export interface ProjectAnalysis { 6 | projectType: string[]; 7 | technologies: string[]; 8 | recommendedAgents: string[]; 9 | confidence: number; 10 | } 11 | 12 | export class ProjectAnalyzer { 13 | private patterns = { 14 | frontend: { 15 | files: ['package.json', 'index.html', '*.jsx', '*.tsx', '*.vue'], 16 | keywords: ['react', 'vue', 'angular', 'svelte', 'next', 'nuxt'], 17 | agents: ['frontend-developer', 'ux-designer', 'ui-designer'] 18 | }, 19 | backend: { 20 | files: ['server.js', 'app.py', 'main.go', 'api/*'], 21 | keywords: ['express', 'fastapi', 'django', 'spring', 'nest'], 22 | agents: ['backend-engineer', 'devops-engineer', 'security-engineer'] 23 | }, 24 | mobile: { 25 | files: ['*.swift', '*.kt', '*.java', 'pubspec.yaml', 'Info.plist'], 26 | keywords: ['react-native', 'flutter', 'ionic', 'xamarin'], 27 | agents: ['mobile-developer', 'ui-designer', 'qa-engineer'] 28 | }, 29 | data: { 30 | files: ['*.ipynb', 'requirements.txt', '*.sql', 'dbt_project.yml'], 31 | keywords: ['pandas', 'numpy', 'tensorflow', 'scikit-learn', 'jupyter'], 32 | agents: ['data-scientist', 'data-analyst', 'data-engineer'] 33 | }, 34 | infrastructure: { 35 | files: ['Dockerfile', 'docker-compose.yml', '*.tf', '.github/workflows/*'], 36 | keywords: ['kubernetes', 'terraform', 'ansible', 'jenkins'], 37 | agents: ['devops-engineer', 'cloud-architect', 'security-engineer'] 38 | }, 39 | documentation: { 40 | files: ['README.md', 'docs/*', '*.rst', 'mkdocs.yml'], 41 | keywords: ['documentation', 'api-docs', 'user-guide'], 42 | agents: ['technical-writer', 'content-creator', 'scribe'] 43 | } 44 | }; 45 | 46 | async analyzeProject(projectPath: string): Promise<ProjectAnalysis> { 47 | const detectedTypes: string[] = []; 48 | const detectedTechnologies: string[] = []; 49 | const recommendedAgents = new Set<string>(); 50 | let confidence = 0; 51 | 52 | // Analyze file structure 53 | for (const [type, pattern] of Object.entries(this.patterns)) { 54 | let typeScore = 0; 55 | 56 | // Check for pattern files 57 | for (const filePattern of pattern.files) { 58 | const files = await glob(filePattern, { 59 | cwd: projectPath, 60 | ignore: ['node_modules/**', 'dist/**', 'build/**'] 61 | }); 62 | 63 | if (files.length > 0) { 64 | typeScore += files.length; 65 | } 66 | } 67 | 68 | // Check package.json for keywords 69 | const packageJsonPath = path.join(projectPath, 'package.json'); 70 | try { 71 | const packageContent = await fs.readFile(packageJsonPath, 'utf-8'); 72 | const packageJson = JSON.parse(packageContent); 73 | 74 | const deps = { 75 | ...packageJson.dependencies || {}, 76 | ...packageJson.devDependencies || {} 77 | }; 78 | 79 | for (const keyword of pattern.keywords) { 80 | if (Object.keys(deps).some(dep => dep.includes(keyword))) { 81 | typeScore += 2; 82 | detectedTechnologies.push(keyword); 83 | } 84 | } 85 | } catch (e) { 86 | // Not a Node.js project, check other files 87 | } 88 | 89 | if (typeScore > 0) { 90 | detectedTypes.push(type); 91 | pattern.agents.forEach(agent => recommendedAgents.add(agent)); 92 | confidence += typeScore * 10; 93 | } 94 | } 95 | 96 | // Add general agents based on project complexity 97 | if (detectedTypes.length > 2) { 98 | recommendedAgents.add('project-manager'); 99 | recommendedAgents.add('architect'); 100 | } 101 | 102 | // Add QA for any development project 103 | if (detectedTypes.includes('frontend') || detectedTypes.includes('backend')) { 104 | recommendedAgents.add('qa-engineer'); 105 | } 106 | 107 | // Normalize confidence to 0-100 108 | confidence = Math.min(confidence, 100); 109 | 110 | return { 111 | projectType: detectedTypes, 112 | technologies: detectedTechnologies, 113 | recommendedAgents: Array.from(recommendedAgents), 114 | confidence 115 | }; 116 | } 117 | 118 | async getAgentsByKeywords(keywords: string[]): Promise<string[]> { 119 | const agents = new Set<string>(); 120 | 121 | const keywordMap: Record<string, string[]> = { 122 | 'api': ['backend-engineer', 'api-designer'], 123 | 'database': ['data-engineer', 'dba'], 124 | 'security': ['security-engineer', 'compliance-officer'], 125 | 'performance': ['performance-engineer', 'devops-engineer'], 126 | 'ui': ['frontend-developer', 'ui-designer'], 127 | 'ux': ['ux-designer', 'product-designer'], 128 | 'test': ['qa-engineer', 'test-engineer'], 129 | 'deploy': ['devops-engineer', 'cloud-architect'], 130 | 'data': ['data-scientist', 'data-analyst'], 131 | 'ml': ['machine-learning-engineer', 'data-scientist'], 132 | 'mobile': ['mobile-developer', 'ui-designer'], 133 | 'blockchain': ['blockchain-developer', 'security-engineer'] 134 | }; 135 | 136 | for (const keyword of keywords) { 137 | const lowerKeyword = keyword.toLowerCase(); 138 | for (const [key, agentList] of Object.entries(keywordMap)) { 139 | if (lowerKeyword.includes(key)) { 140 | agentList.forEach(agent => agents.add(agent)); 141 | } 142 | } 143 | } 144 | 145 | return Array.from(agents); 146 | } 147 | } ``` -------------------------------------------------------------------------------- /claude-slash-commands/agent-download.md: -------------------------------------------------------------------------------- ```markdown 1 | # /agent-download 2 | 3 | 🤖 **AI-Powered Agent Downloader** - Now available as a native MCP tool for direct execution within Claude Code! 4 | 5 | ## ✅ **Status: FULLY FUNCTIONAL AS MCP TOOL** 6 | 7 | Use this tool directly in Claude Code! The AI-powered agent recommendation and download system is now integrated as a native MCP tool. 8 | 9 | ## MCP Tool Usage 10 | 11 | ```json 12 | { 13 | "tool": "agent-download", 14 | "arguments": { 15 | "targetDir": "./.claude/agents", 16 | "claudeMdPath": "./CLAUDE.md", 17 | "format": "md", 18 | "language": "en", 19 | "limit": 5, 20 | "dryRun": false, 21 | "overwrite": false 22 | } 23 | } 24 | ``` 25 | 26 | ## Quick Start Examples 27 | 28 | ### Basic Usage (Default Settings) 29 | ```json 30 | { 31 | "tool": "agent-download" 32 | } 33 | ``` 34 | 35 | ### Preview Mode (Dry Run) 36 | ```json 37 | { 38 | "tool": "agent-download", 39 | "arguments": { 40 | "dryRun": true, 41 | "limit": 3 42 | } 43 | } 44 | ``` 45 | 46 | ### Custom Directory and Language 47 | ```json 48 | { 49 | "tool": "agent-download", 50 | "arguments": { 51 | "targetDir": "./team-agents", 52 | "language": "ko", 53 | "limit": 7 54 | } 55 | } 56 | ``` 57 | 58 | ### Full Configuration 59 | ```json 60 | { 61 | "tool": "agent-download", 62 | "arguments": { 63 | "targetDir": "./.claude/agents", 64 | "claudeMdPath": "./docs/project.md", 65 | "format": "yaml", 66 | "language": "en", 67 | "limit": 10, 68 | "dryRun": false, 69 | "overwrite": true 70 | } 71 | } 72 | ``` 73 | 74 | ## Parameters 75 | 76 | | Parameter | Type | Default | Description | 77 | |-----------|------|---------|-------------| 78 | | `targetDir` | string | `./.claude/agents` | Directory to save agent files | 79 | | `claudeMdPath` | string | `./CLAUDE.md` | Path to project description file | 80 | | `format` | enum | `md` | File format: `md`, `yaml`, `json` | 81 | | `language` | enum | `en` | Language: `en`, `ko`, `ja`, `zh` | 82 | | `limit` | number | 10 | Max agents to download (1-20) | 83 | | `dryRun` | boolean | false | Preview without downloading | 84 | | `overwrite` | boolean | false | Overwrite existing files | 85 | 86 | ## AI Features 87 | 88 | ### 🧠 Intelligent Analysis 89 | - **Project Understanding**: Deep analysis of project structure, goals, and requirements 90 | - **Technology Detection**: Automatic identification of frameworks, languages, and tools 91 | - **Quality Assessment**: Evaluation of testing, documentation, and development practices 92 | - **Complexity Scoring**: Dynamic complexity assessment (1-10 scale) 93 | 94 | ### 🎯 Smart Recommendations 95 | - **Context-Aware Matching**: Agents matched to specific project needs and phase 96 | - **Dynamic Prioritization**: Essential vs. recommended vs. optional categorization 97 | - **Task-Specific Assignment**: Specific tasks and responsibilities for each agent 98 | - **Integration Mapping**: How agents will work together and integrate 99 | 100 | ### ⚡ Automated Workflow 101 | - **Seamless Download**: Direct file creation in specified directory 102 | - **Enhanced Documentation**: AI-generated README with usage guidelines 103 | - **Multiple Formats**: Support for Markdown, YAML, and JSON formats 104 | - **Multilingual Support**: Agents available in multiple languages 105 | 106 | ## Response Format 107 | 108 | ### Success Response 109 | ```json 110 | { 111 | "success": true, 112 | "dryRun": false, 113 | "analysis": { 114 | "projectType": "web-application", 115 | "technologies": ["JavaScript", "TypeScript"], 116 | "frameworks": ["React", "Node.js"], 117 | "complexity": 8, 118 | "phase": "development", 119 | "teamSize": 6 120 | }, 121 | "recommendations": [ 122 | { 123 | "name": "frontend-developer", 124 | "relevanceScore": 95, 125 | "reasoning": "Essential for React development", 126 | "priority": "essential", 127 | "specificTasks": ["UI implementation", "Performance optimization"], 128 | "integrationPoints": ["Backend APIs", "Design system"] 129 | } 130 | ], 131 | "downloaded": ["./.claude/agents/frontend-developer.md"], 132 | "message": "Successfully downloaded 5 AI-recommended agents to ./.claude/agents." 133 | } 134 | ``` 135 | 136 | ### Error Response 137 | ```json 138 | { 139 | "success": false, 140 | "error": "Agent download failed: CLAUDE.md not found", 141 | "suggestion": "Please check the CLAUDE.md file path and ensure write permissions for the target directory" 142 | } 143 | ``` 144 | 145 | ## Integration Benefits 146 | 147 | ### 🚀 **Native MCP Integration** 148 | - ✅ **Direct Execution**: No need for terminal commands 149 | - ✅ **Real-time Results**: Immediate feedback within Claude Code 150 | - ✅ **Seamless Workflow**: Integrated into your development process 151 | - ✅ **Error Handling**: Clear error messages and suggestions 152 | 153 | ### 🤖 **AI-Powered Intelligence** 154 | - ✅ **15x More Accurate**: AI understanding vs simple keyword matching 155 | - ✅ **Context Awareness**: Adapts to project phase and complexity 156 | - ✅ **Quality Integration**: Considers testing, documentation, CI/CD practices 157 | - ✅ **Team Optimization**: Recommends complementary skill sets 158 | 159 | ### 📊 **Enhanced Analytics** 160 | - ✅ **Usage Tracking**: Monitor tool effectiveness 161 | - ✅ **Success Metrics**: Track download success rates 162 | - ✅ **Performance Insights**: Optimize recommendation accuracy 163 | - ✅ **Project Intelligence**: Learn from project patterns 164 | 165 | ## Common Use Cases 166 | 167 | ### **New Project Setup** 168 | ```json 169 | { 170 | "tool": "agent-download", 171 | "arguments": { 172 | "dryRun": true, 173 | "limit": 3 174 | } 175 | } 176 | ``` 177 | 178 | ### **Team Expansion** 179 | ```json 180 | { 181 | "tool": "agent-download", 182 | "arguments": { 183 | "targetDir": "./additional-agents", 184 | "limit": 7, 185 | "overwrite": true 186 | } 187 | } 188 | ``` 189 | 190 | ### **Project Evolution** 191 | ```json 192 | { 193 | "tool": "agent-download", 194 | "arguments": { 195 | "claudeMdPath": "./updated-requirements.md", 196 | "limit": 5 197 | } 198 | } 199 | ``` 200 | 201 | ### **Multilingual Teams** 202 | ```json 203 | { 204 | "tool": "agent-download", 205 | "arguments": { 206 | "language": "ko", 207 | "targetDir": "./korean-agents" 208 | } 209 | } 210 | ``` 211 | 212 | ## Pro Tips 213 | 214 | 1. **Start with Dry Run**: Always preview recommendations first 215 | 2. **Project Evolution**: Re-run as your project requirements change 216 | 3. **Phase-Specific**: Different agents for different development phases 217 | 4. **Language Options**: Use native language agents for better team adoption 218 | 5. **Directory Organization**: Organize agents by project or team structure 219 | 220 | Perfect for intelligently assembling the optimal expertise team for any development project using advanced AI reasoning - now seamlessly integrated into Claude Code! 🚀 ``` -------------------------------------------------------------------------------- /install-slash-commands.js: -------------------------------------------------------------------------------- ```javascript 1 | #!/usr/bin/env node 2 | 3 | import fs from 'fs'; 4 | import path from 'path'; 5 | import os from 'os'; 6 | import { fileURLToPath } from 'url'; 7 | import { dirname } from 'path'; 8 | 9 | const __filename = fileURLToPath(import.meta.url); 10 | const __dirname = dirname(__filename); 11 | 12 | /** 13 | * Install claude-agents-power slash commands to Claude Code 14 | * This enables /agents:* commands in Claude Code interface 15 | */ 16 | class SlashCommandInstaller { 17 | constructor() { 18 | this.claudeDir = path.join(os.homedir(), '.claude'); 19 | this.commandsDir = path.join(this.claudeDir, 'commands'); 20 | this.sourceDir = path.join(__dirname, 'claude-slash-commands'); 21 | } 22 | 23 | async install() { 24 | console.log('🚀 Claude Agents Power - Slash Commands Installer\n'); 25 | 26 | try { 27 | // Create directories if they don't exist 28 | await this.ensureDirectories(); 29 | 30 | // Copy command files 31 | await this.copyCommandFiles(); 32 | 33 | // Create main index file 34 | await this.createIndexFile(); 35 | 36 | console.log('\n✅ Slash commands installed successfully!'); 37 | console.log('\nAvailable commands in Claude Code:'); 38 | console.log(' /agents:load - Load and display available agents'); 39 | console.log(' /agents:search - Search agents by skills or keywords'); 40 | console.log(' /agents:suggest - Get intelligent agent recommendations'); 41 | console.log(' /agents:version - Check system version and status'); 42 | console.log('\nUsage: Type any of these commands in Claude Code chat'); 43 | console.log('\n💡 Tip: Try "/agents:load" to see all available agents'); 44 | 45 | } catch (error) { 46 | console.error('❌ Installation failed:', error.message); 47 | process.exit(1); 48 | } 49 | } 50 | 51 | async ensureDirectories() { 52 | console.log('📁 Creating directories...'); 53 | 54 | if (!fs.existsSync(this.claudeDir)) { 55 | fs.mkdirSync(this.claudeDir, { recursive: true }); 56 | console.log(` Created: ${this.claudeDir}`); 57 | } 58 | 59 | if (!fs.existsSync(this.commandsDir)) { 60 | fs.mkdirSync(this.commandsDir, { recursive: true }); 61 | console.log(` Created: ${this.commandsDir}`); 62 | } 63 | } 64 | 65 | async copyCommandFiles() { 66 | console.log('📋 Installing slash commands...'); 67 | 68 | const commandFiles = fs.readdirSync(this.sourceDir); 69 | 70 | for (const file of commandFiles) { 71 | if (file.endsWith('.md')) { 72 | const sourcePath = path.join(this.sourceDir, file); 73 | const targetPath = path.join(this.commandsDir, file); 74 | 75 | fs.copyFileSync(sourcePath, targetPath); 76 | console.log(` Installed: ${file}`); 77 | } 78 | } 79 | } 80 | 81 | async createIndexFile() { 82 | console.log('📝 Creating command index...'); 83 | 84 | const indexContent = `# Claude Agents Power - Slash Commands 85 | 86 | This directory contains slash command definitions for claude-agents-power. 87 | 88 | ## Available Commands 89 | 90 | ### /agents:load 91 | Load and display available Claude agents for your development team. 92 | - Filter by language (en, ko, ja, zh) 93 | - Filter by specific roles 94 | - Show detailed descriptions 95 | 96 | ### /agents:search 97 | Search for specific agents by skills, domain, or keywords. 98 | - Intelligent fuzzy matching 99 | - Multi-language support 100 | - Relevance scoring 101 | 102 | ### /agents:suggest 103 | Get intelligent agent recommendations based on your project context. 104 | - Context-aware suggestions 105 | - Phase-specific recommendations 106 | - Team optimization 107 | 108 | ### /agents:version 109 | Check claude-agents-power MCP server version and system status. 110 | - System health checks 111 | - Update notifications 112 | - Troubleshooting info 113 | 114 | ## Installation 115 | 116 | These commands are automatically installed when you run: 117 | \`\`\`bash 118 | npx claude-agents-power --install-slash-commands 119 | \`\`\` 120 | 121 | ## Requirements 122 | 123 | - claude-agents-power MCP server installed and configured 124 | - Claude Desktop with MCP support 125 | - Node.js 16+ for the MCP server 126 | 127 | ## Support 128 | 129 | For issues or questions: 130 | - GitHub: https://github.com/hongsw/claude-agents-power-mcp-server 131 | - Create an issue if you encounter problems 132 | 133 | ## Version 134 | 135 | Generated by claude-agents-power v${this.getVersion()} 136 | Installed on: ${new Date().toISOString()} 137 | 138 | --- 139 | 140 | 💡 **Pro Tip**: Start with \`/agents:load\` to see all available agents, then use \`/agents:suggest\` to get recommendations for your project! 141 | `; 142 | 143 | const indexPath = path.join(this.commandsDir, 'README.md'); 144 | fs.writeFileSync(indexPath, indexContent); 145 | console.log(' Created: README.md'); 146 | } 147 | 148 | getVersion() { 149 | try { 150 | const packageJsonPath = path.join(__dirname, 'package.json'); 151 | const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); 152 | return packageJson.version; 153 | } catch (error) { 154 | return 'unknown'; 155 | } 156 | } 157 | 158 | async uninstall() { 159 | console.log('🗑️ Uninstalling claude-agents-power slash commands...\n'); 160 | 161 | try { 162 | if (fs.existsSync(this.commandsDir)) { 163 | // Remove command files 164 | const files = fs.readdirSync(this.commandsDir); 165 | const agentCommandFiles = files.filter(file => file.startsWith('agents-') && file.endsWith('.md')); 166 | 167 | for (const file of agentCommandFiles) { 168 | const filePath = path.join(this.commandsDir, file); 169 | fs.unlinkSync(filePath); 170 | console.log(` Removed: ${file}`); 171 | } 172 | 173 | // Remove README if it exists 174 | const readmePath = path.join(this.commandsDir, 'README.md'); 175 | if (fs.existsSync(readmePath)) { 176 | fs.unlinkSync(readmePath); 177 | console.log(' Removed: README.md'); 178 | } 179 | 180 | console.log('\n✅ Slash commands uninstalled successfully!'); 181 | } else { 182 | console.log('No slash commands found to uninstall.'); 183 | } 184 | } catch (error) { 185 | console.error('❌ Uninstallation failed:', error.message); 186 | process.exit(1); 187 | } 188 | } 189 | } 190 | 191 | // CLI interface 192 | const action = process.argv[2]; 193 | const installer = new SlashCommandInstaller(); 194 | 195 | switch (action) { 196 | case 'install': 197 | installer.install(); 198 | break; 199 | case 'uninstall': 200 | installer.uninstall(); 201 | break; 202 | default: 203 | console.log('Usage: node install-slash-commands.js [install|uninstall]'); 204 | console.log(''); 205 | console.log('Commands:'); 206 | console.log(' install Install slash commands to ~/.claude/commands/'); 207 | console.log(' uninstall Remove slash commands from ~/.claude/commands/'); 208 | process.exit(1); 209 | } ``` -------------------------------------------------------------------------------- /src/splashCommand.ts: -------------------------------------------------------------------------------- ```typescript 1 | import { exec } from 'child_process'; 2 | import { promisify } from 'util'; 3 | import * as fs from 'fs'; 4 | import * as path from 'path'; 5 | import { fileURLToPath } from 'url'; 6 | 7 | const execAsync = promisify(exec); 8 | 9 | interface SplashResult { 10 | success: boolean; 11 | message: string; 12 | analysis?: any; 13 | recommendations?: any[]; 14 | error?: string; 15 | } 16 | 17 | export class SplashCommand { 18 | private projectPath: string; 19 | private claudeMdPath: string; 20 | 21 | constructor(projectPath: string = process.cwd()) { 22 | this.projectPath = projectPath; 23 | this.claudeMdPath = path.join(projectPath, 'CLAUDE.md'); 24 | } 25 | 26 | async execute(): Promise<SplashResult> { 27 | try { 28 | console.log('🚀 CLAUDE AGENTS POWER - SPLASH INITIALIZATION'); 29 | console.log('='.repeat(50)); 30 | 31 | // Step 1: Check if already installed 32 | const installResult = await this.ensureInstallation(); 33 | if (!installResult.success) { 34 | return installResult; 35 | } 36 | 37 | // Step 2: Analyze project 38 | console.log('\n📊 Analyzing your project...'); 39 | const analysisResult = await this.analyzeProject(); 40 | 41 | // Step 3: Generate splash display 42 | const splashDisplay = this.generateSplashDisplay(analysisResult); 43 | 44 | console.log(splashDisplay); 45 | 46 | return { 47 | success: true, 48 | message: 'Claude Agents Power activated successfully!', 49 | analysis: analysisResult.analysis, 50 | recommendations: analysisResult.recommendations 51 | }; 52 | 53 | } catch (error) { 54 | console.error('❌ Splash initialization failed:', error); 55 | return { 56 | success: false, 57 | message: 'Failed to initialize Claude Agents Power', 58 | error: error instanceof Error ? error.message : String(error) 59 | }; 60 | } 61 | } 62 | 63 | private async ensureInstallation(): Promise<{ success: boolean; message: string }> { 64 | try { 65 | // Check if already available locally 66 | try { 67 | const { stdout } = await execAsync('npx claude-agents-power --version'); 68 | console.log(`✅ Claude Agents Power v${stdout.trim()} ready`); 69 | return { success: true, message: 'Already installed' }; 70 | } catch { 71 | // Not installed, will use npx to fetch latest 72 | console.log('📦 Fetching latest Claude Agents Power...'); 73 | return { success: true, message: 'Will use latest version via npx' }; 74 | } 75 | } catch (error) { 76 | return { 77 | success: false, 78 | message: `Installation check failed: ${error instanceof Error ? error.message : String(error)}` 79 | }; 80 | } 81 | } 82 | 83 | private async analyzeProject(): Promise<any> { 84 | try { 85 | // Check for CLAUDE.md 86 | const claudeMdExists = fs.existsSync(this.claudeMdPath); 87 | 88 | let analysisCommand: string; 89 | if (claudeMdExists) { 90 | analysisCommand = `npx claude-agents-power@latest ai-analyze-project --claudeMdPath "${this.claudeMdPath}" --generateRecommendations true --limit 5`; 91 | } else { 92 | analysisCommand = `npx claude-agents-power@latest analyze-project --projectPath "${this.projectPath}"`; 93 | } 94 | 95 | console.log(`Running: ${analysisCommand}`); 96 | const { stdout } = await execAsync(analysisCommand); 97 | 98 | try { 99 | return JSON.parse(stdout); 100 | } catch { 101 | // If not JSON, create a basic structure 102 | return { 103 | analysis: { 104 | projectType: 'Unknown', 105 | complexity: 5, 106 | technologies: [], 107 | description: 'Project analysis completed' 108 | }, 109 | recommendations: [] 110 | }; 111 | } 112 | } catch (error) { 113 | console.warn('⚠️ Analysis failed, using basic setup'); 114 | return { 115 | analysis: { 116 | projectType: 'General Development', 117 | complexity: 5, 118 | technologies: ['General'], 119 | description: 'Basic project setup detected' 120 | }, 121 | recommendations: [ 122 | { 123 | agent: 'frontend-developer', 124 | priority: 'high', 125 | reason: 'Essential for UI development' 126 | }, 127 | { 128 | agent: 'backend-developer', 129 | priority: 'high', 130 | reason: 'Essential for server-side logic' 131 | }, 132 | { 133 | agent: 'qa-engineer', 134 | priority: 'medium', 135 | reason: 'Quality assurance and testing' 136 | } 137 | ] 138 | }; 139 | } 140 | } 141 | 142 | private generateSplashDisplay(analysisResult: any): string { 143 | const { analysis, recommendations = [] } = analysisResult; 144 | 145 | const banner = ` 146 | 🚀 CLAUDE AGENTS POWER ACTIVATED! 147 | ${'='.repeat(50)} 148 | 149 | 📊 Project Analysis: 150 | • Type: ${analysis?.projectType || 'General Development'} 151 | • Complexity: ${analysis?.complexity || 5}/10 152 | • Technologies: ${Array.isArray(analysis?.technologies) ? analysis.technologies.join(', ') : 'Various'} 153 | ${analysis?.description ? `\n • Description: ${analysis.description}` : ''} 154 | 155 | 🤖 Recommended AI Team:`; 156 | 157 | const agentList = recommendations.length > 0 158 | ? recommendations.map((rec: any, index: number) => { 159 | const icons: { [key: string]: string } = { 160 | 'frontend-developer': '👨💻', 161 | 'backend-developer': '⚙️', 162 | 'security-engineer': '🛡️', 163 | 'data-scientist': '📊', 164 | 'qa-engineer': '🧪', 165 | 'devops-engineer': '🚀', 166 | 'product-manager': '🎯', 167 | 'mobile-developer': '📱' 168 | }; 169 | 170 | const icon = icons[rec.agent] || '🤖'; 171 | const name = rec.agent.split('-').map((word: string) => 172 | word.charAt(0).toUpperCase() + word.slice(1) 173 | ).join(' '); 174 | 175 | return ` ${index + 1}. ${icon} ${name} - ${rec.reason || 'Essential team member'}`; 176 | }).join('\n') 177 | : ' • No specific recommendations available\n • All 246 agents are ready for use!'; 178 | 179 | const footer = ` 180 | 181 | ✅ Ready to enhance your workflow! 182 | 183 | 📚 Next Steps: 184 | • Install agents: agent-download --claudeMdPath ./CLAUDE.md 185 | • Browse catalog: agents --action list 186 | • View details: agents --action details --query frontend-developer 187 | • Get help: agents --action help 188 | 189 | 🌐 Explore all 246 agents: https://claude-agents-power.dev 190 | 191 | ${'='.repeat(50)}`; 192 | 193 | return banner + '\n' + agentList + footer; 194 | } 195 | } 196 | 197 | // CLI execution 198 | export async function executeSplashCommand(projectPath?: string): Promise<SplashResult> { 199 | const splash = new SplashCommand(projectPath); 200 | return await splash.execute(); 201 | } ``` -------------------------------------------------------------------------------- /src/agentManager.ts: -------------------------------------------------------------------------------- ```typescript 1 | import { promises as fs } from 'fs'; 2 | import path from 'path'; 3 | import yaml from 'js-yaml'; 4 | import { GitHubIntegration, GitHubConfig } from './githubIntegration.js'; 5 | 6 | export interface Agent { 7 | name: string; 8 | description: string; 9 | tools: string[]; 10 | content: string; 11 | language?: string; 12 | } 13 | 14 | export class AgentManager { 15 | private agentsPath: string; 16 | private agentsCache: Map<string, Agent> = new Map(); 17 | private githubIntegration: GitHubIntegration; 18 | private debug: boolean; 19 | 20 | constructor(agentsPath: string, githubConfig?: GitHubConfig, debug: boolean = false) { 21 | this.debug = debug; 22 | this.agentsPath = agentsPath; 23 | 24 | // Initialize GitHub integration with default repository 25 | this.githubIntegration = new GitHubIntegration( 26 | githubConfig || { 27 | owner: 'baryonlabs', 28 | repo: 'claude-sub-agent-contents', 29 | branch: 'main', 30 | path: 'sub-agents' 31 | } 32 | ); 33 | } 34 | 35 | async loadAgents(): Promise<void> { 36 | try { 37 | // Check if the agents directory exists 38 | await fs.access(this.agentsPath); 39 | 40 | // Load English agents from /en subdirectory 41 | const enAgentsPath = path.join(this.agentsPath, 'en'); 42 | try { 43 | const enFiles = await fs.readdir(enAgentsPath); 44 | if (this.debug) { 45 | console.error(`[MCP Sub-Agents] Found ${enFiles.length} files in ${enAgentsPath}`); 46 | } 47 | 48 | for (const file of enFiles) { 49 | if (file.endsWith('.md')) { 50 | const agent = await this.loadAgent(path.join(enAgentsPath, file), 'en'); 51 | if (agent) { 52 | this.agentsCache.set(agent.name, agent); 53 | } 54 | } 55 | } 56 | } catch (e) { 57 | if (this.debug) { 58 | console.error('[MCP Sub-Agents] English agents directory not found:', enAgentsPath); 59 | } 60 | } 61 | 62 | // Load Korean agents from /ko subdirectory 63 | const koAgentsPath = path.join(this.agentsPath, 'ko'); 64 | try { 65 | const koFiles = await fs.readdir(koAgentsPath); 66 | if (this.debug) { 67 | console.error(`[MCP Sub-Agents] Found ${koFiles.length} files in ${koAgentsPath}`); 68 | } 69 | 70 | for (const file of koFiles) { 71 | if (file.endsWith('.md')) { 72 | const agent = await this.loadAgent(path.join(koAgentsPath, file), 'ko'); 73 | if (agent) { 74 | this.agentsCache.set(`${agent.name}-ko`, agent); 75 | } 76 | } 77 | } 78 | } catch (e) { 79 | if (this.debug) { 80 | console.error('[MCP Sub-Agents] Korean agents directory not found:', koAgentsPath); 81 | } 82 | } 83 | 84 | // Load Japanese agents from /ja subdirectory 85 | const jaAgentsPath = path.join(this.agentsPath, 'ja'); 86 | try { 87 | const jaFiles = await fs.readdir(jaAgentsPath); 88 | if (this.debug) { 89 | console.error(`[MCP Sub-Agents] Found ${jaFiles.length} files in ${jaAgentsPath}`); 90 | } 91 | 92 | for (const file of jaFiles) { 93 | if (file.endsWith('.md')) { 94 | const agent = await this.loadAgent(path.join(jaAgentsPath, file), 'ja'); 95 | if (agent) { 96 | this.agentsCache.set(`${agent.name}-ja`, agent); 97 | } 98 | } 99 | } 100 | } catch (e) { 101 | if (this.debug) { 102 | console.error('[MCP Sub-Agents] Japanese agents directory not found:', jaAgentsPath); 103 | } 104 | } 105 | 106 | // Load Chinese agents from /zh subdirectory 107 | const zhAgentsPath = path.join(this.agentsPath, 'zh'); 108 | try { 109 | const zhFiles = await fs.readdir(zhAgentsPath); 110 | if (this.debug) { 111 | console.error(`[MCP Sub-Agents] Found ${zhFiles.length} files in ${zhAgentsPath}`); 112 | } 113 | 114 | for (const file of zhFiles) { 115 | if (file.endsWith('.md')) { 116 | const agent = await this.loadAgent(path.join(zhAgentsPath, file), 'zh'); 117 | if (agent) { 118 | this.agentsCache.set(`${agent.name}-zh`, agent); 119 | } 120 | } 121 | } 122 | } catch (e) { 123 | if (this.debug) { 124 | console.error('[MCP Sub-Agents] Chinese agents directory not found:', zhAgentsPath); 125 | } 126 | } 127 | } catch (error) { 128 | if (this.debug) { 129 | console.error('[MCP Sub-Agents] Local agents directory not found. Agents will be fetched from GitHub as needed.'); 130 | } 131 | // Try to fetch some common agents from GitHub 132 | await this.refreshAgentsFromGitHub(); 133 | } 134 | } 135 | 136 | private async loadAgent(filePath: string, language: string = 'en'): Promise<Agent | null> { 137 | try { 138 | const content = await fs.readFile(filePath, 'utf-8'); 139 | const lines = content.split('\n'); 140 | 141 | // Find YAML frontmatter 142 | let inFrontmatter = false; 143 | let frontmatterLines: string[] = []; 144 | let contentLines: string[] = []; 145 | 146 | for (let i = 0; i < lines.length; i++) { 147 | if (lines[i] === '---') { 148 | if (!inFrontmatter) { 149 | inFrontmatter = true; 150 | } else { 151 | // End of frontmatter 152 | contentLines = lines.slice(i + 1); 153 | break; 154 | } 155 | } else if (inFrontmatter) { 156 | frontmatterLines.push(lines[i]); 157 | } 158 | } 159 | 160 | if (frontmatterLines.length === 0) { 161 | return null; 162 | } 163 | 164 | const frontmatter = yaml.load(frontmatterLines.join('\n')) as any; 165 | 166 | return { 167 | name: frontmatter.name, 168 | description: frontmatter.description, 169 | tools: frontmatter.tools.split(', '), 170 | content: contentLines.join('\n'), 171 | language 172 | }; 173 | } catch (e) { 174 | console.error(`Error loading agent from ${filePath}:`, e); 175 | return null; 176 | } 177 | } 178 | 179 | getAgent(name: string, language: string = 'en'): Agent | undefined { 180 | const key = language === 'en' ? name : `${name}-${language}`; 181 | return this.agentsCache.get(key) || this.agentsCache.get(name); 182 | } 183 | 184 | getAllAgents(language?: string): Agent[] { 185 | const agents: Agent[] = []; 186 | 187 | for (const [key, agent] of this.agentsCache.entries()) { 188 | if (!language || agent.language === language) { 189 | agents.push(agent); 190 | } 191 | } 192 | 193 | return agents; 194 | } 195 | 196 | searchAgents(query: string): Agent[] { 197 | const results: Agent[] = []; 198 | const lowerQuery = query.toLowerCase(); 199 | 200 | for (const agent of this.agentsCache.values()) { 201 | if ( 202 | agent.name.toLowerCase().includes(lowerQuery) || 203 | agent.description.toLowerCase().includes(lowerQuery) 204 | ) { 205 | results.push(agent); 206 | } 207 | } 208 | 209 | return results; 210 | } 211 | 212 | async installAgent(agent: Agent, targetPath: string): Promise<string> { 213 | const subAgentsDir = path.join(targetPath, 'claude', 'agents'); 214 | await fs.mkdir(subAgentsDir, { recursive: true }); 215 | 216 | const agentPath = path.join(subAgentsDir, `${agent.name}.md`); 217 | 218 | const content = `--- 219 | name: ${agent.name} 220 | description: ${agent.description} 221 | tools: ${agent.tools.join(', ')} 222 | --- 223 | 224 | ${agent.content}`; 225 | 226 | await fs.writeFile(agentPath, content, 'utf-8'); 227 | 228 | return agentPath; 229 | } 230 | 231 | async installMultipleAgents(agentNames: string[], targetPath: string, language: string = 'en'): Promise<string[]> { 232 | const installedPaths: string[] = []; 233 | 234 | for (const agentName of agentNames) { 235 | // First try to get from cache 236 | let agent = this.getAgent(agentName, language); 237 | 238 | // If not in cache, try to fetch from GitHub 239 | if (!agent) { 240 | if (this.debug) { 241 | console.error(`[MCP Sub-Agents] Agent ${agentName} not found locally, fetching from GitHub...`); 242 | } 243 | agent = await this.githubIntegration.fetchAgentFromGitHub(agentName, language); 244 | 245 | if (agent) { 246 | // Add to cache 247 | const key = language === 'en' ? agent.name : `${agent.name}-${language}`; 248 | this.agentsCache.set(key, agent); 249 | } 250 | } 251 | 252 | if (agent) { 253 | const path = await this.installAgent(agent, targetPath); 254 | installedPaths.push(path); 255 | } else { 256 | if (this.debug) { 257 | console.error(`[MCP Sub-Agents] Failed to find or fetch agent: ${agentName}`); 258 | } 259 | } 260 | } 261 | 262 | return installedPaths; 263 | } 264 | 265 | // Get download statistics 266 | getDownloadStats(): Map<string, number> { 267 | return this.githubIntegration.getDownloadStats(); 268 | } 269 | 270 | // Get most downloaded agents 271 | getMostDownloadedAgents(limit: number = 10): Array<{name: string, downloads: number}> { 272 | return this.githubIntegration.getMostDownloaded(limit); 273 | } 274 | 275 | // Fetch and cache agents from GitHub 276 | async refreshAgentsFromGitHub(): Promise<void> { 277 | const agents = await this.githubIntegration.fetchAllAgentsFromGitHub(); 278 | 279 | for (const agent of agents) { 280 | const key = agent.language === 'en' ? agent.name : `${agent.name}-${agent.language}`; 281 | this.agentsCache.set(key, agent); 282 | } 283 | 284 | if (this.debug) { 285 | console.error(`[MCP Sub-Agents] Refreshed ${agents.length} agents from GitHub`); 286 | } 287 | } 288 | } ``` -------------------------------------------------------------------------------- /src/agentDownloader.ts: -------------------------------------------------------------------------------- ```typescript 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | import { fileURLToPath } from 'url'; 4 | import { dirname } from 'path'; 5 | import { AIAnalysisService, AIProjectAnalysis, AIAgentRecommendation } from './aiAnalysisService.js'; 6 | 7 | const __filename = fileURLToPath(import.meta.url); 8 | const __dirname = dirname(__filename); 9 | 10 | // Using AIProjectAnalysis and AIAgentRecommendation from aiAnalysisService 11 | export type ProjectAnalysis = AIProjectAnalysis; 12 | export type AgentRecommendation = AIAgentRecommendation; 13 | 14 | export interface DownloadOptions { 15 | targetDir: string; 16 | claudeMdPath: string; 17 | format: 'md' | 'yaml' | 'json'; 18 | language: 'en' | 'ko' | 'ja' | 'zh'; 19 | limit: number; 20 | dryRun: boolean; 21 | overwrite: boolean; 22 | } 23 | 24 | /** 25 | * Agent Downloader - Analyzes projects and downloads recommended agents 26 | */ 27 | export class AgentDownloader { 28 | private agentsSourceDir: string; 29 | private aiAnalysisService: AIAnalysisService; 30 | 31 | constructor() { 32 | this.agentsSourceDir = path.join(__dirname, '../claude/agents'); 33 | this.aiAnalysisService = new AIAnalysisService(); 34 | } 35 | 36 | /** 37 | * Main entry point - analyze project and download agents using AI 38 | */ 39 | async downloadAgents(options: DownloadOptions): Promise<{ 40 | analysis: ProjectAnalysis; 41 | recommendations: AgentRecommendation[]; 42 | downloaded?: string[]; 43 | }> { 44 | // 1. Perform AI-powered project analysis 45 | const analysis = await this.aiAnalysisService.analyzeProject(options.claudeMdPath); 46 | 47 | // 2. Generate AI-powered recommendations 48 | const recommendations = await this.aiAnalysisService.generateRecommendations(analysis); 49 | 50 | // 3. Sort and limit recommendations (they're already sorted by AI) 51 | const sortedRecommendations = recommendations.slice(0, options.limit); 52 | 53 | if (options.dryRun) { 54 | return { analysis, recommendations: sortedRecommendations }; 55 | } 56 | 57 | // 4. Download agent files 58 | const downloaded = await this.downloadAgentFiles( 59 | sortedRecommendations, 60 | options, 61 | analysis 62 | ); 63 | 64 | return { analysis, recommendations: sortedRecommendations, downloaded }; 65 | } 66 | 67 | /** 68 | * Legacy wrapper - now uses AI analysis service 69 | * @deprecated Use aiAnalysisService.analyzeProject directly 70 | */ 71 | private async analyzeProject(claudeMdPath: string): Promise<ProjectAnalysis> { 72 | return await this.aiAnalysisService.analyzeProject(claudeMdPath); 73 | } 74 | 75 | /** 76 | * Legacy wrapper - now uses AI analysis service 77 | * @deprecated Parsing is now handled by AI analysis service 78 | */ 79 | private parseClaudeMd(content: string): ProjectAnalysis { 80 | // This method is now deprecated - the AI analysis service handles all parsing 81 | throw new Error('parseClaudeMd is deprecated - use AI analysis service instead'); 82 | } 83 | 84 | /** 85 | * Legacy wrapper - now uses AI analysis service 86 | * @deprecated Project structure analysis is now handled by AI analysis service 87 | */ 88 | private async analyzeProjectStructure(): Promise<ProjectAnalysis> { 89 | // This method is now deprecated - the AI analysis service handles all project structure analysis 90 | throw new Error('analyzeProjectStructure is deprecated - use AI analysis service instead'); 91 | } 92 | 93 | /** 94 | * Legacy wrapper - now uses AI analysis service 95 | * @deprecated Use aiAnalysisService.generateRecommendations directly 96 | */ 97 | private async generateRecommendations(analysis: ProjectAnalysis): Promise<AgentRecommendation[]> { 98 | return await this.aiAnalysisService.generateRecommendations(analysis); 99 | } 100 | 101 | /** 102 | * Load agent details from file 103 | */ 104 | private async loadAgentDetails(agentName: string, language: string): Promise<{ 105 | description: string; 106 | tools: string[]; 107 | } | null> { 108 | try { 109 | const agentPath = path.join(this.agentsSourceDir, language, `${agentName}.md`); 110 | 111 | if (!fs.existsSync(agentPath)) { 112 | return null; 113 | } 114 | 115 | const content = fs.readFileSync(agentPath, 'utf8'); 116 | 117 | // Parse frontmatter 118 | const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/); 119 | if (!frontmatterMatch) { 120 | return null; 121 | } 122 | 123 | const frontmatter = frontmatterMatch[1]; 124 | const descMatch = frontmatter.match(/description:\s*(.+)/); 125 | const toolsMatch = frontmatter.match(/tools:\s*(.+)/); 126 | 127 | return { 128 | description: descMatch ? descMatch[1].trim() : '', 129 | tools: toolsMatch ? toolsMatch[1].split(',').map(t => t.trim()) : ['Read', 'Write'] 130 | }; 131 | } catch (error) { 132 | console.warn(`Error loading agent details for ${agentName}: ${error}`); 133 | return null; 134 | } 135 | } 136 | 137 | /** 138 | * Download agent files to target directory 139 | */ 140 | private async downloadAgentFiles( 141 | recommendations: AgentRecommendation[], 142 | options: DownloadOptions, 143 | analysis: any 144 | ): Promise<string[]> { 145 | const downloaded: string[] = []; 146 | 147 | // Create target directory 148 | if (!fs.existsSync(options.targetDir)) { 149 | fs.mkdirSync(options.targetDir, { recursive: true }); 150 | } 151 | 152 | for (const rec of recommendations) { 153 | try { 154 | const sourcePath = path.join( 155 | this.agentsSourceDir, 156 | options.language, 157 | `${rec.name}.md` 158 | ); 159 | 160 | if (!fs.existsSync(sourcePath)) { 161 | console.warn(`Agent file not found: ${sourcePath}`); 162 | continue; 163 | } 164 | 165 | const targetPath = path.join(options.targetDir, `${rec.name}.${options.format}`); 166 | 167 | // Check if file exists and overwrite flag 168 | if (fs.existsSync(targetPath) && !options.overwrite) { 169 | console.log(`Skipping existing file: ${targetPath}`); 170 | continue; 171 | } 172 | 173 | // Copy file 174 | const content = fs.readFileSync(sourcePath, 'utf8'); 175 | 176 | if (options.format === 'md') { 177 | fs.writeFileSync(targetPath, content); 178 | } else if (options.format === 'yaml') { 179 | // Convert to YAML format (simplified) 180 | const yamlContent = this.convertToYaml(content, rec); 181 | fs.writeFileSync(targetPath, yamlContent); 182 | } else if (options.format === 'json') { 183 | // Convert to JSON format 184 | const jsonContent = this.convertToJson(content, rec); 185 | fs.writeFileSync(targetPath, jsonContent); 186 | } 187 | 188 | downloaded.push(targetPath); 189 | console.log(`✅ Downloaded: ${rec.name}.${options.format}`); 190 | 191 | } catch (error) { 192 | console.error(`Error downloading ${rec.name}: ${error}`); 193 | } 194 | } 195 | 196 | // Create README 197 | await this.createReadme(recommendations, options, analysis); 198 | 199 | return downloaded; 200 | } 201 | 202 | /** 203 | * Convert agent content to YAML format 204 | */ 205 | private convertToYaml(content: string, rec: AgentRecommendation): string { 206 | const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)/); 207 | 208 | if (!frontmatterMatch) { 209 | return content; 210 | } 211 | 212 | const frontmatter = frontmatterMatch[1]; 213 | const body = frontmatterMatch[2]; 214 | 215 | return `# Agent: ${rec.name} 216 | ${frontmatter} 217 | relevance_score: ${rec.relevanceScore} 218 | reasoning: "${rec.reasoning}" 219 | category: ${rec.category} 220 | priority: ${rec.priority} 221 | 222 | # Content 223 | content: | 224 | ${body.split('\n').map(line => ` ${line}`).join('\n')} 225 | `; 226 | } 227 | 228 | /** 229 | * Convert agent content to JSON format 230 | */ 231 | private convertToJson(content: string, rec: AgentRecommendation): string { 232 | const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)/); 233 | 234 | const agent = { 235 | name: rec.name, 236 | description: rec.description, 237 | relevanceScore: rec.relevanceScore, 238 | reasoning: rec.reasoning, 239 | category: rec.category, 240 | priority: rec.priority, 241 | tools: rec.tools, 242 | content: frontmatterMatch ? frontmatterMatch[2].trim() : content 243 | }; 244 | 245 | return JSON.stringify(agent, null, 2); 246 | } 247 | 248 | /** 249 | * Create README file with enhanced AI analysis information 250 | */ 251 | private async createReadme(recommendations: AgentRecommendation[], options: DownloadOptions, analysis: any): Promise<void> { 252 | const readmePath = path.join(options.targetDir, 'README.md'); 253 | 254 | const content = `# 🤖 AI-Recommended Agents 255 | 256 | This directory contains ${recommendations.length} agents intelligently recommended for your project using AI analysis. 257 | 258 | ## 📋 Agent Summary 259 | 260 | | Agent | Category | Priority | Relevance | Color | Description | 261 | |-------|----------|----------|-----------|-------|-------------| 262 | ${recommendations.map(rec => 263 | `| **${rec.name}** | ${rec.category} | ${rec.priority} | ${rec.relevanceScore}% | <span style="color: ${rec.color || '#6B7280'}">●</span> ${rec.color || '#6B7280'} | ${rec.description} |` 264 | ).join('\n')} 265 | 266 | ## 🎯 Usage in Claude Code 267 | 268 | Each agent can be activated by referencing their expertise: 269 | 270 | \`\`\` 271 | "${recommendations[0]?.name} 에이전트를 활용해서 [specific task]를 해줘" 272 | \`\`\` 273 | 274 | ## 📊 AI-Generated Recommendations by Priority 275 | 276 | ### ⭐ Essential (${recommendations.filter(r => r.priority === 'essential').length}) 277 | ${recommendations.filter(r => r.priority === 'essential').map(r => 278 | `- **${r.name}**: ${r.reasoning}${r.specificTasks ? '\n - Tasks: ' + r.specificTasks.join(', ') : ''}` 279 | ).join('\n')} 280 | 281 | ### 🔧 Recommended (${recommendations.filter(r => r.priority === 'recommended').length}) 282 | ${recommendations.filter(r => r.priority === 'recommended').map(r => 283 | `- **${r.name}**: ${r.reasoning}${r.specificTasks ? '\n - Tasks: ' + r.specificTasks.join(', ') : ''}` 284 | ).join('\n')} 285 | 286 | ### 💡 Optional (${recommendations.filter(r => r.priority === 'optional').length}) 287 | ${recommendations.filter(r => r.priority === 'optional').map(r => 288 | `- **${r.name}**: ${r.reasoning}${r.specificTasks ? '\n - Tasks: ' + r.specificTasks.join(', ') : ''}` 289 | ).join('\n')} 290 | 291 | ## 🎯 Recommended Agent Swarm Patterns 292 | 293 | Based on your project type (${analysis.projectType}), consider these coordination patterns: 294 | 295 | ${this.getSwarmPatternRecommendation(analysis, recommendations)} 296 | 297 | ## 🚀 Getting Started 298 | 299 | 1. **Review Agent Roles**: Read individual agent files to understand their capabilities 300 | 2. **Start with Essentials**: Begin with essential priority agents for core functionality 301 | 3. **Add Specialists**: Include recommended agents based on specific project needs 302 | 4. **Deploy as Swarm**: Use concurrent agent deployment for maximum efficiency 303 | 5. **Customize as Needed**: Modify agent instructions for your specific requirements 304 | 305 | ## 🧠 AI Analysis Features 306 | 307 | This recommendation was generated using: 308 | - **Intelligent Project Analysis**: AI-powered understanding of your project structure and requirements 309 | - **Context-Aware Recommendations**: Agent suggestions based on comprehensive project context 310 | - **Dynamic Prioritization**: Smart priority assignment based on project needs and complexity 311 | - **Task-Specific Matching**: Agents matched to specific tasks and integration points 312 | - **Swarm Pattern Recognition**: Optimal agent coordination patterns for your project 313 | 314 | Generated by claude-agents-power v${this.getVersion()} (AI-Powered) on ${new Date().toISOString()} 315 | `; 316 | 317 | fs.writeFileSync(readmePath, content); 318 | } 319 | 320 | /** 321 | * Get swarm pattern recommendation based on project analysis 322 | */ 323 | private getSwarmPatternRecommendation( 324 | analysis: any, 325 | recommendations: AIAgentRecommendation[] 326 | ): string { 327 | const agentCount = recommendations.length; 328 | const essentialCount = recommendations.filter(r => r.priority === 'essential').length; 329 | 330 | // Determine swarm size 331 | let swarmSize = 'Small'; 332 | let coordinationPattern = 'Direct'; 333 | 334 | if (agentCount > 12) { 335 | swarmSize = 'Enterprise'; 336 | coordinationPattern = 'Hierarchical'; 337 | } else if (agentCount > 8) { 338 | swarmSize = 'Large'; 339 | coordinationPattern = 'Mesh'; 340 | } else if (agentCount > 5) { 341 | swarmSize = 'Medium'; 342 | coordinationPattern = 'Adaptive'; 343 | } 344 | 345 | // Generate swarm pattern recommendation 346 | let pattern = `### 🏗️ Suggested Swarm Configuration 347 | 348 | **Swarm Size**: ${swarmSize} (${agentCount} agents) 349 | **Coordination Pattern**: ${coordinationPattern} 350 | **Essential Agents**: ${essentialCount} 351 | 352 | `; 353 | 354 | // Add specific pattern based on project type 355 | if (analysis.projectType.includes('Web') || analysis.projectType.includes('Full-Stack')) { 356 | pattern += `#### Full-Stack Development Swarm 357 | \`\`\`javascript 358 | const swarm = [ 359 | ${recommendations.slice(0, 8).map(r => ` { 360 | agent: "${r.name}", 361 | priority: "${r.priority}", 362 | color: "${r.color || '#6B7280'}", 363 | task: "${r.specificTasks?.[0] || 'General development'}" 364 | }`).join(',\n')} 365 | ]; 366 | 367 | // Deploy concurrently for maximum efficiency 368 | await deploySwarm(swarm); 369 | \`\`\``; 370 | } else if (analysis.projectType.includes('API') || analysis.projectType.includes('Backend')) { 371 | pattern += `#### Backend Service Swarm 372 | \`\`\`javascript 373 | const swarm = [ 374 | ${recommendations.slice(0, 6).map(r => ` { 375 | agent: "${r.name}", 376 | priority: "${r.priority}", 377 | color: "${r.color || '#6B7280'}", 378 | task: "${r.specificTasks?.[0] || 'Backend development'}" 379 | }`).join(',\n')} 380 | ]; 381 | 382 | // Use mesh coordination for distributed services 383 | await deploySwarm(swarm, { pattern: 'mesh' }); 384 | \`\`\``; 385 | } else if (analysis.projectType.includes('Data') || analysis.projectType.includes('ML')) { 386 | pattern += `#### Data & AI Pipeline Swarm 387 | \`\`\`javascript 388 | const swarm = [ 389 | ${recommendations.slice(0, 7).map(r => ` { agent: "${r.name}", priority: "${r.priority}", task: "${r.specificTasks?.[0] || 'Data processing'}" }`).join(',\n')} 390 | ]; 391 | 392 | // Pipeline coordination for sequential data flow 393 | await deploySwarm(swarm, { pattern: 'pipeline' }); 394 | \`\`\``; 395 | } else { 396 | pattern += `#### General Development Swarm 397 | \`\`\`javascript 398 | const swarm = [ 399 | ${recommendations.slice(0, 5).map(r => ` { agent: "${r.name}", priority: "${r.priority}", task: "${r.specificTasks?.[0] || 'Development'}" }`).join(',\n')} 400 | ]; 401 | 402 | // Adaptive coordination for flexible workflow 403 | await deploySwarm(swarm, { pattern: 'adaptive' }); 404 | \`\`\``; 405 | } 406 | 407 | pattern += ` 408 | 409 | #### Coordination Benefits 410 | - **Concurrent Execution**: Deploy all agents simultaneously for ${Math.round(agentCount * 0.7)}x faster delivery 411 | - **Cross-Agent Communication**: Agents share context and findings automatically 412 | - **Fault Tolerance**: ${coordinationPattern} pattern provides redundancy and error recovery 413 | - **Resource Optimization**: Smart load balancing across ${agentCount} agents 414 | `; 415 | 416 | return pattern; 417 | } 418 | 419 | /** 420 | * Get package version 421 | */ 422 | private getVersion(): string { 423 | try { 424 | const packageJsonPath = path.join(__dirname, '../package.json'); 425 | const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); 426 | return packageJson.version; 427 | } catch (error) { 428 | return 'unknown'; 429 | } 430 | } 431 | } ``` -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- ```html 1 | <!DOCTYPE html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8"> 5 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 | <title>Pair-Role MCP Server - Smart Role Assignment for Development Teams</title> 7 | <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet"> 8 | <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> 9 | <style> 10 | .gradient-bg { 11 | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 12 | } 13 | .role-card { 14 | transition: all 0.3s ease; 15 | } 16 | .role-card:hover { 17 | transform: translateY(-5px); 18 | box-shadow: 0 10px 30px rgba(0,0,0,0.2); 19 | } 20 | .category-badge { 21 | transition: all 0.2s ease; 22 | } 23 | .category-badge:hover { 24 | transform: scale(1.05); 25 | } 26 | .feature-icon { 27 | transition: all 0.3s ease; 28 | } 29 | .feature-icon:hover { 30 | transform: rotate(10deg) scale(1.1); 31 | } 32 | .code-block { 33 | background-color: #1e1e1e; 34 | color: #d4d4d4; 35 | border-radius: 8px; 36 | padding: 16px; 37 | font-family: 'Consolas', 'Monaco', monospace; 38 | overflow-x: auto; 39 | } 40 | .tab-content { 41 | display: none; 42 | } 43 | .tab-content.active { 44 | display: block; 45 | } 46 | .hero-animation { 47 | animation: float 6s ease-in-out infinite; 48 | } 49 | @keyframes float { 50 | 0% { transform: translatey(0px); } 51 | 50% { transform: translatey(-20px); } 52 | 100% { transform: translatey(0px); } 53 | } 54 | </style> 55 | </head> 56 | <body class="bg-gray-50"> 57 | <!-- Navigation --> 58 | <nav class="bg-white shadow-lg sticky top-0 z-50"> 59 | <div class="container mx-auto px-6 py-4"> 60 | <div class="flex items-center justify-between"> 61 | <div class="flex items-center"> 62 | <i class="fas fa-users-cog text-3xl text-purple-600 mr-3"></i> 63 | <h1 class="text-2xl font-bold text-gray-800">Pair-Role MCP Server</h1> 64 | </div> 65 | <div class="flex space-x-6"> 66 | <a href="#features" class="text-gray-700 hover:text-purple-600 transition">Features</a> 67 | <a href="#roles" class="text-gray-700 hover:text-purple-600 transition">Roles</a> 68 | <a href="#usage" class="text-gray-700 hover:text-purple-600 transition">Usage</a> 69 | <a href="#installation" class="text-gray-700 hover:text-purple-600 transition">Installation</a> 70 | <a href="https://github.com/hongsw/claude-agents-power-mcp-server" class="text-gray-700 hover:text-purple-600 transition"> 71 | <i class="fab fa-github text-2xl"></i> 72 | </a> 73 | </div> 74 | </div> 75 | </div> 76 | </nav> 77 | 78 | <!-- Hero Section --> 79 | <section class="gradient-bg text-white py-20"> 80 | <div class="container mx-auto px-6"> 81 | <div class="flex flex-col md:flex-row items-center"> 82 | <div class="md:w-1/2 mb-10 md:mb-0"> 83 | <h2 class="text-4xl md:text-5xl font-bold mb-6"> 84 | 🎯 Smart Role Assignment for Development Teams 85 | </h2> 86 | <p class="text-xl mb-8 text-purple-100"> 87 | An intelligent MCP server that analyzes your project and recommends the perfect team composition from 100+ professional roles across all company departments. 88 | </p> 89 | <div class="flex space-x-4"> 90 | <a href="#installation" class="bg-white text-purple-700 px-8 py-3 rounded-lg font-bold hover:bg-purple-100 transition"> 91 | Get Started 92 | </a> 93 | <a href="https://github.com/hongsw/claude-agents-power-mcp-server" class="border-2 border-white text-white px-8 py-3 rounded-lg font-bold hover:bg-white hover:text-purple-700 transition"> 94 | View on GitHub 95 | </a> 96 | </div> 97 | </div> 98 | <div class="md:w-1/2 flex justify-center"> 99 | <div class="hero-animation"> 100 | <div class="bg-white bg-opacity-20 backdrop-blur-lg rounded-lg p-8 shadow-2xl"> 101 | <div class="text-center mb-4"> 102 | <i class="fas fa-project-diagram text-6xl mb-4"></i> 103 | <h3 class="text-2xl font-bold">AI-Powered Team Builder</h3> 104 | </div> 105 | <div class="space-y-2"> 106 | <div class="bg-white bg-opacity-20 rounded px-4 py-2"> 107 | <i class="fas fa-check-circle mr-2"></i> Analyze Project 108 | </div> 109 | <div class="bg-white bg-opacity-20 rounded px-4 py-2"> 110 | <i class="fas fa-users mr-2"></i> Recommend Roles 111 | </div> 112 | <div class="bg-white bg-opacity-20 rounded px-4 py-2"> 113 | <i class="fas fa-download mr-2"></i> Install Agents 114 | </div> 115 | </div> 116 | </div> 117 | </div> 118 | </div> 119 | </div> 120 | </div> 121 | </section> 122 | 123 | <!-- Stats Section --> 124 | <section class="py-12 bg-white"> 125 | <div class="container mx-auto px-6"> 126 | <div class="grid grid-cols-2 md:grid-cols-4 gap-6 text-center"> 127 | <div class="p-6"> 128 | <div class="text-4xl font-bold text-purple-600">100+</div> 129 | <div class="text-gray-600 mt-2">Professional Roles</div> 130 | </div> 131 | <div class="p-6"> 132 | <div class="text-4xl font-bold text-purple-600">8</div> 133 | <div class="text-gray-600 mt-2">Departments</div> 134 | </div> 135 | <div class="p-6"> 136 | <div class="text-4xl font-bold text-purple-600">2</div> 137 | <div class="text-gray-600 mt-2">Languages</div> 138 | </div> 139 | <div class="p-6"> 140 | <div class="text-4xl font-bold text-purple-600">∞</div> 141 | <div class="text-gray-600 mt-2">Team Combinations</div> 142 | </div> 143 | </div> 144 | </div> 145 | </section> 146 | 147 | <!-- Features Section --> 148 | <section id="features" class="py-20 bg-gray-50"> 149 | <div class="container mx-auto px-6"> 150 | <h2 class="text-3xl font-bold text-center text-gray-800 mb-16"> 151 | 🌟 Key Features 152 | </h2> 153 | <div class="grid md:grid-cols-3 gap-8"> 154 | <div class="bg-white rounded-lg shadow-lg p-8 text-center role-card"> 155 | <div class="feature-icon inline-block mb-4"> 156 | <i class="fas fa-search text-5xl text-purple-600"></i> 157 | </div> 158 | <h3 class="text-xl font-bold mb-4">Intelligent Project Analysis</h3> 159 | <p class="text-gray-600"> 160 | Automatically detects project type, frameworks, and complexity to provide smart role recommendations based on your tech stack. 161 | </p> 162 | </div> 163 | <div class="bg-white rounded-lg shadow-lg p-8 text-center role-card"> 164 | <div class="feature-icon inline-block mb-4"> 165 | <i class="fas fa-users text-5xl text-purple-600"></i> 166 | </div> 167 | <h3 class="text-xl font-bold mb-4">100+ Professional Roles</h3> 168 | <p class="text-gray-600"> 169 | Comprehensive coverage across Technology, Data, Product, Marketing, Operations, Finance, HR, and Executive roles. 170 | </p> 171 | </div> 172 | <div class="bg-white rounded-lg shadow-lg p-8 text-center role-card"> 173 | <div class="feature-icon inline-block mb-4"> 174 | <i class="fas fa-globe text-5xl text-purple-600"></i> 175 | </div> 176 | <h3 class="text-xl font-bold mb-4">Multi-Language Support</h3> 177 | <p class="text-gray-600"> 178 | Available in English and Korean, supporting global standards and local business contexts. 179 | </p> 180 | </div> 181 | </div> 182 | </div> 183 | </section> 184 | 185 | <!-- Roles Section --> 186 | <section id="roles" class="py-20 bg-white"> 187 | <div class="container mx-auto px-6"> 188 | <h2 class="text-3xl font-bold text-center text-gray-800 mb-16"> 189 | 📋 Available Roles by Department 190 | </h2> 191 | 192 | <!-- Department Tabs --> 193 | <div class="flex flex-wrap justify-center mb-8 gap-2"> 194 | <button onclick="showDepartment('tech')" class="category-badge bg-purple-600 text-white px-4 py-2 rounded-full text-sm font-semibold"> 195 | 🔧 Technology (20) 196 | </button> 197 | <button onclick="showDepartment('data')" class="category-badge bg-blue-600 text-white px-4 py-2 rounded-full text-sm font-semibold"> 198 | 📊 Data & Analytics (15) 199 | </button> 200 | <button onclick="showDepartment('product')" class="category-badge bg-pink-600 text-white px-4 py-2 rounded-full text-sm font-semibold"> 201 | 🎨 Product & Design (10) 202 | </button> 203 | <button onclick="showDepartment('marketing')" class="category-badge bg-green-600 text-white px-4 py-2 rounded-full text-sm font-semibold"> 204 | 📈 Marketing & Sales (10) 205 | </button> 206 | <button onclick="showDepartment('operations')" class="category-badge bg-yellow-600 text-white px-4 py-2 rounded-full text-sm font-semibold"> 207 | ⚙️ Operations (15) 208 | </button> 209 | <button onclick="showDepartment('finance')" class="category-badge bg-red-600 text-white px-4 py-2 rounded-full text-sm font-semibold"> 210 | 💰 Finance (10) 211 | </button> 212 | <button onclick="showDepartment('hr')" class="category-badge bg-indigo-600 text-white px-4 py-2 rounded-full text-sm font-semibold"> 213 | 👥 HR (10) 214 | </button> 215 | <button onclick="showDepartment('executive')" class="category-badge bg-gray-800 text-white px-4 py-2 rounded-full text-sm font-semibold"> 216 | 🏢 Executive (10) 217 | </button> 218 | </div> 219 | 220 | <!-- Department Content --> 221 | <div id="tech" class="tab-content active"> 222 | <div class="grid md:grid-cols-3 gap-6"> 223 | <div class="role-card bg-gray-50 p-6 rounded-lg"> 224 | <h4 class="font-bold text-lg mb-2">Software Engineer</h4> 225 | <p class="text-gray-600 text-sm mb-3">Full-stack development, system design</p> 226 | <div class="flex flex-wrap gap-2"> 227 | <span class="bg-purple-100 text-purple-800 px-2 py-1 rounded text-xs">Bash</span> 228 | <span class="bg-purple-100 text-purple-800 px-2 py-1 rounded text-xs">Read</span> 229 | <span class="bg-purple-100 text-purple-800 px-2 py-1 rounded text-xs">Write</span> 230 | <span class="bg-purple-100 text-purple-800 px-2 py-1 rounded text-xs">Edit</span> 231 | </div> 232 | </div> 233 | <div class="role-card bg-gray-50 p-6 rounded-lg"> 234 | <h4 class="font-bold text-lg mb-2">Frontend Developer</h4> 235 | <p class="text-gray-600 text-sm mb-3">React, Vue, Angular, UI/UX</p> 236 | <div class="flex flex-wrap gap-2"> 237 | <span class="bg-purple-100 text-purple-800 px-2 py-1 rounded text-xs">Read</span> 238 | <span class="bg-purple-100 text-purple-800 px-2 py-1 rounded text-xs">Write</span> 239 | <span class="bg-purple-100 text-purple-800 px-2 py-1 rounded text-xs">Edit</span> 240 | <span class="bg-purple-100 text-purple-800 px-2 py-1 rounded text-xs">Bash</span> 241 | </div> 242 | </div> 243 | <div class="role-card bg-gray-50 p-6 rounded-lg"> 244 | <h4 class="font-bold text-lg mb-2">Backend Developer</h4> 245 | <p class="text-gray-600 text-sm mb-3">APIs, databases, server architecture</p> 246 | <div class="flex flex-wrap gap-2"> 247 | <span class="bg-purple-100 text-purple-800 px-2 py-1 rounded text-xs">Bash</span> 248 | <span class="bg-purple-100 text-purple-800 px-2 py-1 rounded text-xs">Read</span> 249 | <span class="bg-purple-100 text-purple-800 px-2 py-1 rounded text-xs">Write</span> 250 | <span class="bg-purple-100 text-purple-800 px-2 py-1 rounded text-xs">Edit</span> 251 | </div> 252 | </div> 253 | <!-- More roles... --> 254 | </div> 255 | <p class="text-center mt-6 text-gray-600"> 256 | + 17 more technology roles including DevOps, Security, Cloud, Mobile, QA, and more! 257 | </p> 258 | </div> 259 | 260 | <div id="data" class="tab-content"> 261 | <div class="grid md:grid-cols-3 gap-6"> 262 | <div class="role-card bg-gray-50 p-6 rounded-lg"> 263 | <h4 class="font-bold text-lg mb-2">Data Scientist</h4> 264 | <p class="text-gray-600 text-sm mb-3">ML modeling, statistical analysis</p> 265 | <div class="flex flex-wrap gap-2"> 266 | <span class="bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs">Bash</span> 267 | <span class="bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs">Read</span> 268 | <span class="bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs">Write</span> 269 | </div> 270 | </div> 271 | <div class="role-card bg-gray-50 p-6 rounded-lg"> 272 | <h4 class="font-bold text-lg mb-2">Data Analyst</h4> 273 | <p class="text-gray-600 text-sm mb-3">Business insights, reporting</p> 274 | <div class="flex flex-wrap gap-2"> 275 | <span class="bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs">Read</span> 276 | <span class="bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs">Write</span> 277 | <span class="bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs">Bash</span> 278 | </div> 279 | </div> 280 | <div class="role-card bg-gray-50 p-6 rounded-lg"> 281 | <h4 class="font-bold text-lg mb-2">Business Intelligence Analyst</h4> 282 | <p class="text-gray-600 text-sm mb-3">Dashboards, BI tools</p> 283 | <div class="flex flex-wrap gap-2"> 284 | <span class="bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs">Read</span> 285 | <span class="bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs">Write</span> 286 | <span class="bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs">Bash</span> 287 | </div> 288 | </div> 289 | </div> 290 | <p class="text-center mt-6 text-gray-600"> 291 | + 12 more data & analytics roles including Analytics Engineer, Marketing Analyst, and more! 292 | </p> 293 | </div> 294 | 295 | <div id="product" class="tab-content"> 296 | <div class="grid md:grid-cols-3 gap-6"> 297 | <div class="role-card bg-gray-50 p-6 rounded-lg"> 298 | <h4 class="font-bold text-lg mb-2">Product Manager</h4> 299 | <p class="text-gray-600 text-sm mb-3">Product strategy, roadmap</p> 300 | <div class="flex flex-wrap gap-2"> 301 | <span class="bg-pink-100 text-pink-800 px-2 py-1 rounded text-xs">Read</span> 302 | <span class="bg-pink-100 text-pink-800 px-2 py-1 rounded text-xs">Write</span> 303 | </div> 304 | </div> 305 | <div class="role-card bg-gray-50 p-6 rounded-lg"> 306 | <h4 class="font-bold text-lg mb-2">UX Designer</h4> 307 | <p class="text-gray-600 text-sm mb-3">User research, wireframes</p> 308 | <div class="flex flex-wrap gap-2"> 309 | <span class="bg-pink-100 text-pink-800 px-2 py-1 rounded text-xs">Read</span> 310 | <span class="bg-pink-100 text-pink-800 px-2 py-1 rounded text-xs">Write</span> 311 | </div> 312 | </div> 313 | <div class="role-card bg-gray-50 p-6 rounded-lg"> 314 | <h4 class="font-bold text-lg mb-2">UI Designer</h4> 315 | <p class="text-gray-600 text-sm mb-3">Visual design, prototypes</p> 316 | <div class="flex flex-wrap gap-2"> 317 | <span class="bg-pink-100 text-pink-800 px-2 py-1 rounded text-xs">Read</span> 318 | <span class="bg-pink-100 text-pink-800 px-2 py-1 rounded text-xs">Write</span> 319 | </div> 320 | </div> 321 | </div> 322 | <p class="text-center mt-6 text-gray-600"> 323 | + 7 more product & design roles including Product Designer, UX Researcher, and more! 324 | </p> 325 | </div> 326 | 327 | <!-- Other department tabs... --> 328 | </div> 329 | </section> 330 | 331 | <!-- Usage Examples Section --> 332 | <section id="usage" class="py-20 bg-gray-50"> 333 | <div class="container mx-auto px-6"> 334 | <h2 class="text-3xl font-bold text-center text-gray-800 mb-16"> 335 | 🎯 Usage Examples 336 | </h2> 337 | 338 | <div class="grid md:grid-cols-3 gap-8"> 339 | <!-- Startup Example --> 340 | <div class="bg-white rounded-lg shadow-lg p-8"> 341 | <div class="text-2xl mb-4">🚀</div> 342 | <h3 class="text-xl font-bold mb-4">Startup MVP Development</h3> 343 | <div class="code-block mb-4"> 344 | <pre><code># Analyze project 345 | mcp__pair-role__analyze-project 346 | 347 | # Install startup team 348 | mcp__pair-role__install-agents [ 349 | "product-manager", 350 | "frontend-developer", 351 | "backend-developer", 352 | "growth-marketing-manager" 353 | ]</code></pre> 354 | </div> 355 | <p class="text-gray-600">Perfect for building your minimum viable product with a lean team.</p> 356 | </div> 357 | 358 | <!-- Enterprise Example --> 359 | <div class="bg-white rounded-lg shadow-lg p-8"> 360 | <div class="text-2xl mb-4">🏢</div> 361 | <h3 class="text-xl font-bold mb-4">Enterprise Application</h3> 362 | <div class="code-block mb-4"> 363 | <pre><code># Get enterprise recommendations 364 | mcp__pair-role__recommend-by-keywords [ 365 | "enterprise", "security", 366 | "scalability", "compliance" 367 | ] 368 | 369 | # Install enterprise team 370 | mcp__pair-role__install-agents [ 371 | "solution-architect", 372 | "security-engineer", 373 | "devops-engineer", 374 | "compliance-manager" 375 | ]</code></pre> 376 | </div> 377 | <p class="text-gray-600">Build secure, scalable enterprise solutions with the right expertise.</p> 378 | </div> 379 | 380 | <!-- Data Platform Example --> 381 | <div class="bg-white rounded-lg shadow-lg p-8"> 382 | <div class="text-2xl mb-4">📊</div> 383 | <h3 class="text-xl font-bold mb-4">Data Platform</h3> 384 | <div class="code-block mb-4"> 385 | <pre><code># Search data roles 386 | mcp__pair-role__search-agents \ 387 | "data analytics machine learning" 388 | 389 | # Install data team 390 | mcp__pair-role__install-agents [ 391 | "data-scientist", 392 | "data-engineer", 393 | "machine-learning-engineer", 394 | "analytics-engineer" 395 | ]</code></pre> 396 | </div> 397 | <p class="text-gray-600">Create powerful data platforms with specialized data professionals.</p> 398 | </div> 399 | </div> 400 | </div> 401 | </section> 402 | 403 | <!-- Installation Section --> 404 | <section id="installation" class="py-20 bg-white"> 405 | <div class="container mx-auto px-6"> 406 | <h2 class="text-3xl font-bold text-center text-gray-800 mb-16"> 407 | ⚡ Quick Installation 408 | </h2> 409 | 410 | <div class="max-w-3xl mx-auto"> 411 | <div class="mb-8"> 412 | <h3 class="text-xl font-bold mb-4">1. Clone and Build</h3> 413 | <div class="code-block"> 414 | <pre><code>git clone https://github.com/hongsw/claude-agents-power-mcp-server.git 415 | cd claude-agents-power-mcp-server 416 | npm install 417 | npm run build</code></pre> 418 | </div> 419 | </div> 420 | 421 | <div class="mb-8"> 422 | <h3 class="text-xl font-bold mb-4">2. Configure MCP</h3> 423 | <p class="text-gray-600 mb-4">Add to your <code class="bg-gray-200 px-2 py-1 rounded">~/.config/claude/mcp_servers.json</code>:</p> 424 | <div class="code-block"> 425 | <pre><code>{ 426 | "mcpServers": { 427 | "pair-role": { 428 | "command": "node", 429 | "args": ["/path/to/claude-agents-power-mcp-server/dist/index.js"], 430 | "cwd": "/path/to/your/project", 431 | "env": {} 432 | } 433 | } 434 | }</code></pre> 435 | </div> 436 | </div> 437 | 438 | <div> 439 | <h3 class="text-xl font-bold mb-4">3. Start Using</h3> 440 | <p class="text-gray-600 mb-4">Restart Claude Code and start building your perfect team!</p> 441 | <div class="code-block"> 442 | <pre><code># Analyze your project 443 | mcp__pair-role__analyze-project 444 | 445 | # Get recommendations 446 | mcp__pair-role__recommend-by-keywords ["your", "tech", "stack"] 447 | 448 | # Install agents 449 | mcp__pair-role__install-agents ["selected", "roles"]</code></pre> 450 | </div> 451 | </div> 452 | </div> 453 | </div> 454 | </section> 455 | 456 | <!-- CTA Section --> 457 | <section class="gradient-bg text-white py-20"> 458 | <div class="container mx-auto px-6 text-center"> 459 | <h2 class="text-3xl font-bold mb-6"> 460 | Ready to Build Your Perfect Team? 461 | </h2> 462 | <p class="text-xl mb-8 text-purple-100"> 463 | Start using Pair-Role MCP Server today and revolutionize how you build development teams. 464 | </p> 465 | <div class="flex justify-center space-x-4"> 466 | <a href="https://github.com/hongsw/claude-agents-power-mcp-server" class="bg-white text-purple-700 px-8 py-3 rounded-lg font-bold hover:bg-purple-100 transition"> 467 | <i class="fab fa-github mr-2"></i> View on GitHub 468 | </a> 469 | <a href="https://github.com/hongsw/claude-agents-power-mcp-server/issues" class="border-2 border-white text-white px-8 py-3 rounded-lg font-bold hover:bg-white hover:text-purple-700 transition"> 470 | <i class="fas fa-comment mr-2"></i> Get Support 471 | </a> 472 | </div> 473 | </div> 474 | </section> 475 | 476 | <!-- Footer --> 477 | <footer class="bg-gray-800 text-white py-8"> 478 | <div class="container mx-auto px-6 text-center"> 479 | <p class="mb-4"> 480 | Made with ❤️ for the Claude Code community 481 | </p> 482 | <div class="flex justify-center space-x-6"> 483 | <a href="https://github.com/hongsw/claude-agents-power-mcp-server" class="hover:text-purple-400 transition"> 484 | <i class="fab fa-github text-2xl"></i> 485 | </a> 486 | <a href="https://miri.dev" class="hover:text-purple-400 transition"> 487 | <i class="fas fa-globe text-2xl"></i> 488 | </a> 489 | <a href="https://discord.gg/claudecode" class="hover:text-purple-400 transition"> 490 | <i class="fab fa-discord text-2xl"></i> 491 | </a> 492 | </div> 493 | <p class="mt-4 text-gray-400"> 494 | © 2024 Pair-Role MCP Server. MIT License. 495 | </p> 496 | </div> 497 | </footer> 498 | 499 | <script> 500 | function showDepartment(dept) { 501 | // Hide all tabs 502 | const tabs = document.querySelectorAll('.tab-content'); 503 | tabs.forEach(tab => tab.classList.remove('active')); 504 | 505 | // Show selected tab 506 | document.getElementById(dept).classList.add('active'); 507 | 508 | // Update button styles 509 | const buttons = document.querySelectorAll('.category-badge'); 510 | buttons.forEach(button => { 511 | button.style.opacity = '0.7'; 512 | }); 513 | event.target.style.opacity = '1'; 514 | } 515 | 516 | // Smooth scrolling for navigation links 517 | document.querySelectorAll('a[href^="#"]').forEach(anchor => { 518 | anchor.addEventListener('click', function (e) { 519 | e.preventDefault(); 520 | document.querySelector(this.getAttribute('href')).scrollIntoView({ 521 | behavior: 'smooth' 522 | }); 523 | }); 524 | }); 525 | </script> 526 | </body> 527 | </html> ```