octocode-cli 1.2.6 → 1.2.7
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 +7026 -6945
- 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,755 @@
|
|
|
1
|
+
# Implementation Plan: Replace Bash Scripts with Node.js Server Start
|
|
2
|
+
|
|
3
|
+
> **Goal**: Replace `install.sh` (441 lines) and `start.sh` (9 lines) with an enhanced Node.js `scripts/server.ts`
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Executive Summary
|
|
8
|
+
|
|
9
|
+
| Aspect | Current (Bash) | Target (Node.js) |
|
|
10
|
+
|--------|----------------|------------------|
|
|
11
|
+
| Entry point | `./install.sh start` | `npm run server:start` |
|
|
12
|
+
| Lines of code | 450 (bash) | ~180 (TypeScript) |
|
|
13
|
+
| Cross-platform | ❌ Unix only | ✅ Windows/Mac/Linux |
|
|
14
|
+
| Dependencies | bash, curl, lsof | Node.js only |
|
|
15
|
+
| Token resolution | Manual gh CLI | ✅ `resolveTokenFull` from octocode-shared |
|
|
16
|
+
| Session management | Manual file ops | ✅ `getOrCreateSession` from octocode-shared |
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Key Design Decision: Reuse octocode-shared
|
|
21
|
+
|
|
22
|
+
Instead of re-implementing token and session logic, we leverage existing utilities:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
octocode-shared (add as direct dependency)
|
|
26
|
+
├── resolveTokenFull() → Complete token resolution (env → storage → gh CLI)
|
|
27
|
+
├── getOrCreateSession() → Session management with deferred writes
|
|
28
|
+
└── getSessionId() → Get current session ID
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This ensures consistency with octocode-mcp and octocode-cli.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Phase 0: Package.json Update (REQUIRED)
|
|
36
|
+
|
|
37
|
+
### Add octocode-shared as Direct Dependency
|
|
38
|
+
|
|
39
|
+
```diff
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"express": "^4.21.2",
|
|
42
|
+
"js-yaml": "^4.1.1",
|
|
43
|
+
"octocode-mcp": "file:../../packages/octocode-mcp",
|
|
44
|
+
+ "octocode-shared": "file:../../packages/octocode-shared",
|
|
45
|
+
"zod": "^3.24.1"
|
|
46
|
+
},
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Why**: `getOrCreateSession` and `getSessionId` are exported from `octocode-shared/session`, not from `octocode-mcp`.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Phase 1: Analyze Current install.sh Functions
|
|
54
|
+
|
|
55
|
+
### Features to Migrate
|
|
56
|
+
|
|
57
|
+
| Function | Lines | Priority | Migration Strategy |
|
|
58
|
+
|----------|-------|----------|-------------------|
|
|
59
|
+
| `check_requirements()` | 98-110 | HIGH | Simple Node.js version check |
|
|
60
|
+
| `is_our_server_running()` | 113-118 | HIGH | `fetch('/health')` |
|
|
61
|
+
| `is_port_occupied()` | 135-147 | HIGH | `net.createServer()` check |
|
|
62
|
+
| `stop_server()` | 149-172 | HIGH | `process.kill()` + force option |
|
|
63
|
+
| `install_dependencies()` | 179-218 | HIGH | `execSync('npm/yarn install')` |
|
|
64
|
+
| `start_server()` | 220-303 | HIGH | `spawn('node', ['dist/server.js'])` |
|
|
65
|
+
| `get_or_create_session_id()` | 39-78 | LOW | ✅ Use `getOrCreateSession()` |
|
|
66
|
+
| `log_skill_install()` | 81-93 | LOW | Simple fetch POST |
|
|
67
|
+
| `is_monorepo()` | 174-177 | MEDIUM | Check for `../../package.json` |
|
|
68
|
+
|
|
69
|
+
### Features Already Available (No Implementation Needed)
|
|
70
|
+
|
|
71
|
+
| Feature | Source | Notes |
|
|
72
|
+
|---------|--------|-------|
|
|
73
|
+
| Token resolution | `resolveTokenFull` | Handles env + storage + gh CLI |
|
|
74
|
+
| Session management | `getOrCreateSession` | Handles file + deferred writes |
|
|
75
|
+
| Colors | `src/utils/colors.ts` | Already exists in project |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Phase 2: Enhanced scripts/server.ts
|
|
80
|
+
|
|
81
|
+
### New File Structure
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
#!/usr/bin/env npx tsx
|
|
85
|
+
/**
|
|
86
|
+
* Cross-platform server management for octocode-research
|
|
87
|
+
* Usage: npx tsx scripts/server.ts [start|stop|restart|status|health|logs|build]
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
import { spawn, execSync } from 'child_process';
|
|
91
|
+
import { writeFileSync, readFileSync, unlinkSync, existsSync, openSync, closeSync, rmSync } from 'fs';
|
|
92
|
+
import { createServer } from 'net';
|
|
93
|
+
import { tmpdir, homedir } from 'os';
|
|
94
|
+
import { join, dirname } from 'path';
|
|
95
|
+
import { fileURLToPath } from 'url';
|
|
96
|
+
|
|
97
|
+
// Token resolution from octocode-shared (via octocode-mcp re-export)
|
|
98
|
+
import { resolveTokenFull, type FullTokenResolution, type GhCliTokenGetter } from 'octocode-mcp';
|
|
99
|
+
|
|
100
|
+
// Session management from octocode-shared (direct import)
|
|
101
|
+
import { getOrCreateSession, getSessionId, type PersistedSession } from 'octocode-shared';
|
|
102
|
+
|
|
103
|
+
// === CONSTANTS ===
|
|
104
|
+
const PORT = 1987;
|
|
105
|
+
const PID_FILE = join(tmpdir(), 'octocode-research.pid');
|
|
106
|
+
const LOG_FILE = join(tmpdir(), 'octocode-research.log');
|
|
107
|
+
const OCTOCODE_LOGS_DIR = join(homedir(), '.octocode', 'logs');
|
|
108
|
+
const LOG_ENDPOINT = 'https://octocode-mcp-host.onrender.com/log';
|
|
109
|
+
const SKILL_NAME = 'octocode-research';
|
|
110
|
+
const SKILL_VERSION = '2.0.0';
|
|
111
|
+
|
|
112
|
+
// === COLORS (inline for standalone script) ===
|
|
113
|
+
const colors = {
|
|
114
|
+
green: (s: string) => `\x1b[32m${s}\x1b[0m`,
|
|
115
|
+
red: (s: string) => `\x1b[31m${s}\x1b[0m`,
|
|
116
|
+
yellow: (s: string) => `\x1b[33m${s}\x1b[0m`,
|
|
117
|
+
cyan: (s: string) => `\x1b[36m${s}\x1b[0m`,
|
|
118
|
+
dim: (s: string) => `\x1b[2m${s}\x1b[0m`,
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// === UTILITY FUNCTIONS ===
|
|
122
|
+
|
|
123
|
+
/** Get project root (where package.json lives) */
|
|
124
|
+
function getProjectRoot(): string {
|
|
125
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
126
|
+
return join(__dirname, '..');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Check Node.js version >= 20 */
|
|
130
|
+
function checkNodeVersion(): void {
|
|
131
|
+
const version = process.versions.node.split('.')[0];
|
|
132
|
+
if (parseInt(version, 10) < 20) {
|
|
133
|
+
console.error(colors.red(`❌ Node.js 20+ required (found: v${process.versions.node})`));
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Check if dist/ exists and is built */
|
|
139
|
+
function needsBuild(): boolean {
|
|
140
|
+
const distServer = join(getProjectRoot(), 'dist', 'server.js');
|
|
141
|
+
return !existsSync(distServer);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Check if we're in the octocode-mcp monorepo */
|
|
145
|
+
function isMonorepo(): boolean {
|
|
146
|
+
const root = getProjectRoot();
|
|
147
|
+
const parentPkg = join(root, '..', '..', 'package.json');
|
|
148
|
+
if (!existsSync(parentPkg)) return false;
|
|
149
|
+
try {
|
|
150
|
+
const content = readFileSync(parentPkg, 'utf8');
|
|
151
|
+
return content.includes('"octocode-mcp"');
|
|
152
|
+
} catch {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Install dependencies if node_modules missing */
|
|
158
|
+
function installDependencies(): void {
|
|
159
|
+
const root = getProjectRoot();
|
|
160
|
+
const nodeModules = join(root, 'node_modules');
|
|
161
|
+
|
|
162
|
+
if (existsSync(nodeModules)) {
|
|
163
|
+
return; // Already installed
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
console.log(colors.cyan('[INFO] Installing dependencies...'));
|
|
167
|
+
|
|
168
|
+
if (isMonorepo()) {
|
|
169
|
+
const workspaceRoot = join(root, '..', '..');
|
|
170
|
+
execSync('yarn install', { cwd: workspaceRoot, stdio: 'inherit' });
|
|
171
|
+
} else {
|
|
172
|
+
execSync('npm install --omit=dev', { cwd: root, stdio: 'inherit' });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** Build project if dist/ is missing */
|
|
177
|
+
function buildProject(): void {
|
|
178
|
+
if (!needsBuild()) {
|
|
179
|
+
return; // Already built
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
console.log(colors.cyan('[INFO] Building project...'));
|
|
183
|
+
const root = getProjectRoot();
|
|
184
|
+
|
|
185
|
+
if (isMonorepo()) {
|
|
186
|
+
execSync('yarn run build', { cwd: root, stdio: 'inherit' });
|
|
187
|
+
} else {
|
|
188
|
+
execSync('npm run build', { cwd: root, stdio: 'inherit' });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** Check if server is running via health endpoint */
|
|
193
|
+
async function isServerRunning(): Promise<boolean> {
|
|
194
|
+
try {
|
|
195
|
+
const controller = new AbortController();
|
|
196
|
+
const timeout = setTimeout(() => controller.abort(), 2000);
|
|
197
|
+
const res = await fetch(`http://localhost:${PORT}/health`, { signal: controller.signal });
|
|
198
|
+
clearTimeout(timeout);
|
|
199
|
+
return res.ok;
|
|
200
|
+
} catch {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** Check if port is in use by ANY process (not just our server) */
|
|
206
|
+
async function isPortInUse(): Promise<boolean> {
|
|
207
|
+
return new Promise((resolve) => {
|
|
208
|
+
const server = createServer()
|
|
209
|
+
.once('error', () => resolve(true))
|
|
210
|
+
.once('listening', () => {
|
|
211
|
+
server.close();
|
|
212
|
+
resolve(false);
|
|
213
|
+
})
|
|
214
|
+
.listen(PORT);
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** Get PID from file */
|
|
219
|
+
function getPid(): number | null {
|
|
220
|
+
if (existsSync(PID_FILE)) {
|
|
221
|
+
try {
|
|
222
|
+
const pid = parseInt(readFileSync(PID_FILE, 'utf8').trim(), 10);
|
|
223
|
+
return isNaN(pid) ? null : pid;
|
|
224
|
+
} catch {
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** Check if a process with given PID exists */
|
|
232
|
+
function isProcessRunning(pid: number): boolean {
|
|
233
|
+
try {
|
|
234
|
+
process.kill(pid, 0); // Signal 0 = check existence
|
|
235
|
+
return true;
|
|
236
|
+
} catch {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** gh CLI token getter for resolveTokenFull */
|
|
242
|
+
const getGhCliToken: GhCliTokenGetter = () => {
|
|
243
|
+
try {
|
|
244
|
+
return execSync('gh auth token', { encoding: 'utf8', timeout: 5000 }).trim();
|
|
245
|
+
} catch {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
/** Resolve and set GitHub/GitLab tokens in environment */
|
|
251
|
+
async function resolveAndSetTokens(): Promise<void> {
|
|
252
|
+
try {
|
|
253
|
+
// GitHub token resolution (env → storage → gh CLI)
|
|
254
|
+
const result = await resolveTokenFull({ getGhCliToken });
|
|
255
|
+
if (result?.token) {
|
|
256
|
+
process.env.GITHUB_TOKEN = result.token;
|
|
257
|
+
console.log(colors.cyan(`[INFO] GitHub token resolved from: ${result.source}`));
|
|
258
|
+
}
|
|
259
|
+
} catch {
|
|
260
|
+
// Token resolution is optional - server can still start
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// GitLab tokens (pass through from environment)
|
|
264
|
+
// These are already in process.env if set, no resolution needed
|
|
265
|
+
if (process.env.GITLAB_TOKEN) {
|
|
266
|
+
console.log(colors.cyan('[INFO] GitLab token found in environment'));
|
|
267
|
+
} else if (process.env.GL_TOKEN) {
|
|
268
|
+
console.log(colors.cyan('[INFO] GL_TOKEN found in environment'));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** Clean up old log files */
|
|
273
|
+
function cleanupLogs(): void {
|
|
274
|
+
// Clear main log file
|
|
275
|
+
writeFileSync(LOG_FILE, '');
|
|
276
|
+
|
|
277
|
+
// Clean octocode logs directory
|
|
278
|
+
if (existsSync(OCTOCODE_LOGS_DIR)) {
|
|
279
|
+
try {
|
|
280
|
+
const files = require('fs').readdirSync(OCTOCODE_LOGS_DIR);
|
|
281
|
+
for (const file of files) {
|
|
282
|
+
if (file.endsWith('.log')) {
|
|
283
|
+
rmSync(join(OCTOCODE_LOGS_DIR, file), { force: true });
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
} catch {
|
|
287
|
+
// Ignore cleanup errors
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** Send skill install log (async, non-blocking) */
|
|
293
|
+
function logSkillInstall(sessionId: string): void {
|
|
294
|
+
const payload = {
|
|
295
|
+
sessionId,
|
|
296
|
+
intent: 'skill_install',
|
|
297
|
+
data: { skill_name: SKILL_NAME, skill_version: SKILL_VERSION },
|
|
298
|
+
timestamp: new Date().toISOString(),
|
|
299
|
+
version: SKILL_VERSION,
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
// Fire and forget - don't await
|
|
303
|
+
fetch(LOG_ENDPOINT, {
|
|
304
|
+
method: 'POST',
|
|
305
|
+
headers: { 'Content-Type': 'application/json' },
|
|
306
|
+
body: JSON.stringify(payload),
|
|
307
|
+
signal: AbortSignal.timeout(5000),
|
|
308
|
+
}).catch(() => {}); // Ignore errors
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/** Kill process on port (cross-platform) */
|
|
312
|
+
function killProcessOnPort(): boolean {
|
|
313
|
+
try {
|
|
314
|
+
if (process.platform === 'win32') {
|
|
315
|
+
// Windows: use netstat + taskkill
|
|
316
|
+
const output = execSync(`netstat -ano | findstr :${PORT}`, { encoding: 'utf8' });
|
|
317
|
+
const match = output.match(/LISTENING\s+(\d+)/);
|
|
318
|
+
if (match) {
|
|
319
|
+
execSync(`taskkill /PID ${match[1]} /F`, { stdio: 'ignore' });
|
|
320
|
+
return true;
|
|
321
|
+
}
|
|
322
|
+
} else {
|
|
323
|
+
// Unix: use lsof
|
|
324
|
+
const pid = execSync(`lsof -ti :${PORT}`, { encoding: 'utf8' }).trim();
|
|
325
|
+
if (pid) {
|
|
326
|
+
process.kill(parseInt(pid, 10), 'SIGKILL');
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
} catch {
|
|
331
|
+
// No process on port
|
|
332
|
+
}
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// === COMMANDS ===
|
|
337
|
+
|
|
338
|
+
async function start(): Promise<void> {
|
|
339
|
+
// Step 1: Check Node version
|
|
340
|
+
checkNodeVersion();
|
|
341
|
+
|
|
342
|
+
// Step 2: Check if already running
|
|
343
|
+
if (await isServerRunning()) {
|
|
344
|
+
console.log(colors.green(`✅ Server already running on port ${PORT}`));
|
|
345
|
+
const sessionId = await getSessionId();
|
|
346
|
+
if (sessionId) logSkillInstall(sessionId);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Step 3: Check if port is occupied by another process
|
|
351
|
+
if (await isPortInUse()) {
|
|
352
|
+
console.error(colors.red(`❌ Port ${PORT} is already in use by another process!`));
|
|
353
|
+
console.error(colors.yellow(` Check with: lsof -i :${PORT}`));
|
|
354
|
+
console.error(colors.cyan(` Or use: npm run server stop --force`));
|
|
355
|
+
process.exit(1);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Step 4: Install dependencies if needed
|
|
359
|
+
installDependencies();
|
|
360
|
+
|
|
361
|
+
// Step 5: Build if needed
|
|
362
|
+
buildProject();
|
|
363
|
+
|
|
364
|
+
// Step 6: Resolve tokens
|
|
365
|
+
await resolveAndSetTokens();
|
|
366
|
+
|
|
367
|
+
// Step 7: Clean up old logs
|
|
368
|
+
cleanupLogs();
|
|
369
|
+
|
|
370
|
+
// Step 8: Start server
|
|
371
|
+
console.log(colors.cyan(`[SERVER] Starting Octocode Research Server on port ${PORT}...`));
|
|
372
|
+
|
|
373
|
+
const root = getProjectRoot();
|
|
374
|
+
const logFd = openSync(LOG_FILE, 'a');
|
|
375
|
+
const isWindows = process.platform === 'win32';
|
|
376
|
+
|
|
377
|
+
const child = spawn('node', ['dist/server.js'], {
|
|
378
|
+
cwd: root,
|
|
379
|
+
detached: !isWindows,
|
|
380
|
+
windowsHide: true,
|
|
381
|
+
stdio: ['ignore', logFd, logFd],
|
|
382
|
+
env: process.env,
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
// Close log file descriptor after spawn
|
|
386
|
+
closeSync(logFd);
|
|
387
|
+
|
|
388
|
+
child.unref();
|
|
389
|
+
writeFileSync(PID_FILE, String(child.pid));
|
|
390
|
+
|
|
391
|
+
// Step 9: Wait for health check
|
|
392
|
+
for (let i = 0; i < 15; i++) {
|
|
393
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
394
|
+
if (await isServerRunning()) {
|
|
395
|
+
console.log(colors.green(`✅ Server started successfully! (PID: ${child.pid})`));
|
|
396
|
+
console.log(colors.cyan(`[SERVER] Health check: http://localhost:${PORT}/health`));
|
|
397
|
+
console.log(colors.green(`\n[INFO] API ready at http://localhost:${PORT}`));
|
|
398
|
+
|
|
399
|
+
// Log analytics (non-blocking)
|
|
400
|
+
const session = await getOrCreateSession();
|
|
401
|
+
logSkillInstall(session.sessionId);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// Failed to start
|
|
407
|
+
console.error(colors.red('❌ Server failed to start. Check logs:'));
|
|
408
|
+
console.error(colors.yellow(` ${LOG_FILE}`));
|
|
409
|
+
process.exit(1);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
function stop(force = false): void {
|
|
413
|
+
const pid = getPid();
|
|
414
|
+
|
|
415
|
+
// If force flag, kill whatever is on the port
|
|
416
|
+
if (force) {
|
|
417
|
+
if (killProcessOnPort()) {
|
|
418
|
+
console.log(colors.green(`✅ Killed process on port ${PORT}`));
|
|
419
|
+
} else {
|
|
420
|
+
console.log(colors.yellow(`⚠️ No process found on port ${PORT}`));
|
|
421
|
+
}
|
|
422
|
+
} else if (pid && isProcessRunning(pid)) {
|
|
423
|
+
try {
|
|
424
|
+
process.kill(pid, 'SIGTERM');
|
|
425
|
+
console.log(colors.green(`✅ Stopped server (PID: ${pid})`));
|
|
426
|
+
} catch {
|
|
427
|
+
console.log(colors.yellow('⚠️ Process already stopped'));
|
|
428
|
+
}
|
|
429
|
+
} else {
|
|
430
|
+
console.log(colors.yellow('⚠️ Server not running'));
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// Clean up PID file
|
|
434
|
+
if (existsSync(PID_FILE)) {
|
|
435
|
+
try {
|
|
436
|
+
unlinkSync(PID_FILE);
|
|
437
|
+
} catch {
|
|
438
|
+
// Ignore cleanup errors
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
async function restart(): Promise<void> {
|
|
444
|
+
stop();
|
|
445
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
446
|
+
await start();
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
async function status(): Promise<void> {
|
|
450
|
+
const running = await isServerRunning();
|
|
451
|
+
const pid = getPid();
|
|
452
|
+
|
|
453
|
+
if (running) {
|
|
454
|
+
console.log(colors.green(`✅ Server running on port ${PORT}${pid ? ` (PID: ${pid})` : ''}`));
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// Server not responding - check why
|
|
459
|
+
const portInUse = await isPortInUse();
|
|
460
|
+
|
|
461
|
+
if (portInUse) {
|
|
462
|
+
console.log(colors.yellow(`⚠️ Port ${PORT} is in use, but NOT by our server!`));
|
|
463
|
+
console.log(colors.cyan(` Check with: lsof -i :${PORT}`));
|
|
464
|
+
console.log(colors.cyan(` Force stop: npm run server stop --force`));
|
|
465
|
+
} else if (pid && isProcessRunning(pid)) {
|
|
466
|
+
console.log(colors.yellow(`⚠️ PID ${pid} exists but server not responding`));
|
|
467
|
+
console.log(colors.cyan(' Try: npm run server restart'));
|
|
468
|
+
} else {
|
|
469
|
+
console.log(colors.red('❌ Server not running'));
|
|
470
|
+
console.log(colors.cyan(' Start with: npm run server:start'));
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
async function health(): Promise<void> {
|
|
475
|
+
try {
|
|
476
|
+
const res = await fetch(`http://localhost:${PORT}/health`);
|
|
477
|
+
const data = await res.json();
|
|
478
|
+
console.log(JSON.stringify(data, null, 2));
|
|
479
|
+
} catch {
|
|
480
|
+
console.error(colors.red('❌ Server not responding'));
|
|
481
|
+
process.exit(1);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
function logs(follow = false): void {
|
|
486
|
+
if (!existsSync(LOG_FILE)) {
|
|
487
|
+
console.log(colors.yellow(`⚠️ No logs found at ${LOG_FILE}`));
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if (follow) {
|
|
492
|
+
// Live tail using spawn
|
|
493
|
+
const tail = spawn('tail', ['-f', LOG_FILE], { stdio: 'inherit' });
|
|
494
|
+
process.on('SIGINT', () => {
|
|
495
|
+
tail.kill();
|
|
496
|
+
process.exit(0);
|
|
497
|
+
});
|
|
498
|
+
} else {
|
|
499
|
+
const content = readFileSync(LOG_FILE, 'utf8');
|
|
500
|
+
console.log(content || colors.yellow('(empty log file)'));
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
function build(): void {
|
|
505
|
+
checkNodeVersion();
|
|
506
|
+
installDependencies();
|
|
507
|
+
buildProject();
|
|
508
|
+
console.log(colors.green('✅ Build complete'));
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
function showUsage(): void {
|
|
512
|
+
console.log(`
|
|
513
|
+
🔍 Octocode Research Server - HTTP API on port ${PORT}
|
|
514
|
+
|
|
515
|
+
Usage: npm run server [command] [options]
|
|
516
|
+
|
|
517
|
+
Commands:
|
|
518
|
+
start Start server (install & build if needed) [default]
|
|
519
|
+
stop Stop running server
|
|
520
|
+
stop --force Kill any process on port ${PORT}
|
|
521
|
+
restart Restart server
|
|
522
|
+
status Check server status
|
|
523
|
+
health Health check (JSON output)
|
|
524
|
+
logs Show server logs
|
|
525
|
+
logs -f Follow logs (live tail)
|
|
526
|
+
build Build without starting
|
|
527
|
+
|
|
528
|
+
Quick Start:
|
|
529
|
+
npm run server:start # Start server
|
|
530
|
+
npm run server:stop # Stop server
|
|
531
|
+
npm run server status # Check status
|
|
532
|
+
curl http://localhost:${PORT}/health
|
|
533
|
+
|
|
534
|
+
API Endpoints:
|
|
535
|
+
GET /health Health check
|
|
536
|
+
GET /local/* Local filesystem tools
|
|
537
|
+
GET /lsp/* LSP semantic tools
|
|
538
|
+
GET /github/* GitHub API tools
|
|
539
|
+
GET /package/* Package search
|
|
540
|
+
GET /tools/list List available tools
|
|
541
|
+
GET /prompts/list List available prompts
|
|
542
|
+
`);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// === MAIN ===
|
|
546
|
+
|
|
547
|
+
const commands: Record<string, () => Promise<void> | void> = {
|
|
548
|
+
start,
|
|
549
|
+
stop: () => stop(process.argv.includes('--force')),
|
|
550
|
+
restart,
|
|
551
|
+
status,
|
|
552
|
+
health,
|
|
553
|
+
logs: () => logs(process.argv.includes('-f') || process.argv.includes('--follow')),
|
|
554
|
+
build,
|
|
555
|
+
'--help': showUsage,
|
|
556
|
+
'-h': showUsage,
|
|
557
|
+
help: showUsage,
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
const cmd = process.argv[2] || 'start';
|
|
561
|
+
const handler = commands[cmd];
|
|
562
|
+
|
|
563
|
+
if (!handler) {
|
|
564
|
+
console.error(colors.red(`Unknown command: ${cmd}`));
|
|
565
|
+
showUsage();
|
|
566
|
+
process.exit(1);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
Promise.resolve(handler()).catch((err) => {
|
|
570
|
+
console.error(colors.red(`Error: ${err.message}`));
|
|
571
|
+
process.exit(1);
|
|
572
|
+
});
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
## Phase 3: Update SKILL.md
|
|
578
|
+
|
|
579
|
+
### Changes Required
|
|
580
|
+
|
|
581
|
+
```diff
|
|
582
|
+
### Phase 1: Initialization & Context (Startup)
|
|
583
|
+
|
|
584
|
+
1. **Start Server** (Idempotent):
|
|
585
|
+
- ```bash
|
|
586
|
+
- ./install.sh start
|
|
587
|
+
- ```
|
|
588
|
+
+ ```bash
|
|
589
|
+
+ npm run server:start
|
|
590
|
+
+ ```
|
|
591
|
+
*Action*: Tell user "Starting the research server..."
|
|
592
|
+
|
|
593
|
+
- **Fallback**: If `./install.sh` fails (e.g., bash errors, missing `lsof`, Windows), use Node.js:
|
|
594
|
+
- ```bash
|
|
595
|
+
- npm run server:start
|
|
596
|
+
- ```
|
|
597
|
+
+ **Alternative**: For development with hot-reload:
|
|
598
|
+
+ ```bash
|
|
599
|
+
+ npm run dev
|
|
600
|
+
+ ```
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
---
|
|
604
|
+
|
|
605
|
+
## Phase 4: File Cleanup
|
|
606
|
+
|
|
607
|
+
### Files to Delete
|
|
608
|
+
|
|
609
|
+
```bash
|
|
610
|
+
rm skills/octocode-research/install.sh
|
|
611
|
+
rm skills/octocode-research/start.sh
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### package.json Updates
|
|
615
|
+
|
|
616
|
+
```diff
|
|
617
|
+
"dependencies": {
|
|
618
|
+
"express": "^4.21.2",
|
|
619
|
+
"js-yaml": "^4.1.1",
|
|
620
|
+
"octocode-mcp": "file:../../packages/octocode-mcp",
|
|
621
|
+
+ "octocode-shared": "file:../../packages/octocode-shared",
|
|
622
|
+
"zod": "^3.24.1"
|
|
623
|
+
},
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
```diff
|
|
627
|
+
"files": [
|
|
628
|
+
"dist",
|
|
629
|
+
"src",
|
|
630
|
+
- "install.sh",
|
|
631
|
+
- "start.sh",
|
|
632
|
+
"SKILL.md",
|
|
633
|
+
"LICENSE",
|
|
634
|
+
"tsconfig.json"
|
|
635
|
+
],
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
---
|
|
639
|
+
|
|
640
|
+
## Phase 5: Testing Checklist
|
|
641
|
+
|
|
642
|
+
### Manual Tests
|
|
643
|
+
|
|
644
|
+
| Test | Command | Expected |
|
|
645
|
+
|------|---------|----------|
|
|
646
|
+
| Fresh start | `npm run server:start` | Server starts, health OK |
|
|
647
|
+
| Already running | `npm run server:start` | Shows "already running" |
|
|
648
|
+
| Port conflict | (start nginx on 1987) | Shows "port in use" error |
|
|
649
|
+
| Force stop | `npm run server stop --force` | Kills any process on port |
|
|
650
|
+
| Stop | `npm run server:stop` | Server stops |
|
|
651
|
+
| Restart | `npm run server restart` | Clean restart |
|
|
652
|
+
| Status (running) | `npm run server status` | Shows ✅ running |
|
|
653
|
+
| Status (stopped) | `npm run server status` | Shows ❌ not running |
|
|
654
|
+
| Status (port conflict) | `npm run server status` | Shows ⚠️ port in use |
|
|
655
|
+
| Health | `npm run server health` | JSON response |
|
|
656
|
+
| Logs | `npm run server logs` | Shows log file |
|
|
657
|
+
| Logs follow | `npm run server logs -f` | Live tail |
|
|
658
|
+
| Build only | `npm run server build` | Builds without starting |
|
|
659
|
+
|
|
660
|
+
### Token Resolution Tests
|
|
661
|
+
|
|
662
|
+
| Scenario | Expected |
|
|
663
|
+
|----------|----------|
|
|
664
|
+
| `GITHUB_TOKEN` set | Uses env token |
|
|
665
|
+
| `GH_TOKEN` set | Uses env token |
|
|
666
|
+
| `OCTOCODE_TOKEN` set | Uses env token (highest priority) |
|
|
667
|
+
| `gh auth` configured | Uses gh CLI token |
|
|
668
|
+
| Octocode credentials stored | Uses stored token |
|
|
669
|
+
| `GITLAB_TOKEN` set | Passed through to server |
|
|
670
|
+
| `GL_TOKEN` set | Passed through to server |
|
|
671
|
+
| No token available | Server starts (limited functionality) |
|
|
672
|
+
|
|
673
|
+
### Cross-Platform Tests
|
|
674
|
+
|
|
675
|
+
- [ ] macOS (ARM64)
|
|
676
|
+
- [ ] macOS (x64)
|
|
677
|
+
- [ ] Linux (Ubuntu)
|
|
678
|
+
- [ ] Windows (WSL)
|
|
679
|
+
- [ ] Windows (native)
|
|
680
|
+
|
|
681
|
+
---
|
|
682
|
+
|
|
683
|
+
## Implementation Order
|
|
684
|
+
|
|
685
|
+
1. **Update package.json** - Add octocode-shared dependency
|
|
686
|
+
2. **Create enhanced `scripts/server.ts`** (~180 lines)
|
|
687
|
+
3. **Test new script** with all commands
|
|
688
|
+
4. **Update SKILL.md** documentation
|
|
689
|
+
5. **Update package.json** files array
|
|
690
|
+
6. **Delete bash scripts**
|
|
691
|
+
7. **Final testing**
|
|
692
|
+
|
|
693
|
+
---
|
|
694
|
+
|
|
695
|
+
## Rollback Plan
|
|
696
|
+
|
|
697
|
+
If issues arise, the original bash scripts can be restored from git:
|
|
698
|
+
|
|
699
|
+
```bash
|
|
700
|
+
git checkout HEAD -- skills/octocode-research/install.sh
|
|
701
|
+
git checkout HEAD -- skills/octocode-research/start.sh
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
---
|
|
705
|
+
|
|
706
|
+
## Timeline Estimate
|
|
707
|
+
|
|
708
|
+
| Phase | Effort |
|
|
709
|
+
|-------|--------|
|
|
710
|
+
| Phase 0: package.json dependency | 2 min |
|
|
711
|
+
| Phase 2: Enhanced server.ts | 25 min |
|
|
712
|
+
| Phase 3: Update SKILL.md | 5 min |
|
|
713
|
+
| Phase 4: File cleanup | 2 min |
|
|
714
|
+
| Phase 5: Testing | 20 min |
|
|
715
|
+
| **Total** | **~55 min** |
|
|
716
|
+
|
|
717
|
+
---
|
|
718
|
+
|
|
719
|
+
## Comparison: Old Plan vs Final Plan
|
|
720
|
+
|
|
721
|
+
| Aspect | Old Plan | Final Plan |
|
|
722
|
+
|--------|----------|------------|
|
|
723
|
+
| Lines of code | ~200 | ~180 |
|
|
724
|
+
| Token resolution | Manual (60 lines) | `resolveTokenFull` (5 lines) |
|
|
725
|
+
| Session management | Manual (30 lines) | `getOrCreateSession` (1 line) |
|
|
726
|
+
| Import source | ❌ Incorrect (octocode-mcp) | ✅ Correct (octocode-shared) |
|
|
727
|
+
| gh CLI fallback | ❌ Missing | ✅ Via `getGhCliToken` option |
|
|
728
|
+
| GitLab tokens | ❌ Missing | ✅ Pass-through |
|
|
729
|
+
| Port conflict check | ❌ Missing | ✅ `net.createServer()` |
|
|
730
|
+
| Force stop option | ❌ Missing | ✅ `--force` flag |
|
|
731
|
+
| Live log tailing | ❌ Missing | ✅ `-f` / `--follow` flag |
|
|
732
|
+
| Log cleanup | ❌ Missing | ✅ Clears old logs |
|
|
733
|
+
| Build command | ❌ Missing | ✅ Included |
|
|
734
|
+
| Status with port check | ❌ Missing | ✅ Detects "port in use by other" |
|
|
735
|
+
| API routes in help | ❌ Missing | ✅ Included |
|
|
736
|
+
| Error handling | ❌ Missing | ✅ Top-level catch |
|
|
737
|
+
|
|
738
|
+
---
|
|
739
|
+
|
|
740
|
+
## Key Imports Summary
|
|
741
|
+
|
|
742
|
+
```typescript
|
|
743
|
+
// Token resolution - re-exported from octocode-mcp (originally from octocode-shared)
|
|
744
|
+
import { resolveTokenFull, type FullTokenResolution, type GhCliTokenGetter } from 'octocode-mcp';
|
|
745
|
+
|
|
746
|
+
// Session management - direct from octocode-shared (NOT exported from octocode-mcp)
|
|
747
|
+
import { getOrCreateSession, getSessionId, type PersistedSession } from 'octocode-shared';
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
**⚠️ Important**: `getOrCreateSession` and `getSessionId` are NOT exported from `octocode-mcp`. They must be imported directly from `octocode-shared`, which requires adding it as a direct dependency.
|
|
751
|
+
|
|
752
|
+
---
|
|
753
|
+
|
|
754
|
+
*Plan finalized: All issues addressed*
|
|
755
|
+
*Status: Ready for implementation*
|