octocode-cli 1.2.6 → 1.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -63
- package/README.md +85 -142
- package/out/octocode-cli.js +7063 -6934
- package/package.json +8 -6
- package/skills/README.md +97 -120
- package/skills/octocode-code-engineer/.claude/settings.local.json +18 -0
- package/skills/octocode-code-engineer/.octocode/rfc/RFC-code-engineer-weakness-fixes.md +255 -0
- package/skills/octocode-code-engineer/.plan/VALIDATED_PLAN.md +223 -0
- package/skills/octocode-code-engineer/README.md +178 -0
- package/skills/octocode-code-engineer/SKILL.md +418 -0
- package/skills/octocode-code-engineer/coverage/architecture.ts.html +7828 -0
- package/skills/octocode-code-engineer/coverage/ast-helpers.ts.html +211 -0
- package/skills/octocode-code-engineer/coverage/ast-search.ts.html +1795 -0
- package/skills/octocode-code-engineer/coverage/base.css +224 -0
- package/skills/octocode-code-engineer/coverage/block-navigation.js +87 -0
- package/skills/octocode-code-engineer/coverage/cache.ts.html +376 -0
- package/skills/octocode-code-engineer/coverage/cli.ts.html +982 -0
- package/skills/octocode-code-engineer/coverage/clover.xml +3217 -0
- package/skills/octocode-code-engineer/coverage/collect-effects.ts.html +664 -0
- package/skills/octocode-code-engineer/coverage/collect-input-sources.ts.html +577 -0
- package/skills/octocode-code-engineer/coverage/collect-performance.ts.html +331 -0
- package/skills/octocode-code-engineer/coverage/collect-prototype-pollution.ts.html +421 -0
- package/skills/octocode-code-engineer/coverage/collect-security.ts.html +604 -0
- package/skills/octocode-code-engineer/coverage/collect-test-profile.ts.html +589 -0
- package/skills/octocode-code-engineer/coverage/coverage-final.json +30 -0
- package/skills/octocode-code-engineer/coverage/dependencies.ts.html +997 -0
- package/skills/octocode-code-engineer/coverage/dependency-summary.ts.html +688 -0
- package/skills/octocode-code-engineer/coverage/discovery.ts.html +322 -0
- package/skills/octocode-code-engineer/coverage/favicon.png +0 -0
- package/skills/octocode-code-engineer/coverage/graph-analytics.ts.html +1510 -0
- package/skills/octocode-code-engineer/coverage/index.html +536 -0
- package/skills/octocode-code-engineer/coverage/index.ts.html +826 -0
- package/skills/octocode-code-engineer/coverage/metrics.ts.html +553 -0
- package/skills/octocode-code-engineer/coverage/pipeline.ts.html +2044 -0
- package/skills/octocode-code-engineer/coverage/prettify.css +1 -0
- package/skills/octocode-code-engineer/coverage/prettify.js +2 -0
- package/skills/octocode-code-engineer/coverage/report-analysis.ts.html +1570 -0
- package/skills/octocode-code-engineer/coverage/report-writer.ts.html +1102 -0
- package/skills/octocode-code-engineer/coverage/security-detectors.ts.html +1747 -0
- package/skills/octocode-code-engineer/coverage/semantic-detectors.ts.html +2152 -0
- package/skills/octocode-code-engineer/coverage/semantic.ts.html +1897 -0
- package/skills/octocode-code-engineer/coverage/sort-arrow-sprite.png +0 -0
- package/skills/octocode-code-engineer/coverage/sorter.js +210 -0
- package/skills/octocode-code-engineer/coverage/summary-md.ts.html +1222 -0
- package/skills/octocode-code-engineer/coverage/test-quality-detectors.ts.html +1039 -0
- package/skills/octocode-code-engineer/coverage/tree-sitter-analyzer.ts.html +955 -0
- package/skills/octocode-code-engineer/coverage/ts-analyzer.ts.html +1213 -0
- package/skills/octocode-code-engineer/coverage/types.ts.html +2473 -0
- package/skills/octocode-code-engineer/coverage/utils.ts.html +820 -0
- package/skills/octocode-code-engineer/eslint.config.mjs +54 -0
- package/skills/octocode-code-engineer/minify-scripts.mjs +32 -0
- package/skills/octocode-code-engineer/package.json +54 -0
- package/skills/octocode-code-engineer/references/agent-ast-reading-rfc.md +95 -0
- package/skills/octocode-code-engineer/references/architecture-techniques.md +121 -0
- package/skills/octocode-code-engineer/references/ast-search.md +210 -0
- package/skills/octocode-code-engineer/references/ast-tree-search.md +151 -0
- package/skills/octocode-code-engineer/references/cli-reference.md +167 -0
- package/skills/octocode-code-engineer/references/concepts.md +107 -0
- package/skills/octocode-code-engineer/references/finding-categories.md +128 -0
- package/skills/octocode-code-engineer/references/improvement-roadmap.md +304 -0
- package/skills/octocode-code-engineer/references/output-files.md +144 -0
- package/skills/octocode-code-engineer/references/playbooks.md +204 -0
- package/skills/octocode-code-engineer/references/present-results.md +136 -0
- package/skills/octocode-code-engineer/references/tool-workflows.md +566 -0
- package/skills/octocode-code-engineer/references/validate-investigate.md +225 -0
- package/skills/octocode-code-engineer/scripts/analysis/dependencies.js +1 -0
- package/skills/octocode-code-engineer/scripts/analysis/dependency-summary.js +1 -0
- package/skills/octocode-code-engineer/scripts/analysis/discovery.js +1 -0
- package/skills/octocode-code-engineer/scripts/analysis/graph-analytics.js +1 -0
- package/skills/octocode-code-engineer/scripts/analysis/semantic.js +1 -0
- package/skills/octocode-code-engineer/scripts/ast/helpers.js +1 -0
- package/skills/octocode-code-engineer/scripts/ast/metrics.js +1 -0
- package/skills/octocode-code-engineer/scripts/ast/search.js +2 -0
- package/skills/octocode-code-engineer/scripts/ast/tree-search.js +2 -0
- package/skills/octocode-code-engineer/scripts/ast/tree-sitter.js +1 -0
- package/skills/octocode-code-engineer/scripts/ast/ts-analyzer.js +1 -0
- package/skills/octocode-code-engineer/scripts/collectors/chains.js +1 -0
- package/skills/octocode-code-engineer/scripts/collectors/effects.js +1 -0
- package/skills/octocode-code-engineer/scripts/collectors/input-sources.js +1 -0
- package/skills/octocode-code-engineer/scripts/collectors/performance.js +1 -0
- package/skills/octocode-code-engineer/scripts/collectors/prototype-pollution.js +1 -0
- package/skills/octocode-code-engineer/scripts/collectors/security.js +1 -0
- package/skills/octocode-code-engineer/scripts/collectors/test-profile.js +1 -0
- package/skills/octocode-code-engineer/scripts/common/is-direct-run.js +1 -0
- package/skills/octocode-code-engineer/scripts/common/utils.js +1 -0
- package/skills/octocode-code-engineer/scripts/detectors/code-quality.js +1 -0
- package/skills/octocode-code-engineer/scripts/detectors/cohesion.js +1 -0
- package/skills/octocode-code-engineer/scripts/detectors/coupling.js +1 -0
- package/skills/octocode-code-engineer/scripts/detectors/cycle.js +1 -0
- package/skills/octocode-code-engineer/scripts/detectors/dead-code.js +1 -0
- package/skills/octocode-code-engineer/scripts/detectors/import-style.js +1 -0
- package/skills/octocode-code-engineer/scripts/detectors/index.js +1 -0
- package/skills/octocode-code-engineer/scripts/detectors/security.js +1 -0
- package/skills/octocode-code-engineer/scripts/detectors/semantic.js +1 -0
- package/skills/octocode-code-engineer/scripts/detectors/shared.js +1 -0
- package/skills/octocode-code-engineer/scripts/detectors/test-quality.js +1 -0
- package/skills/octocode-code-engineer/scripts/index.js +1 -0
- package/skills/octocode-code-engineer/scripts/pipeline/cache.js +1 -0
- package/skills/octocode-code-engineer/scripts/pipeline/cli.js +1 -0
- package/skills/octocode-code-engineer/scripts/pipeline/main.js +2 -0
- package/skills/octocode-code-engineer/scripts/reporting/analysis.js +1 -0
- package/skills/octocode-code-engineer/scripts/reporting/summary-md.js +1 -0
- package/skills/octocode-code-engineer/scripts/reporting/writer.js +1 -0
- package/skills/octocode-code-engineer/scripts/types/constants.js +1 -0
- package/skills/octocode-code-engineer/scripts/types/index.js +1 -0
- package/skills/octocode-code-engineer/scripts/types/interfaces.js +1 -0
- package/skills/octocode-code-engineer/src/analysis/dependencies.test.ts +545 -0
- package/skills/octocode-code-engineer/src/analysis/dependencies.ts +406 -0
- package/skills/octocode-code-engineer/src/analysis/dependency-summary.test.ts +566 -0
- package/skills/octocode-code-engineer/src/analysis/dependency-summary.ts +257 -0
- package/skills/octocode-code-engineer/src/analysis/discovery.test.ts +420 -0
- package/skills/octocode-code-engineer/src/analysis/discovery.ts +87 -0
- package/skills/octocode-code-engineer/src/analysis/graph-analytics.test.ts +449 -0
- package/skills/octocode-code-engineer/src/analysis/graph-analytics.ts +534 -0
- package/skills/octocode-code-engineer/src/analysis/semantic.test.ts +1533 -0
- package/skills/octocode-code-engineer/src/analysis/semantic.ts +830 -0
- package/skills/octocode-code-engineer/src/ast/helpers.test.ts +185 -0
- package/skills/octocode-code-engineer/src/ast/helpers.ts +62 -0
- package/skills/octocode-code-engineer/src/ast/metrics.test.ts +304 -0
- package/skills/octocode-code-engineer/src/ast/metrics.ts +204 -0
- package/skills/octocode-code-engineer/src/ast/search.test.ts +647 -0
- package/skills/octocode-code-engineer/src/ast/search.ts +648 -0
- package/skills/octocode-code-engineer/src/ast/tree-search.test.ts +199 -0
- package/skills/octocode-code-engineer/src/ast/tree-search.ts +392 -0
- package/skills/octocode-code-engineer/src/ast/tree-sitter.test.ts +407 -0
- package/skills/octocode-code-engineer/src/ast/tree-sitter.ts +402 -0
- package/skills/octocode-code-engineer/src/ast/ts-analyzer.test.ts +1864 -0
- package/skills/octocode-code-engineer/src/ast/ts-analyzer.ts +509 -0
- package/skills/octocode-code-engineer/src/collectors/chains.ts +74 -0
- package/skills/octocode-code-engineer/src/collectors/effects.test.ts +490 -0
- package/skills/octocode-code-engineer/src/collectors/effects.ts +332 -0
- package/skills/octocode-code-engineer/src/collectors/input-sources.test.ts +144 -0
- package/skills/octocode-code-engineer/src/collectors/input-sources.ts +196 -0
- package/skills/octocode-code-engineer/src/collectors/performance.test.ts +82 -0
- package/skills/octocode-code-engineer/src/collectors/performance.ts +141 -0
- package/skills/octocode-code-engineer/src/collectors/prototype-pollution.test.ts +55 -0
- package/skills/octocode-code-engineer/src/collectors/prototype-pollution.ts +162 -0
- package/skills/octocode-code-engineer/src/collectors/security.test.ts +124 -0
- package/skills/octocode-code-engineer/src/collectors/security.ts +309 -0
- package/skills/octocode-code-engineer/src/collectors/test-profile.test.ts +97 -0
- package/skills/octocode-code-engineer/src/collectors/test-profile.ts +269 -0
- package/skills/octocode-code-engineer/src/common/is-direct-run.test.ts +32 -0
- package/skills/octocode-code-engineer/src/common/is-direct-run.ts +13 -0
- package/skills/octocode-code-engineer/src/common/utils.test.ts +463 -0
- package/skills/octocode-code-engineer/src/common/utils.ts +304 -0
- package/skills/octocode-code-engineer/src/detectors/code-quality.ts +966 -0
- package/skills/octocode-code-engineer/src/detectors/cohesion.ts +539 -0
- package/skills/octocode-code-engineer/src/detectors/coupling.ts +323 -0
- package/skills/octocode-code-engineer/src/detectors/cycle.ts +349 -0
- package/skills/octocode-code-engineer/src/detectors/dead-code.ts +320 -0
- package/skills/octocode-code-engineer/src/detectors/import-style.ts +376 -0
- package/skills/octocode-code-engineer/src/detectors/index.test.ts +3061 -0
- package/skills/octocode-code-engineer/src/detectors/index.ts +88 -0
- package/skills/octocode-code-engineer/src/detectors/security.test.ts +882 -0
- package/skills/octocode-code-engineer/src/detectors/security.ts +821 -0
- package/skills/octocode-code-engineer/src/detectors/semantic.ts +758 -0
- package/skills/octocode-code-engineer/src/detectors/shared.ts +49 -0
- package/skills/octocode-code-engineer/src/detectors/test-quality.test.ts +388 -0
- package/skills/octocode-code-engineer/src/detectors/test-quality.ts +367 -0
- package/skills/octocode-code-engineer/src/index.test.ts +4425 -0
- package/skills/octocode-code-engineer/src/index.ts +403 -0
- package/skills/octocode-code-engineer/src/pipeline/cache.test.ts +199 -0
- package/skills/octocode-code-engineer/src/pipeline/cache.ts +130 -0
- package/skills/octocode-code-engineer/src/pipeline/cli.test.ts +493 -0
- package/skills/octocode-code-engineer/src/pipeline/cli.ts +344 -0
- package/skills/octocode-code-engineer/src/pipeline/main.test.ts +174 -0
- package/skills/octocode-code-engineer/src/pipeline/main.ts +1074 -0
- package/skills/octocode-code-engineer/src/pipeline.test.ts +84 -0
- package/skills/octocode-code-engineer/src/reporting/analysis.test.ts +782 -0
- package/skills/octocode-code-engineer/src/reporting/analysis.ts +688 -0
- package/skills/octocode-code-engineer/src/reporting/output-contract.test.ts +463 -0
- package/skills/octocode-code-engineer/src/reporting/summary-md.test.ts +421 -0
- package/skills/octocode-code-engineer/src/reporting/summary-md.ts +714 -0
- package/skills/octocode-code-engineer/src/reporting/writer.ts +430 -0
- package/skills/octocode-code-engineer/src/sanity.test.ts +47 -0
- package/skills/octocode-code-engineer/src/types/constants.ts +248 -0
- package/skills/octocode-code-engineer/src/types/index.ts +80 -0
- package/skills/octocode-code-engineer/src/types/interfaces.ts +682 -0
- package/skills/octocode-code-engineer/tsconfig.json +17 -0
- package/skills/octocode-code-engineer/vitest.config.ts +8 -0
- package/skills/octocode-documentation-writer/README.md +113 -0
- package/skills/octocode-documentation-writer/SKILL.md +886 -0
- package/skills/octocode-documentation-writer/references/agent-discovery-analysis.md +453 -0
- package/skills/octocode-documentation-writer/references/agent-documentation-writer.md +255 -0
- package/skills/octocode-documentation-writer/references/agent-engineer-questions.md +247 -0
- package/skills/octocode-documentation-writer/references/agent-orchestrator.md +370 -0
- package/skills/octocode-documentation-writer/references/agent-qa-validator.md +227 -0
- package/skills/octocode-documentation-writer/references/agent-researcher.md +250 -0
- package/skills/octocode-documentation-writer/schemas/analysis-schema.json +886 -0
- package/skills/octocode-documentation-writer/schemas/discovery-tasks.json +96 -0
- package/skills/octocode-documentation-writer/schemas/documentation-structure.json +373 -0
- package/skills/octocode-documentation-writer/schemas/partial-discovery-schema.json +102 -0
- package/skills/octocode-documentation-writer/schemas/partial-research-schema.json +98 -0
- package/skills/octocode-documentation-writer/schemas/qa-results-schema.json +113 -0
- package/skills/octocode-documentation-writer/schemas/questions-schema.json +228 -0
- package/skills/octocode-documentation-writer/schemas/research-schema.json +104 -0
- package/skills/octocode-documentation-writer/schemas/state-schema.json +222 -0
- package/skills/octocode-documentation-writer/schemas/work-assignments-schema.json +74 -0
- package/skills/octocode-plan/SKILL.md +122 -116
- package/skills/octocode-prompt-optimizer/SKILL.md +617 -0
- package/skills/octocode-pull-request-reviewer/README.md +249 -0
- package/skills/octocode-pull-request-reviewer/SKILL.md +479 -0
- package/skills/octocode-pull-request-reviewer/references/dependency-check.md +74 -0
- package/skills/octocode-pull-request-reviewer/references/domain-reviewers.md +24 -0
- package/skills/octocode-pull-request-reviewer/references/execution-lifecycle.md +441 -0
- package/skills/octocode-pull-request-reviewer/references/flow-analysis-protocol.md +64 -0
- package/skills/octocode-pull-request-reviewer/references/output-template.md +174 -0
- package/skills/octocode-pull-request-reviewer/references/parallel-agent-protocol.md +182 -0
- package/skills/octocode-pull-request-reviewer/references/review-guidelines.md +26 -0
- package/skills/octocode-pull-request-reviewer/references/verification-checklist.md +40 -0
- package/skills/octocode-research/.claude/settings.local.json +46 -0
- package/skills/octocode-research/.octocode/plan/code-review-fixes/plan.md +312 -0
- package/skills/octocode-research/.octocode/plan/code-review-fixes/research.md +212 -0
- package/skills/octocode-research/.octocode/plans/NODE_SERVER_START_PLAN.md +755 -0
- package/skills/octocode-research/.octocode/research/code-review/research.md +371 -0
- package/skills/octocode-research/.octocode/review/IMPROVEMENTS.md +391 -0
- package/skills/octocode-research/.octocode/review/REVIEW_PLAN.md +289 -0
- package/skills/octocode-research/.octocode/review/REVIEW_REPORT.md +356 -0
- package/skills/octocode-research/AGENTS.md +349 -0
- package/skills/octocode-research/README.md +494 -0
- package/skills/octocode-research/SKILL.md +652 -274
- package/skills/octocode-research/docs/API_REFERENCE.md +562 -0
- package/skills/octocode-research/docs/ARCHITECTURE.md +554 -0
- package/skills/octocode-research/docs/FLOWS.md +577 -0
- package/skills/octocode-research/docs/OVERVIEW.md +564 -0
- package/skills/octocode-research/docs/SERVER_FLOWS.md +631 -0
- package/skills/octocode-research/ecosystem.config.cjs +88 -0
- package/skills/octocode-research/eslint.config.mjs +27 -0
- package/skills/octocode-research/package.json +84 -0
- package/skills/octocode-research/references/GUARDRAILS.md +40 -0
- package/skills/octocode-research/references/PARALLEL_AGENT_PROTOCOL.md +178 -0
- package/skills/octocode-research/references/roast-prompt.md +149 -0
- package/skills/octocode-research/scripts/server-init.d.ts +2 -0
- package/skills/octocode-research/scripts/server-init.js +2 -0
- package/skills/octocode-research/scripts/server.d.ts +8 -0
- package/skills/octocode-research/scripts/server.js +445 -0
- package/skills/octocode-research/src/__tests__/integration/circuitBreaker.test.ts +205 -0
- package/skills/octocode-research/src/__tests__/integration/routes.test.ts +374 -0
- package/skills/octocode-research/src/__tests__/unit/circuitBreaker.test.ts +245 -0
- package/skills/octocode-research/src/__tests__/unit/errorHandler.test.ts +183 -0
- package/skills/octocode-research/src/__tests__/unit/httpPreprocess.test.ts +157 -0
- package/skills/octocode-research/src/__tests__/unit/logger.test.ts +143 -0
- package/skills/octocode-research/src/__tests__/unit/queryParser.test.ts +130 -0
- package/skills/octocode-research/src/__tests__/unit/responseBuilder.test.ts +469 -0
- package/skills/octocode-research/src/__tests__/unit/retry.test.ts +205 -0
- package/skills/octocode-research/src/index.ts +186 -0
- package/skills/octocode-research/src/mcpCache.ts +49 -0
- package/skills/octocode-research/src/middleware/errorHandler.ts +65 -0
- package/skills/octocode-research/src/middleware/logger.ts +61 -0
- package/skills/octocode-research/src/middleware/queryParser.ts +115 -0
- package/skills/octocode-research/src/middleware/readiness.ts +17 -0
- package/skills/octocode-research/src/routes/github.ts +197 -0
- package/skills/octocode-research/src/routes/local.ts +175 -0
- package/skills/octocode-research/src/routes/lsp.ts +177 -0
- package/skills/octocode-research/src/routes/package.ts +127 -0
- package/skills/octocode-research/src/routes/prompts.ts +138 -0
- package/skills/octocode-research/src/routes/tools.ts +677 -0
- package/skills/octocode-research/src/server-init.ts +363 -0
- package/skills/octocode-research/src/server.ts +285 -0
- package/skills/octocode-research/src/types/errorGuards.ts +151 -0
- package/skills/octocode-research/src/types/express.d.ts +76 -0
- package/skills/octocode-research/src/types/guards.ts +98 -0
- package/skills/octocode-research/src/types/mcp.ts +119 -0
- package/skills/octocode-research/src/types/responses.ts +199 -0
- package/skills/octocode-research/src/types/toolTypes.ts +33 -0
- package/skills/octocode-research/src/utils/asyncTimeout.ts +116 -0
- package/skills/octocode-research/src/utils/circuitBreaker.ts +492 -0
- package/skills/octocode-research/src/utils/colors.ts +53 -0
- package/skills/octocode-research/src/utils/errorQueue.ts +71 -0
- package/skills/octocode-research/src/utils/logEmoji.ts +103 -0
- package/skills/octocode-research/src/utils/logger.ts +413 -0
- package/skills/octocode-research/src/utils/resilience.ts +169 -0
- package/skills/octocode-research/src/utils/responseBuilder.ts +495 -0
- package/skills/octocode-research/src/utils/responseFactory.ts +100 -0
- package/skills/octocode-research/src/utils/responseParser.ts +272 -0
- package/skills/octocode-research/src/utils/retry.ts +280 -0
- package/skills/octocode-research/src/utils/routeFactory.ts +117 -0
- package/skills/octocode-research/src/utils/url.ts +20 -0
- package/skills/octocode-research/src/validation/httpPreprocess.ts +155 -0
- package/skills/octocode-research/src/validation/index.ts +2 -0
- package/skills/octocode-research/src/validation/schemas.ts +578 -0
- package/skills/octocode-research/src/validation/toolCallSchema.ts +132 -0
- package/skills/octocode-research/tsconfig.json +21 -0
- package/skills/octocode-research/tsdown.config.ts +42 -0
- package/skills/octocode-research/vitest.config.ts +20 -0
- package/skills/octocode-researcher/SKILL.md +461 -0
- package/skills/octocode-researcher/references/fallbacks.md +120 -0
- package/skills/{octocode-local-search → octocode-researcher}/references/tool-reference.md +132 -49
- package/skills/{octocode-local-search → octocode-researcher}/references/workflow-patterns.md +204 -4
- package/skills/octocode-rfc-generator/SKILL.md +223 -0
- package/skills/octocode-rfc-generator/references/rfc-template.md +193 -0
- package/skills/octocode-roast/SKILL.md +63 -21
- package/skills/octocode-implement/SKILL.md +0 -293
- package/skills/octocode-implement/references/execution-phases.md +0 -317
- package/skills/octocode-implement/references/tool-reference.md +0 -403
- package/skills/octocode-implement/references/workflow-patterns.md +0 -385
- package/skills/octocode-local-search/SKILL.md +0 -449
- package/skills/octocode-pr-review/SKILL.md +0 -391
- package/skills/octocode-pr-review/references/domain-reviewers.md +0 -105
- package/skills/octocode-pr-review/references/execution-lifecycle.md +0 -116
- package/skills/octocode-pr-review/references/research-flows.md +0 -75
- package/skills/octocode-research/references/tool-reference.md +0 -304
- package/skills/octocode-research/references/workflow-patterns.md +0 -325
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Octocode Research Skill
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all octocode tools with skill-friendly names.
|
|
5
|
+
* Each tool can be called as a function with query arrays.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { githubSearchCode, localSearchCode, lspGotoDefinition } from 'octocode-research';
|
|
10
|
+
*
|
|
11
|
+
* // Search GitHub code
|
|
12
|
+
* const result = await githubSearchCode({
|
|
13
|
+
* queries: [{
|
|
14
|
+
* mainResearchGoal: "Find React hooks",
|
|
15
|
+
* researchGoal: "Locate useState implementation",
|
|
16
|
+
* reasoning: "Understanding state management",
|
|
17
|
+
* keywordsToSearch: ["useState"],
|
|
18
|
+
* owner: "facebook",
|
|
19
|
+
* repo: "react"
|
|
20
|
+
* }]
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// GitHub Tools (Remote Repository Research)
|
|
27
|
+
// ============================================================================
|
|
28
|
+
|
|
29
|
+
export {
|
|
30
|
+
fetchMultipleGitHubFileContents as githubGetFileContent,
|
|
31
|
+
searchMultipleGitHubCode as githubSearchCode,
|
|
32
|
+
searchMultipleGitHubPullRequests as githubSearchPullRequests,
|
|
33
|
+
searchMultipleGitHubRepos as githubSearchRepositories,
|
|
34
|
+
exploreMultipleRepositoryStructures as githubViewRepoStructure,
|
|
35
|
+
} from 'octocode-mcp/public';
|
|
36
|
+
|
|
37
|
+
// GitHub Types
|
|
38
|
+
export type {
|
|
39
|
+
FileContentQuery,
|
|
40
|
+
ContentResult,
|
|
41
|
+
GitHubCodeSearchQuery,
|
|
42
|
+
SearchResult,
|
|
43
|
+
GitHubPullRequestSearchQuery,
|
|
44
|
+
PullRequestSearchResult,
|
|
45
|
+
GitHubReposSearchQuery,
|
|
46
|
+
RepoSearchResult,
|
|
47
|
+
GitHubViewRepoStructureQuery,
|
|
48
|
+
RepoStructureResult,
|
|
49
|
+
} from 'octocode-mcp/public';
|
|
50
|
+
|
|
51
|
+
// ============================================================================
|
|
52
|
+
// Local Tools (Local Codebase Research)
|
|
53
|
+
// ============================================================================
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
executeFetchContent as localGetFileContent,
|
|
57
|
+
executeFindFiles as localFindFiles,
|
|
58
|
+
executeRipgrepSearch as localSearchCode,
|
|
59
|
+
executeViewStructure as localViewStructure,
|
|
60
|
+
} from 'octocode-mcp/public';
|
|
61
|
+
|
|
62
|
+
// Local Types
|
|
63
|
+
export type {
|
|
64
|
+
FetchContentQuery,
|
|
65
|
+
FetchContentResult,
|
|
66
|
+
FindFilesQuery,
|
|
67
|
+
FindFilesResult,
|
|
68
|
+
RipgrepSearchQuery,
|
|
69
|
+
SearchContentResult,
|
|
70
|
+
ViewStructureQuery,
|
|
71
|
+
ViewStructureResult,
|
|
72
|
+
} from 'octocode-mcp/public';
|
|
73
|
+
|
|
74
|
+
// ============================================================================
|
|
75
|
+
// LSP Tools (Semantic Code Analysis)
|
|
76
|
+
// ============================================================================
|
|
77
|
+
|
|
78
|
+
export {
|
|
79
|
+
executeGotoDefinition as lspGotoDefinition,
|
|
80
|
+
executeFindReferences as lspFindReferences,
|
|
81
|
+
executeCallHierarchy as lspCallHierarchy,
|
|
82
|
+
} from 'octocode-mcp/public';
|
|
83
|
+
|
|
84
|
+
// LSP Types
|
|
85
|
+
export type {
|
|
86
|
+
LSPGotoDefinitionQuery,
|
|
87
|
+
GotoDefinitionResult,
|
|
88
|
+
LSPFindReferencesQuery,
|
|
89
|
+
FindReferencesResult,
|
|
90
|
+
LSPCallHierarchyQuery,
|
|
91
|
+
CallHierarchyResult,
|
|
92
|
+
} from 'octocode-mcp/public';
|
|
93
|
+
|
|
94
|
+
// ============================================================================
|
|
95
|
+
// Package Search Tools
|
|
96
|
+
// ============================================================================
|
|
97
|
+
|
|
98
|
+
export { searchPackages as packageSearch } from 'octocode-mcp/public';
|
|
99
|
+
|
|
100
|
+
// Package Types
|
|
101
|
+
export type {
|
|
102
|
+
PackageSearchQuery,
|
|
103
|
+
PackageSearchResult,
|
|
104
|
+
NpmPackageSearchQuery,
|
|
105
|
+
PythonPackageSearchQuery,
|
|
106
|
+
} from 'octocode-mcp/public';
|
|
107
|
+
|
|
108
|
+
// ============================================================================
|
|
109
|
+
// Response Utilities (for custom result formatting)
|
|
110
|
+
// ============================================================================
|
|
111
|
+
|
|
112
|
+
// Legacy API (backwards compatible)
|
|
113
|
+
export { createResult, createResponseFormat } from 'octocode-mcp/public';
|
|
114
|
+
|
|
115
|
+
// New Role-Based Response API
|
|
116
|
+
export {
|
|
117
|
+
createRoleBasedResult,
|
|
118
|
+
ContentBuilder,
|
|
119
|
+
QuickResult,
|
|
120
|
+
StatusEmoji,
|
|
121
|
+
StatusEmojis,
|
|
122
|
+
} from 'octocode-mcp/public';
|
|
123
|
+
|
|
124
|
+
export type {
|
|
125
|
+
ContentRole,
|
|
126
|
+
RoleContentBlock,
|
|
127
|
+
RoleBasedResultOptions,
|
|
128
|
+
RoleAnnotations,
|
|
129
|
+
} from 'octocode-mcp/public';
|
|
130
|
+
|
|
131
|
+
// Research-specific response builders
|
|
132
|
+
export { ResearchResponse } from './utils/responseBuilder.js';
|
|
133
|
+
|
|
134
|
+
// ============================================================================
|
|
135
|
+
// Tool Metadata & Configuration
|
|
136
|
+
// ============================================================================
|
|
137
|
+
|
|
138
|
+
export {
|
|
139
|
+
TOOL_NAMES,
|
|
140
|
+
DESCRIPTIONS,
|
|
141
|
+
getToolHintsSync,
|
|
142
|
+
getGenericErrorHintsSync,
|
|
143
|
+
} from 'octocode-mcp/public';
|
|
144
|
+
|
|
145
|
+
// ============================================================================
|
|
146
|
+
// Security Validation (for wrapping tool calls)
|
|
147
|
+
// ============================================================================
|
|
148
|
+
|
|
149
|
+
export { withBasicSecurityValidation } from 'octocode-mcp/public';
|
|
150
|
+
|
|
151
|
+
// ============================================================================
|
|
152
|
+
// Token Management (for GitHub API authentication)
|
|
153
|
+
// ============================================================================
|
|
154
|
+
|
|
155
|
+
export {
|
|
156
|
+
initialize,
|
|
157
|
+
initializeProviders,
|
|
158
|
+
getGitHubToken,
|
|
159
|
+
getToken,
|
|
160
|
+
getTokenSource,
|
|
161
|
+
} from 'octocode-mcp/public';
|
|
162
|
+
|
|
163
|
+
export type { TokenSourceType } from 'octocode-mcp/public';
|
|
164
|
+
|
|
165
|
+
// ============================================================================
|
|
166
|
+
// Session Management (for tracking usage and telemetry)
|
|
167
|
+
// ============================================================================
|
|
168
|
+
|
|
169
|
+
export {
|
|
170
|
+
initializeSession,
|
|
171
|
+
getSessionManager,
|
|
172
|
+
logSessionInit,
|
|
173
|
+
logToolCall,
|
|
174
|
+
logPromptCall,
|
|
175
|
+
logSessionError,
|
|
176
|
+
logRateLimit,
|
|
177
|
+
resetSessionManager,
|
|
178
|
+
} from 'octocode-mcp/public';
|
|
179
|
+
|
|
180
|
+
export type {
|
|
181
|
+
SessionData,
|
|
182
|
+
ToolCallData,
|
|
183
|
+
PromptCallData,
|
|
184
|
+
ErrorData,
|
|
185
|
+
RateLimitData,
|
|
186
|
+
} from 'octocode-mcp/public';
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Content Cache Module
|
|
3
|
+
*
|
|
4
|
+
* Loads mcpContent ONCE at server startup and provides cached access.
|
|
5
|
+
* Routes should use getMcpContent() instead of calling loadToolContent() on each request.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { CompleteMetadata } from 'octocode-mcp/public';
|
|
9
|
+
import { initialize, loadToolContent } from 'octocode-mcp/public';
|
|
10
|
+
|
|
11
|
+
let mcpContent: CompleteMetadata | null = null;
|
|
12
|
+
let initPromise: Promise<CompleteMetadata> | null = null;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Initialize mcpContent - call ONCE at server startup
|
|
16
|
+
* Safe to call multiple times (idempotent)
|
|
17
|
+
*/
|
|
18
|
+
export async function initializeMcpContent(): Promise<CompleteMetadata> {
|
|
19
|
+
if (mcpContent) return mcpContent;
|
|
20
|
+
|
|
21
|
+
if (initPromise) return initPromise;
|
|
22
|
+
|
|
23
|
+
initPromise = (async () => {
|
|
24
|
+
await initialize();
|
|
25
|
+
const content = await loadToolContent();
|
|
26
|
+
mcpContent = content;
|
|
27
|
+
return content;
|
|
28
|
+
})();
|
|
29
|
+
|
|
30
|
+
return initPromise;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get cached mcpContent - use in routes
|
|
35
|
+
* Throws if not initialized (indicates server startup failed)
|
|
36
|
+
*/
|
|
37
|
+
export function getMcpContent(): CompleteMetadata {
|
|
38
|
+
if (!mcpContent) {
|
|
39
|
+
throw new Error('mcpContent not initialized. Call initializeMcpContent() at server startup.');
|
|
40
|
+
}
|
|
41
|
+
return mcpContent;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Check if mcpContent is initialized (for health checks)
|
|
46
|
+
*/
|
|
47
|
+
export function isMcpInitialized(): boolean {
|
|
48
|
+
return mcpContent !== null;
|
|
49
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Request, Response, NextFunction } from 'express';
|
|
2
|
+
import type { z } from 'zod/v4';
|
|
3
|
+
import { logError, logWarn, sanitizeQueryParams } from '../utils/logger.js';
|
|
4
|
+
import { logSessionError } from '../index.js';
|
|
5
|
+
import { fireAndForgetWithTimeout } from '../utils/asyncTimeout.js';
|
|
6
|
+
|
|
7
|
+
export interface ApiError extends Error {
|
|
8
|
+
statusCode?: number;
|
|
9
|
+
code?: string;
|
|
10
|
+
details?: z.core.$ZodIssue[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
import { extractToolName } from '../utils/url.js';
|
|
14
|
+
|
|
15
|
+
export function errorHandler(
|
|
16
|
+
error: ApiError,
|
|
17
|
+
req: Request,
|
|
18
|
+
res: Response,
|
|
19
|
+
_next: NextFunction
|
|
20
|
+
): void {
|
|
21
|
+
const statusCode = error.statusCode ?? 500;
|
|
22
|
+
const isValidationError = statusCode === 400;
|
|
23
|
+
|
|
24
|
+
// Log with appropriate level - now persisted to ~/.octocode/logs/errors.log
|
|
25
|
+
if (isValidationError) {
|
|
26
|
+
logWarn(`[VALIDATION] ${req.method} ${req.path}: ${error.message}`, {
|
|
27
|
+
path: req.path,
|
|
28
|
+
query: sanitizeQueryParams(req.query as Record<string, unknown>),
|
|
29
|
+
details: error.details,
|
|
30
|
+
});
|
|
31
|
+
} else {
|
|
32
|
+
logError(`[SERVER] ${req.method} ${req.path}: ${error.message}`, error);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Log error to session telemetry
|
|
36
|
+
const toolName = extractToolName(req.path);
|
|
37
|
+
const errorCode = error.code ?? (isValidationError ? 'VALIDATION_ERROR' : 'INTERNAL_ERROR');
|
|
38
|
+
fireAndForgetWithTimeout(
|
|
39
|
+
() => logSessionError(toolName, errorCode),
|
|
40
|
+
5000,
|
|
41
|
+
'logSessionError'
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const response: {
|
|
45
|
+
success: false;
|
|
46
|
+
error: {
|
|
47
|
+
message: string;
|
|
48
|
+
code: string;
|
|
49
|
+
details?: z.core.$ZodIssue[];
|
|
50
|
+
};
|
|
51
|
+
} = {
|
|
52
|
+
success: false,
|
|
53
|
+
error: {
|
|
54
|
+
message: error.message,
|
|
55
|
+
code: error.code ?? 'INTERNAL_ERROR',
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Include validation details for 400 errors
|
|
60
|
+
if (isValidationError && error.details) {
|
|
61
|
+
response.error.details = error.details;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
res.status(statusCode).json(response);
|
|
65
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Request, Response, NextFunction } from 'express';
|
|
2
|
+
import { randomUUID } from 'crypto';
|
|
3
|
+
import { logToolCall, sanitizeQueryParams } from '../utils/logger.js';
|
|
4
|
+
import { resultLog, errorLog } from '../utils/colors.js';
|
|
5
|
+
import { extractToolName } from '../utils/url.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Generate or retrieve request ID for log correlation.
|
|
9
|
+
* Uses X-Request-ID header if provided, otherwise generates a new UUID.
|
|
10
|
+
*/
|
|
11
|
+
function getRequestId(req: Request): string {
|
|
12
|
+
const existingId = req.headers['x-request-id'];
|
|
13
|
+
if (typeof existingId === 'string' && existingId.length > 0) {
|
|
14
|
+
return existingId;
|
|
15
|
+
}
|
|
16
|
+
return randomUUID();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function requestLogger(
|
|
20
|
+
req: Request,
|
|
21
|
+
res: Response,
|
|
22
|
+
next: NextFunction
|
|
23
|
+
): void {
|
|
24
|
+
const start = Date.now();
|
|
25
|
+
const requestId = getRequestId(req);
|
|
26
|
+
|
|
27
|
+
// Set request ID on response header for correlation
|
|
28
|
+
res.setHeader('x-request-id', requestId);
|
|
29
|
+
|
|
30
|
+
res.on('finish', () => {
|
|
31
|
+
const duration = Date.now() - start;
|
|
32
|
+
const status = res.statusCode;
|
|
33
|
+
const statusIcon = status >= 400 ? '❌' : '✅';
|
|
34
|
+
const success = status < 400;
|
|
35
|
+
|
|
36
|
+
// Results output in BLUE for success, RED for error
|
|
37
|
+
const resultMessage = `${statusIcon} ${req.method} ${req.path} ${status} ${duration}ms`;
|
|
38
|
+
|
|
39
|
+
if (success) {
|
|
40
|
+
console.log(resultLog(resultMessage));
|
|
41
|
+
} else {
|
|
42
|
+
console.log(errorLog(resultMessage));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (req.path !== '/health') {
|
|
46
|
+
logToolCall({
|
|
47
|
+
tool: extractToolName(req.path),
|
|
48
|
+
route: req.path,
|
|
49
|
+
method: req.method,
|
|
50
|
+
params: sanitizeQueryParams(req.query as Record<string, unknown>),
|
|
51
|
+
duration,
|
|
52
|
+
success,
|
|
53
|
+
error: success ? undefined : `HTTP ${status}`,
|
|
54
|
+
requestId,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
next();
|
|
60
|
+
}
|
|
61
|
+
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { Response } from 'express';
|
|
2
|
+
import { z } from 'zod/v4';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Custom error class for validation failures.
|
|
6
|
+
* Carries HTTP status code for proper error responses.
|
|
7
|
+
*/
|
|
8
|
+
class ValidationError extends Error {
|
|
9
|
+
statusCode: number;
|
|
10
|
+
code: string;
|
|
11
|
+
details: z.core.$ZodIssue[];
|
|
12
|
+
|
|
13
|
+
constructor(message: string, details: z.core.$ZodIssue[] = []) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = 'ValidationError';
|
|
16
|
+
this.statusCode = 400;
|
|
17
|
+
this.code = 'VALIDATION_ERROR';
|
|
18
|
+
this.details = details;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Parse and validate query parameters using a Zod schema.
|
|
24
|
+
* Returns the validated data wrapped in an array (for tool compatibility).
|
|
25
|
+
*
|
|
26
|
+
* @param query - Express request query object
|
|
27
|
+
* @param schema - Zod schema for validation
|
|
28
|
+
* @returns Array containing the validated query object
|
|
29
|
+
* @throws ValidationError if validation fails
|
|
30
|
+
*/
|
|
31
|
+
export function parseAndValidate<T>(
|
|
32
|
+
query: Record<string, unknown>,
|
|
33
|
+
schema: z.ZodType<T>
|
|
34
|
+
): T[] {
|
|
35
|
+
// Check for JSON-encoded queries array (batch mode)
|
|
36
|
+
if (query.queries && typeof query.queries === 'string') {
|
|
37
|
+
try {
|
|
38
|
+
const parsed = JSON.parse(query.queries);
|
|
39
|
+
if (Array.isArray(parsed)) {
|
|
40
|
+
// Validate each item in the array
|
|
41
|
+
const validated = parsed.map((item, index) => {
|
|
42
|
+
const result = schema.safeParse(item);
|
|
43
|
+
if (!result.success) {
|
|
44
|
+
throw new ValidationError(
|
|
45
|
+
`Validation failed for query[${index}]: ${formatZodError(result.error)}`,
|
|
46
|
+
result.error.issues
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return result.data;
|
|
50
|
+
});
|
|
51
|
+
return validated;
|
|
52
|
+
}
|
|
53
|
+
} catch (e) {
|
|
54
|
+
if (e instanceof ValidationError) throw e;
|
|
55
|
+
// JSON.parse failed - fall through to single query mode silently
|
|
56
|
+
// (avoid logging untrusted input in production)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Parse flat query params (single query mode)
|
|
61
|
+
const cleanedQuery: Record<string, unknown> = {};
|
|
62
|
+
for (const [key, value] of Object.entries(query)) {
|
|
63
|
+
if (key !== 'queries') {
|
|
64
|
+
cleanedQuery[key] = value;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const result = schema.safeParse(cleanedQuery);
|
|
69
|
+
if (!result.success) {
|
|
70
|
+
throw new ValidationError(
|
|
71
|
+
formatZodError(result.error),
|
|
72
|
+
result.error.issues
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return [result.data];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Format Zod error into a human-readable string.
|
|
81
|
+
*/
|
|
82
|
+
function formatZodError(error: z.ZodError): string {
|
|
83
|
+
return error.issues
|
|
84
|
+
.map((issue) => {
|
|
85
|
+
const path = issue.path.join('.');
|
|
86
|
+
return path ? `${path}: ${issue.message}` : issue.message;
|
|
87
|
+
})
|
|
88
|
+
.join('; ');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Send standardized tool result response.
|
|
93
|
+
*/
|
|
94
|
+
export function sendToolResult(
|
|
95
|
+
res: Response,
|
|
96
|
+
result: {
|
|
97
|
+
content?: Array<{ type: string; text?: string }>;
|
|
98
|
+
isError?: boolean;
|
|
99
|
+
}
|
|
100
|
+
): void {
|
|
101
|
+
const textContent = result.content?.find(
|
|
102
|
+
(c) => c.type === 'text' && 'text' in c
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
const isError = result.isError ?? false;
|
|
106
|
+
|
|
107
|
+
res.status(isError ? 500 : 200).json({
|
|
108
|
+
success: !isError,
|
|
109
|
+
data: textContent?.text ?? null,
|
|
110
|
+
raw: result,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Legacy function for backwards compatibility (deprecated)
|
|
115
|
+
// Internal alias: parseQueryToArray = parseAndValidate
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Request, Response, NextFunction, RequestHandler } from 'express';
|
|
2
|
+
import { isMcpInitialized } from '../mcpCache.js';
|
|
3
|
+
|
|
4
|
+
export const checkReadiness: RequestHandler = (_req: Request, res: Response, next: NextFunction) => {
|
|
5
|
+
if (!isMcpInitialized()) {
|
|
6
|
+
res.status(503).json({
|
|
7
|
+
success: false,
|
|
8
|
+
error: {
|
|
9
|
+
message: 'Server is initializing',
|
|
10
|
+
code: 'SERVER_INITIALIZING',
|
|
11
|
+
hint: 'Please retry in a few seconds',
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
next();
|
|
17
|
+
};
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub routes using route factory pattern.
|
|
3
|
+
*
|
|
4
|
+
* @module routes/github
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Router } from 'express';
|
|
8
|
+
import {
|
|
9
|
+
githubSearchCode,
|
|
10
|
+
githubGetFileContent,
|
|
11
|
+
githubSearchRepositories,
|
|
12
|
+
githubViewRepoStructure,
|
|
13
|
+
githubSearchPullRequests,
|
|
14
|
+
} from '../index.js';
|
|
15
|
+
import {
|
|
16
|
+
githubSearchSchema,
|
|
17
|
+
githubContentSchema,
|
|
18
|
+
githubReposSchema,
|
|
19
|
+
githubStructureSchema,
|
|
20
|
+
githubPRsSchema,
|
|
21
|
+
} from '../validation/index.js';
|
|
22
|
+
import { ResearchResponse, QuickResult, detectLanguageFromPath } from '../utils/responseBuilder.js';
|
|
23
|
+
import { withGitHubResilience } from '../utils/resilience.js';
|
|
24
|
+
import { createRouteHandler } from '../utils/routeFactory.js';
|
|
25
|
+
import {
|
|
26
|
+
safeString,
|
|
27
|
+
safeNumber,
|
|
28
|
+
safeArray,
|
|
29
|
+
transformPagination,
|
|
30
|
+
} from '../utils/responseFactory.js';
|
|
31
|
+
import { isObject, hasProperty, hasNumberProperty, hasBooleanProperty } from '../types/guards.js';
|
|
32
|
+
|
|
33
|
+
export const githubRoutes = Router();
|
|
34
|
+
|
|
35
|
+
// GET /githubSearchCode - Search code on GitHub
|
|
36
|
+
githubRoutes.get(
|
|
37
|
+
'/githubSearchCode',
|
|
38
|
+
createRouteHandler({
|
|
39
|
+
schema: githubSearchSchema,
|
|
40
|
+
toolFn: githubSearchCode,
|
|
41
|
+
toolName: 'githubSearchCode',
|
|
42
|
+
resilience: withGitHubResilience,
|
|
43
|
+
transform: (parsed, queries) => {
|
|
44
|
+
const { data, hints, research } = parsed;
|
|
45
|
+
const files = safeArray<Record<string, unknown>>(data, 'files');
|
|
46
|
+
|
|
47
|
+
return ResearchResponse.searchResults({
|
|
48
|
+
files: files.map((f) => {
|
|
49
|
+
const textMatches = safeArray<string>(f, 'text_matches');
|
|
50
|
+
const firstMatch = textMatches[0];
|
|
51
|
+
return {
|
|
52
|
+
path: safeString(f, 'path'),
|
|
53
|
+
repo: hasProperty(f, 'repo') && typeof f.repo === 'string' ? f.repo : undefined,
|
|
54
|
+
matches: textMatches.length,
|
|
55
|
+
preview: typeof firstMatch === 'string' ? firstMatch.trim().slice(0, 200) : undefined,
|
|
56
|
+
};
|
|
57
|
+
}),
|
|
58
|
+
totalMatches: isObject(data.pagination) ? safeNumber(data.pagination, 'totalMatches', 0) : 0,
|
|
59
|
+
pagination: transformPagination(data.pagination),
|
|
60
|
+
searchPattern: Array.isArray(queries[0]?.keywordsToSearch)
|
|
61
|
+
? queries[0].keywordsToSearch.join(' ')
|
|
62
|
+
: undefined,
|
|
63
|
+
mcpHints: hints,
|
|
64
|
+
research,
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
})
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// GET /githubGetFileContent - Read file from GitHub
|
|
71
|
+
githubRoutes.get(
|
|
72
|
+
'/githubGetFileContent',
|
|
73
|
+
createRouteHandler({
|
|
74
|
+
schema: githubContentSchema,
|
|
75
|
+
toolFn: githubGetFileContent,
|
|
76
|
+
toolName: 'githubGetFileContent',
|
|
77
|
+
resilience: withGitHubResilience,
|
|
78
|
+
transform: (parsed, queries) => {
|
|
79
|
+
const { data, hints, research } = parsed;
|
|
80
|
+
|
|
81
|
+
return ResearchResponse.fileContent({
|
|
82
|
+
path: safeString(data, 'path', queries[0]?.path || 'unknown'),
|
|
83
|
+
content: safeString(data, 'content'),
|
|
84
|
+
lines: hasNumberProperty(data, 'startLine')
|
|
85
|
+
? {
|
|
86
|
+
start: data.startLine,
|
|
87
|
+
end: hasNumberProperty(data, 'endLine') ? data.endLine : data.startLine,
|
|
88
|
+
}
|
|
89
|
+
: undefined,
|
|
90
|
+
language: detectLanguageFromPath(queries[0]?.path || ''),
|
|
91
|
+
totalLines: hasNumberProperty(data, 'totalLines') ? data.totalLines : undefined,
|
|
92
|
+
isPartial: hasBooleanProperty(data, 'isPartial') ? data.isPartial : undefined,
|
|
93
|
+
mcpHints: hints,
|
|
94
|
+
research,
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
})
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// GET /githubSearchRepositories - Search repositories
|
|
101
|
+
githubRoutes.get(
|
|
102
|
+
'/githubSearchRepositories',
|
|
103
|
+
createRouteHandler({
|
|
104
|
+
schema: githubReposSchema,
|
|
105
|
+
toolFn: githubSearchRepositories,
|
|
106
|
+
toolName: 'githubSearchRepositories',
|
|
107
|
+
resilience: withGitHubResilience,
|
|
108
|
+
transform: (parsed) => {
|
|
109
|
+
const { data, hints: mcpHints } = parsed;
|
|
110
|
+
const repos = safeArray<Record<string, unknown>>(data, 'repositories');
|
|
111
|
+
|
|
112
|
+
const summary = repos.length > 0
|
|
113
|
+
? `Found ${repos.length} repositories:\n` +
|
|
114
|
+
repos
|
|
115
|
+
.slice(0, 10)
|
|
116
|
+
.map((r) =>
|
|
117
|
+
`- ${safeString(r, 'owner')}/${safeString(r, 'repo')}${hasNumberProperty(r, 'stars') ? ` ⭐${r.stars}` : ''}\n ${safeString(r, 'description', 'No description')}`
|
|
118
|
+
)
|
|
119
|
+
.join('\n')
|
|
120
|
+
: 'No repositories found';
|
|
121
|
+
|
|
122
|
+
const hints: string[] = [...mcpHints];
|
|
123
|
+
return repos.length === 0
|
|
124
|
+
? QuickResult.empty(summary, hints.length > 0 ? hints : [
|
|
125
|
+
'Try different search terms',
|
|
126
|
+
'Use topicsToSearch for topic-based search',
|
|
127
|
+
])
|
|
128
|
+
: QuickResult.success(summary, data, hints.length > 0 ? hints : [
|
|
129
|
+
'Use githubViewRepoStructure to explore repo',
|
|
130
|
+
'Use githubSearchCode to search within repo',
|
|
131
|
+
]);
|
|
132
|
+
},
|
|
133
|
+
})
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
// GET /githubViewRepoStructure - View repository structure
|
|
137
|
+
githubRoutes.get(
|
|
138
|
+
'/githubViewRepoStructure',
|
|
139
|
+
createRouteHandler({
|
|
140
|
+
schema: githubStructureSchema,
|
|
141
|
+
toolFn: githubViewRepoStructure,
|
|
142
|
+
toolName: 'githubViewRepoStructure',
|
|
143
|
+
resilience: withGitHubResilience,
|
|
144
|
+
transform: (parsed, queries) => {
|
|
145
|
+
const { data, hints, research } = parsed;
|
|
146
|
+
const structure = isObject(data.structure) ? data.structure : {};
|
|
147
|
+
const rootEntry = isObject(structure['.']) ? structure['.'] as { files?: string[]; folders?: string[] } : { files: [], folders: [] };
|
|
148
|
+
const summary = isObject(data.summary) ? data.summary : {};
|
|
149
|
+
|
|
150
|
+
return ResearchResponse.repoStructure({
|
|
151
|
+
path: queries[0]?.path || '/',
|
|
152
|
+
structure: {
|
|
153
|
+
files: Array.isArray(rootEntry.files) ? rootEntry.files : [],
|
|
154
|
+
folders: Array.isArray(rootEntry.folders) ? rootEntry.folders : [],
|
|
155
|
+
},
|
|
156
|
+
depth: hasNumberProperty(queries[0], 'depth') ? queries[0].depth : undefined,
|
|
157
|
+
totalFiles: hasNumberProperty(summary, 'totalFiles') ? summary.totalFiles : undefined,
|
|
158
|
+
totalFolders: hasNumberProperty(summary, 'totalFolders') ? summary.totalFolders : undefined,
|
|
159
|
+
owner: queries[0]?.owner,
|
|
160
|
+
repo: queries[0]?.repo,
|
|
161
|
+
mcpHints: hints,
|
|
162
|
+
research,
|
|
163
|
+
});
|
|
164
|
+
},
|
|
165
|
+
})
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
// GET /githubSearchPullRequests - Search pull requests
|
|
169
|
+
githubRoutes.get(
|
|
170
|
+
'/githubSearchPullRequests',
|
|
171
|
+
createRouteHandler({
|
|
172
|
+
schema: githubPRsSchema,
|
|
173
|
+
toolFn: githubSearchPullRequests,
|
|
174
|
+
toolName: 'githubSearchPullRequests',
|
|
175
|
+
resilience: withGitHubResilience,
|
|
176
|
+
transform: (parsed, queries) => {
|
|
177
|
+
const { data, hints, research } = parsed;
|
|
178
|
+
const prs = safeArray<Record<string, unknown>>(data, 'pull_requests');
|
|
179
|
+
|
|
180
|
+
return ResearchResponse.pullRequests({
|
|
181
|
+
prs: prs.map((pr) => ({
|
|
182
|
+
number: safeNumber(pr, 'number', 0),
|
|
183
|
+
title: safeString(pr, 'title'),
|
|
184
|
+
state: safeString(pr, 'state'),
|
|
185
|
+
author: hasProperty(pr, 'author') && typeof pr.author === 'string' ? pr.author : undefined,
|
|
186
|
+
url: hasProperty(pr, 'url') && typeof pr.url === 'string' ? pr.url : undefined,
|
|
187
|
+
})),
|
|
188
|
+
repo: queries[0]?.owner && queries[0]?.repo
|
|
189
|
+
? `${queries[0].owner}/${queries[0].repo}`
|
|
190
|
+
: undefined,
|
|
191
|
+
pagination: transformPagination(data.pagination),
|
|
192
|
+
mcpHints: hints,
|
|
193
|
+
research,
|
|
194
|
+
});
|
|
195
|
+
},
|
|
196
|
+
})
|
|
197
|
+
);
|