octocode-cli 1.2.5 → 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 +86 -109
- package/out/octocode-cli.js +7027 -7014
- 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,344 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import { ALL_CATEGORIES, DEFAULT_OPTS, PILLAR_CATEGORIES } from '../types/index.js';
|
|
4
|
+
|
|
5
|
+
import type { AnalysisOptions } from '../types/index.js';
|
|
6
|
+
|
|
7
|
+
function parseNumeric(raw: string | undefined, fallback: number): number {
|
|
8
|
+
const n = parseInt(raw ?? '', 10);
|
|
9
|
+
return Number.isNaN(n) ? fallback : n;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function parseDecimal(raw: string | undefined, fallback: number): number {
|
|
13
|
+
const n = parseFloat(raw ?? '');
|
|
14
|
+
return Number.isNaN(n) ? fallback : n;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function resolveCategories(val: string, flagName: string): Set<string> {
|
|
18
|
+
const tokens = val
|
|
19
|
+
.split(',')
|
|
20
|
+
.map(s => s.trim())
|
|
21
|
+
.filter(Boolean);
|
|
22
|
+
const resolved = new Set<string>();
|
|
23
|
+
for (const token of tokens) {
|
|
24
|
+
if (PILLAR_CATEGORIES[token]) {
|
|
25
|
+
for (const cat of PILLAR_CATEGORIES[token]) resolved.add(cat);
|
|
26
|
+
} else if (ALL_CATEGORIES.has(token)) {
|
|
27
|
+
resolved.add(token);
|
|
28
|
+
} else {
|
|
29
|
+
console.error(
|
|
30
|
+
`Unknown ${flagName}: "${token}". Use pillar names (${Object.keys(PILLAR_CATEGORIES).join(', ')}) or category names.`
|
|
31
|
+
);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return resolved;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function parseScope(
|
|
39
|
+
val: string,
|
|
40
|
+
root: string
|
|
41
|
+
): { paths: string[]; symbols: Map<string, string[]> } {
|
|
42
|
+
const paths: string[] = [];
|
|
43
|
+
const symbols = new Map<string, string[]>();
|
|
44
|
+
for (const token of val
|
|
45
|
+
.split(',')
|
|
46
|
+
.map(s => s.trim())
|
|
47
|
+
.filter(Boolean)) {
|
|
48
|
+
const colonIdx = token.lastIndexOf(':');
|
|
49
|
+
if (colonIdx > 0 && !token.substring(0, colonIdx).includes(':')) {
|
|
50
|
+
const filePart = token.substring(0, colonIdx);
|
|
51
|
+
const symbolPart = token.substring(colonIdx + 1);
|
|
52
|
+
const absFile = path.resolve(root, filePart);
|
|
53
|
+
paths.push(absFile);
|
|
54
|
+
if (!symbols.has(absFile)) symbols.set(absFile, []);
|
|
55
|
+
symbols.get(absFile)!.push(symbolPart);
|
|
56
|
+
} else {
|
|
57
|
+
paths.push(path.resolve(root, token));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return { paths, symbols };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
type FlagHandler = (opts: AnalysisOptions, argv: string[], i: number) => number;
|
|
64
|
+
|
|
65
|
+
const BOOL_FLAGS: Record<
|
|
66
|
+
string,
|
|
67
|
+
(opts: AnalysisOptions, value: boolean) => void
|
|
68
|
+
> = {
|
|
69
|
+
'--json': o => {
|
|
70
|
+
o.json = true;
|
|
71
|
+
},
|
|
72
|
+
'--include-tests': o => {
|
|
73
|
+
o.includeTests = true;
|
|
74
|
+
},
|
|
75
|
+
'--emit-tree': o => {
|
|
76
|
+
o.emitTree = true;
|
|
77
|
+
},
|
|
78
|
+
'--no-tree': o => {
|
|
79
|
+
o.emitTree = false;
|
|
80
|
+
},
|
|
81
|
+
'--graph': o => {
|
|
82
|
+
o.graph = true;
|
|
83
|
+
},
|
|
84
|
+
'--semantic': o => {
|
|
85
|
+
o.semantic = true;
|
|
86
|
+
},
|
|
87
|
+
'--no-diversify': o => {
|
|
88
|
+
o.noDiversify = true;
|
|
89
|
+
},
|
|
90
|
+
'--no-cache': o => {
|
|
91
|
+
o.noCache = true;
|
|
92
|
+
},
|
|
93
|
+
'--clear-cache': o => {
|
|
94
|
+
o.clearCache = true;
|
|
95
|
+
},
|
|
96
|
+
'--graph-advanced': o => {
|
|
97
|
+
o.graphAdvanced = true;
|
|
98
|
+
},
|
|
99
|
+
'--flow': o => {
|
|
100
|
+
o.flow = true;
|
|
101
|
+
},
|
|
102
|
+
'--all': o => {
|
|
103
|
+
o.includeTests = true;
|
|
104
|
+
o.semantic = true;
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const INT_FLAGS: Record<string, keyof AnalysisOptions> = {
|
|
109
|
+
'--findings-limit': 'findingsLimit',
|
|
110
|
+
'--min-function-statements': 'minFunctionStatements',
|
|
111
|
+
'--min-flow-statements': 'minFlowStatements',
|
|
112
|
+
'--critical-complexity-threshold': 'criticalComplexityThreshold',
|
|
113
|
+
'--deep-link-topn': 'deepLinkTopN',
|
|
114
|
+
'--tree-depth': 'treeDepth',
|
|
115
|
+
'--coupling-threshold': 'couplingThreshold',
|
|
116
|
+
'--fan-in-threshold': 'fanInThreshold',
|
|
117
|
+
'--fan-out-threshold': 'fanOutThreshold',
|
|
118
|
+
'--god-module-statements': 'godModuleStatements',
|
|
119
|
+
'--god-module-exports': 'godModuleExports',
|
|
120
|
+
'--god-function-statements': 'godFunctionStatements',
|
|
121
|
+
'--god-function-mi-threshold': 'godFunctionMiThreshold',
|
|
122
|
+
'--cognitive-complexity-threshold': 'cognitiveComplexityThreshold',
|
|
123
|
+
'--barrel-symbol-threshold': 'barrelSymbolThreshold',
|
|
124
|
+
'--parameter-threshold': 'parameterThreshold',
|
|
125
|
+
'--halstead-effort-threshold': 'halsteadEffortThreshold',
|
|
126
|
+
'--maintainability-index-threshold': 'maintainabilityIndexThreshold',
|
|
127
|
+
'--any-threshold': 'anyThreshold',
|
|
128
|
+
'--flow-dup-threshold': 'flowDupThreshold',
|
|
129
|
+
'--max-recs-per-category': 'maxRecsPerCategory',
|
|
130
|
+
'--override-chain-threshold': 'overrideChainThreshold',
|
|
131
|
+
'--shotgun-threshold': 'shotgunThreshold',
|
|
132
|
+
'--secret-min-length': 'secretMinLength',
|
|
133
|
+
'--mock-threshold': 'mockThreshold',
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const FLOAT_FLAGS: Record<string, keyof AnalysisOptions> = {
|
|
137
|
+
'--secret-entropy-threshold': 'secretEntropyThreshold',
|
|
138
|
+
'--similarity-threshold': 'similarityThreshold',
|
|
139
|
+
'--sdp-min-delta': 'sdpMinDelta',
|
|
140
|
+
'--sdp-max-source-instability': 'sdpMaxSourceInstability',
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const SPECIAL_FLAGS: Record<string, FlagHandler> = {
|
|
144
|
+
'--parser': (opts, argv, i) => {
|
|
145
|
+
const next = argv[i + 1];
|
|
146
|
+
if (!['auto', 'typescript', 'tree-sitter'].includes(next)) {
|
|
147
|
+
console.error(
|
|
148
|
+
`Unsupported parser: ${next}. Use auto|typescript|tree-sitter`
|
|
149
|
+
);
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
opts.parser = next as AnalysisOptions['parser'];
|
|
153
|
+
return i + 1;
|
|
154
|
+
},
|
|
155
|
+
'--root': (opts, argv, i) => {
|
|
156
|
+
opts.root = path.resolve(argv[i + 1]);
|
|
157
|
+
return i + 1;
|
|
158
|
+
},
|
|
159
|
+
'--out': (opts, argv, i) => {
|
|
160
|
+
opts.out = argv[i + 1];
|
|
161
|
+
return i + 1;
|
|
162
|
+
},
|
|
163
|
+
'--layer-order': (opts, argv, i) => {
|
|
164
|
+
opts.layerOrder = argv[i + 1].split(',').map(s => s.trim());
|
|
165
|
+
return i + 1;
|
|
166
|
+
},
|
|
167
|
+
'--help': () => {
|
|
168
|
+
printHelp();
|
|
169
|
+
return process.exit(0) as never;
|
|
170
|
+
},
|
|
171
|
+
'-h': () => {
|
|
172
|
+
printHelp();
|
|
173
|
+
return process.exit(0) as never;
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
export function parseArgs(argv: string[]): AnalysisOptions {
|
|
178
|
+
const opts: AnalysisOptions = { ...DEFAULT_OPTS };
|
|
179
|
+
let excludeSet: Set<string> | null = null;
|
|
180
|
+
|
|
181
|
+
for (let i = 0; i < argv.length; i++) {
|
|
182
|
+
const arg = argv[i];
|
|
183
|
+
|
|
184
|
+
if (BOOL_FLAGS[arg]) {
|
|
185
|
+
BOOL_FLAGS[arg](opts, true);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (INT_FLAGS[arg]) {
|
|
190
|
+
const key = INT_FLAGS[arg];
|
|
191
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
192
|
+
(opts as any)[key] = parseNumeric(argv[++i], (DEFAULT_OPTS as any)[key]);
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (FLOAT_FLAGS[arg]) {
|
|
197
|
+
const key = FLOAT_FLAGS[arg];
|
|
198
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
199
|
+
(opts as any)[key] = parseDecimal(argv[++i], (DEFAULT_OPTS as any)[key]);
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (SPECIAL_FLAGS[arg]) {
|
|
204
|
+
i = SPECIAL_FLAGS[arg](opts, argv, i);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (arg.startsWith('--out=')) {
|
|
209
|
+
opts.out = arg.slice('--out='.length);
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (arg === '--scope' || arg.startsWith('--scope=')) {
|
|
214
|
+
const val = arg.includes('=') ? arg.split('=')[1] : argv[++i];
|
|
215
|
+
const { paths, symbols } = parseScope(val, opts.root);
|
|
216
|
+
opts.scope = paths;
|
|
217
|
+
if (symbols.size > 0) opts.scopeSymbols = symbols;
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (arg === '--features' || arg.startsWith('--features=')) {
|
|
222
|
+
const val = arg.startsWith('--features=')
|
|
223
|
+
? arg.slice('--features='.length)
|
|
224
|
+
: argv[++i];
|
|
225
|
+
opts.features = resolveCategories(val, 'feature');
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (arg === '--exclude' || arg.startsWith('--exclude=')) {
|
|
230
|
+
const val = arg.startsWith('--exclude=')
|
|
231
|
+
? arg.slice('--exclude='.length)
|
|
232
|
+
: argv[++i];
|
|
233
|
+
excludeSet = resolveCategories(val, 'exclude');
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
opts.packageRoot = path.join(opts.root, 'packages');
|
|
239
|
+
|
|
240
|
+
if (opts.features !== null && excludeSet !== null) {
|
|
241
|
+
console.error(
|
|
242
|
+
'--features and --exclude are mutually exclusive. Use one or the other.'
|
|
243
|
+
);
|
|
244
|
+
process.exit(1);
|
|
245
|
+
}
|
|
246
|
+
if (excludeSet !== null) {
|
|
247
|
+
opts.features = new Set(
|
|
248
|
+
[...ALL_CATEGORIES].filter(c => !excludeSet!.has(c))
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (opts.features !== null) {
|
|
253
|
+
const testQualityCats = new Set(PILLAR_CATEGORIES['test-quality']);
|
|
254
|
+
if ([...opts.features].some(f => testQualityCats.has(f))) {
|
|
255
|
+
opts.includeTests = true;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return opts;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function printHelp(): void {
|
|
263
|
+
console.log(`
|
|
264
|
+
Usage:
|
|
265
|
+
node scripts/index.js [options]
|
|
266
|
+
|
|
267
|
+
Options:
|
|
268
|
+
--root <path> Analyze a different repo root (default: cwd)
|
|
269
|
+
--out <path> Output directory for split report files (timestamped dir by default).
|
|
270
|
+
If path ends with .json, writes single monolithic file (legacy mode).
|
|
271
|
+
--json Print report JSON to stdout
|
|
272
|
+
--include-tests Include *.test* and *.spec* files
|
|
273
|
+
--parser <auto|typescript|tree-sitter>
|
|
274
|
+
Parser engine for extra AST metadata (default: auto)
|
|
275
|
+
--no-tree Do not write AST trees to report
|
|
276
|
+
--emit-tree Force include tree blocks
|
|
277
|
+
--graph Emit Mermaid dependency graph to .md file alongside JSON
|
|
278
|
+
--graph-advanced Enable advanced graph overlays and additional architecture findings
|
|
279
|
+
--flow Enable lightweight flow enrichment for evidence traces and cfgFlags
|
|
280
|
+
--min-function-statements N Minimum function body statement count for duplicate matching (default 6)
|
|
281
|
+
--min-flow-statements N Minimum control-flow statement count for duplicate matching (default 6)
|
|
282
|
+
--critical-complexity-threshold N
|
|
283
|
+
Complexity threshold for HIGH complexity findings and critical path weighting.
|
|
284
|
+
--findings-limit N Cap findings in the report (default: no limit)
|
|
285
|
+
--deep-link-topn N Max number of critical dependency paths to report (default 12)
|
|
286
|
+
--tree-depth N AST tree depth when tree snapshots are emitted (default 4)
|
|
287
|
+
--coupling-threshold N Ca+Ce threshold for high-coupling findings (default 15)
|
|
288
|
+
--fan-in-threshold N Fan-in threshold for god-module-coupling (default 20)
|
|
289
|
+
--fan-out-threshold N Fan-out threshold for god-module-coupling (default 15)
|
|
290
|
+
--god-module-statements N Statement threshold for god-module findings (default 500)
|
|
291
|
+
--god-module-exports N Export threshold for god-module findings (default 20)
|
|
292
|
+
--god-function-statements N Statement threshold for god-function findings (default 100)
|
|
293
|
+
--god-function-mi-threshold N MI threshold for god-function findings (default 10, fires when MI < N and LOC > 30)
|
|
294
|
+
--cognitive-complexity-threshold N
|
|
295
|
+
Cognitive complexity threshold for findings (default 15)
|
|
296
|
+
--barrel-symbol-threshold N Re-export count threshold for barrel-explosion (default 30)
|
|
297
|
+
--layer-order <layers> Comma-separated layer names for violation detection (e.g. ui,service,repository)
|
|
298
|
+
--parameter-threshold N Max function parameters before flagging (default 5)
|
|
299
|
+
--halstead-effort-threshold N Halstead effort threshold for findings (default 500000)
|
|
300
|
+
--maintainability-index-threshold N
|
|
301
|
+
MI below this triggers a finding (default 20, scale 0-100)
|
|
302
|
+
--any-threshold N Max \`any\` type usages per file before flagging (default 5)
|
|
303
|
+
--flow-dup-threshold N Min occurrences for a repeated flow to become a finding (default 3)
|
|
304
|
+
--max-recs-per-category N Max findings per category in top recommendations (default 2)
|
|
305
|
+
--scope=X,Y,Z Limit scan to specific paths, files, or functions. Comma-separated.
|
|
306
|
+
Supports file:functionName to drill into a specific function.
|
|
307
|
+
Examples: --scope=packages/octocode-mcp
|
|
308
|
+
--scope=packages/octocode-mcp/src/tools
|
|
309
|
+
--scope=packages/octocode-mcp/src/session.ts
|
|
310
|
+
--scope=packages/octocode-mcp/src/session.ts:initSession
|
|
311
|
+
--scope=packages/foo,packages/bar
|
|
312
|
+
--features=X,Y,Z Run only selected features. Accepts pillar names (architecture,
|
|
313
|
+
code-quality, dead-code, security, test-quality) or individual
|
|
314
|
+
category names. Comma-separated.
|
|
315
|
+
Examples: --features=architecture
|
|
316
|
+
--features=dead-code,cognitive-complexity
|
|
317
|
+
--features=dependency-cycle,dead-export
|
|
318
|
+
--exclude=X,Y,Z Run everything EXCEPT the given pillars or categories. Mutually
|
|
319
|
+
exclusive with --features. Same pillar/category names as --features.
|
|
320
|
+
Examples: --exclude=architecture
|
|
321
|
+
--exclude=dead-export,unsafe-any
|
|
322
|
+
--semantic Enable semantic analysis phase (TypeChecker + LanguageService).
|
|
323
|
+
Adds 14 categories: over-abstraction, concrete-dependency,
|
|
324
|
+
circular-type-dependency, unused-parameter,
|
|
325
|
+
deep-override-chain, interface-compliance, unused-import,
|
|
326
|
+
orphan-implementation, shotgun-surgery, move-to-caller,
|
|
327
|
+
narrowable-type, semantic-dead-export.
|
|
328
|
+
--override-chain-threshold N Max method override depth before flagging (default 3, requires --semantic)
|
|
329
|
+
--shotgun-threshold N Unique-file threshold for shotgun-surgery (default 8, requires --semantic)
|
|
330
|
+
--sdp-min-delta N Min instability delta for SDP violations (default 0.15)
|
|
331
|
+
--sdp-max-source-instability N Max source instability to report SDP (default 0.6)
|
|
332
|
+
--secret-entropy-threshold N Shannon entropy threshold for secret detection (default 4.5)
|
|
333
|
+
--secret-min-length N Min string length for entropy-based secret detection (default 20)
|
|
334
|
+
--similarity-threshold N Jaccard similarity threshold for near-clone detection (default 0.85)
|
|
335
|
+
--mock-threshold N Max mock/spy calls per test file (default 10)
|
|
336
|
+
--no-diversify Disable category-aware diversification when truncating findings.
|
|
337
|
+
By default, --findings-limit interleaves categories so the
|
|
338
|
+
truncated list is diverse. Use this to get pure severity ordering.
|
|
339
|
+
--no-cache Disable incremental cache; re-parse all files
|
|
340
|
+
--clear-cache Delete the analysis cache and exit (no scan)
|
|
341
|
+
--all Enable all features: --include-tests --semantic
|
|
342
|
+
--help Show this message
|
|
343
|
+
`);
|
|
344
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
|
|
5
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import * as cache from './cache.js';
|
|
8
|
+
import * as cli from './cli.js';
|
|
9
|
+
import { main } from './main.js';
|
|
10
|
+
import * as discovery from '../analysis/discovery.js';
|
|
11
|
+
import { DEFAULT_OPTS } from '../types/index.js';
|
|
12
|
+
|
|
13
|
+
function makeOptions(overrides: Partial<typeof DEFAULT_OPTS> = {}) {
|
|
14
|
+
return {
|
|
15
|
+
...DEFAULT_OPTS,
|
|
16
|
+
...overrides,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function createFixtureProject(): string {
|
|
21
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'oq-pipeline-scope-'));
|
|
22
|
+
fs.writeFileSync(
|
|
23
|
+
path.join(tmp, 'package.json'),
|
|
24
|
+
JSON.stringify({ name: 'fixture', version: '1.0.0' }),
|
|
25
|
+
'utf8'
|
|
26
|
+
);
|
|
27
|
+
const srcDir = path.join(tmp, 'src');
|
|
28
|
+
fs.mkdirSync(srcDir, { recursive: true });
|
|
29
|
+
fs.writeFileSync(
|
|
30
|
+
path.join(srcDir, 'lib.ts'),
|
|
31
|
+
[
|
|
32
|
+
'export function greet(name: string): string {',
|
|
33
|
+
' return `Hello, ${name}!`;',
|
|
34
|
+
'}',
|
|
35
|
+
'',
|
|
36
|
+
'export function farewell(name: string): string {',
|
|
37
|
+
' return `Goodbye, ${name}!`;',
|
|
38
|
+
'}',
|
|
39
|
+
].join('\n'),
|
|
40
|
+
'utf8'
|
|
41
|
+
);
|
|
42
|
+
return tmp;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
describe('pipeline main', () => {
|
|
46
|
+
afterEach(() => {
|
|
47
|
+
vi.restoreAllMocks();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('clears cache and returns early when clearCache is enabled', async () => {
|
|
51
|
+
const opts = makeOptions({ clearCache: true, root: '/tmp/repo' });
|
|
52
|
+
const parseSpy = vi.spyOn(cli, 'parseArgs').mockReturnValue(opts);
|
|
53
|
+
const clearSpy = vi.spyOn(cache, 'clearCache').mockImplementation(() => {});
|
|
54
|
+
const listSpy = vi.spyOn(discovery, 'listWorkspacePackages');
|
|
55
|
+
const errSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
56
|
+
|
|
57
|
+
await main();
|
|
58
|
+
|
|
59
|
+
expect(parseSpy).toHaveBeenCalledTimes(1);
|
|
60
|
+
expect(clearSpy).toHaveBeenCalledWith('/tmp/repo');
|
|
61
|
+
expect(errSpy).toHaveBeenCalledWith('Cache cleared.');
|
|
62
|
+
expect(listSpy).not.toHaveBeenCalled();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('exits when no packages and no root package.json exist', async () => {
|
|
66
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'oq-pipeline-empty-'));
|
|
67
|
+
const opts = makeOptions({
|
|
68
|
+
clearCache: false,
|
|
69
|
+
root: tmp,
|
|
70
|
+
packageRoot: path.join(tmp, 'packages'),
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
vi.spyOn(cli, 'parseArgs').mockReturnValue(opts);
|
|
74
|
+
vi.spyOn(discovery, 'listWorkspacePackages').mockReturnValue([]);
|
|
75
|
+
vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
76
|
+
|
|
77
|
+
const exitErr = new Error('exit-1');
|
|
78
|
+
vi.spyOn(process, 'exit').mockImplementation(((
|
|
79
|
+
code?: string | number | null
|
|
80
|
+
) => {
|
|
81
|
+
throw code === 1 ? exitErr : new Error(`unexpected-exit-${code}`);
|
|
82
|
+
}) as never);
|
|
83
|
+
|
|
84
|
+
await expect(main()).rejects.toBe(exitErr);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('exits when fallback root package.json is unreadable', async () => {
|
|
88
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'oq-pipeline-badjson-'));
|
|
89
|
+
fs.writeFileSync(path.join(tmp, 'package.json'), '{invalid-json', 'utf8');
|
|
90
|
+
const opts = makeOptions({
|
|
91
|
+
clearCache: false,
|
|
92
|
+
root: tmp,
|
|
93
|
+
packageRoot: path.join(tmp, 'packages'),
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
vi.spyOn(cli, 'parseArgs').mockReturnValue(opts);
|
|
97
|
+
vi.spyOn(discovery, 'listWorkspacePackages').mockReturnValue([]);
|
|
98
|
+
vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
99
|
+
|
|
100
|
+
const exitErr = new Error('exit-1');
|
|
101
|
+
vi.spyOn(process, 'exit').mockImplementation(((
|
|
102
|
+
code?: string | number | null
|
|
103
|
+
) => {
|
|
104
|
+
throw code === 1 ? exitErr : new Error(`unexpected-exit-${code}`);
|
|
105
|
+
}) as never);
|
|
106
|
+
|
|
107
|
+
await expect(main()).rejects.toBe(exitErr);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe('pipeline scope symbol resolution', () => {
|
|
112
|
+
afterEach(() => {
|
|
113
|
+
vi.restoreAllMocks();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('warns when --scope=file:symbol cannot resolve the symbol', async () => {
|
|
117
|
+
const tmp = createFixtureProject();
|
|
118
|
+
const absLib = path.join(tmp, 'src', 'lib.ts');
|
|
119
|
+
const scopeSymbols = new Map<string, string[]>();
|
|
120
|
+
scopeSymbols.set(absLib, ['nonExistentFunction']);
|
|
121
|
+
|
|
122
|
+
const opts = makeOptions({
|
|
123
|
+
root: tmp,
|
|
124
|
+
packageRoot: path.join(tmp, 'packages'),
|
|
125
|
+
scope: [absLib],
|
|
126
|
+
scopeSymbols,
|
|
127
|
+
json: false,
|
|
128
|
+
noCache: true,
|
|
129
|
+
emitTree: false,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
vi.spyOn(cli, 'parseArgs').mockReturnValue(opts);
|
|
133
|
+
vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
134
|
+
vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
135
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
136
|
+
|
|
137
|
+
await main();
|
|
138
|
+
|
|
139
|
+
expect(warnSpy).toHaveBeenCalledWith(
|
|
140
|
+
expect.stringContaining('symbol scope could not resolve')
|
|
141
|
+
);
|
|
142
|
+
expect(warnSpy).toHaveBeenCalledWith(
|
|
143
|
+
expect.stringContaining('nonExistentFunction')
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('does not warn when --scope=file:symbol resolves successfully', async () => {
|
|
148
|
+
const tmp = createFixtureProject();
|
|
149
|
+
const absLib = path.join(tmp, 'src', 'lib.ts');
|
|
150
|
+
const scopeSymbols = new Map<string, string[]>();
|
|
151
|
+
scopeSymbols.set(absLib, ['greet']);
|
|
152
|
+
|
|
153
|
+
const opts = makeOptions({
|
|
154
|
+
root: tmp,
|
|
155
|
+
packageRoot: path.join(tmp, 'packages'),
|
|
156
|
+
scope: [absLib],
|
|
157
|
+
scopeSymbols,
|
|
158
|
+
json: false,
|
|
159
|
+
noCache: true,
|
|
160
|
+
emitTree: false,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
vi.spyOn(cli, 'parseArgs').mockReturnValue(opts);
|
|
164
|
+
vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
165
|
+
vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
166
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
167
|
+
|
|
168
|
+
await main();
|
|
169
|
+
|
|
170
|
+
expect(warnSpy).not.toHaveBeenCalledWith(
|
|
171
|
+
expect.stringContaining('symbol scope could not resolve')
|
|
172
|
+
);
|
|
173
|
+
});
|
|
174
|
+
});
|