scip-cli 3.1.0__tar.gz → 3.2.0__tar.gz
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.
- scip_cli-3.2.0/.agents/commands/dogfood.md +15 -0
- scip_cli-3.2.0/.agents/commands/release.md +69 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/.agents/rules/agent.mdc +5 -3
- scip_cli-3.2.0/.agents/skills/new-command/SKILL.md +38 -0
- scip_cli-3.2.0/.agents/skills/sql-bench/SKILL.md +29 -0
- scip_cli-3.2.0/.agents/skills/test/SKILL.md +42 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/.gitignore +0 -1
- scip_cli-3.2.0/.pre-commit-config.yaml +10 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/CONTRIBUTING.md +2 -3
- {scip_cli-3.1.0 → scip_cli-3.2.0}/PKG-INFO +12 -5
- {scip_cli-3.1.0 → scip_cli-3.2.0}/README.md +11 -4
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/SKILL.md +19 -2
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/__init__.py +1 -1
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/__main__.py +16 -1
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/analyze/common.py +5 -0
- scip_cli-3.2.0/scip_cli/analyze/entrypoints/__init__.py +77 -0
- scip_cli-3.2.0/scip_cli/analyze/entrypoints/golang.py +28 -0
- scip_cli-3.2.0/scip_cli/analyze/entrypoints/paths.py +34 -0
- scip_cli-3.2.0/scip_cli/analyze/entrypoints/python.py +128 -0
- scip_cli-3.2.0/scip_cli/analyze/entrypoints/rust.py +49 -0
- scip_cli-3.2.0/scip_cli/analyze/entrypoints/typescript.py +143 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/analyze/file.py +52 -1
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/analyze/project.py +59 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/analyze/sections.py +22 -1
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/analyze/symbol.py +9 -1
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/cache.py +1 -1
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/commands/analyze.py +12 -3
- scip_cli-3.2.0/scip_cli/commands/query.py +66 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/discover.py +15 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/constants.py +9 -1
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/convert.py +12 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/core.py +6 -3
- scip_cli-3.2.0/scip_cli/indexing/import_mentions.py +201 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/languages.py +7 -1
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/runners.py +1 -1
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/ts_projects.py +1 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/session.py +2 -2
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/source.py +13 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/sql.py +7 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scripts/bench_incremental.py +17 -8
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scripts/bench_incremental_gate.py +18 -2
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scripts/publish.sh +15 -1
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scripts/test.sh +1 -2
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/analyze_db.py +17 -0
- scip_cli-3.2.0/tests/conftest.py +35 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/e2e_harness.py +8 -1
- scip_cli-3.2.0/tests/fixture_cache.py +113 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixture_catalog.py +8 -0
- scip_cli-3.2.0/tests/fixtures/typescript-project/bin/cli-entry.ts +5 -0
- scip_cli-3.2.0/tests/fixtures/typescript-project/bin/npm-script-only.ts +3 -0
- scip_cli-3.2.0/tests/fixtures/typescript-project/package.json +11 -0
- scip_cli-3.2.0/tests/fixtures/typescript-project/src/heuristic/classifyLeaf.test.ts +5 -0
- scip_cli-3.2.0/tests/fixtures/typescript-project/src/heuristic/classifyLeaf.ts +3 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_analyze.py +58 -3
- scip_cli-3.2.0/tests/test_analyze_live.py +282 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_cache.py +2 -2
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_discover.py +20 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_e2e.py +58 -1
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_e2e_analyze_patterns.py +37 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_exclude_globs.py +1 -13
- scip_cli-3.2.0/tests/test_import_mentions.py +25 -0
- scip_cli-3.2.0/tests/test_incremental_equivalence.py +52 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_indexer_fallback.py +26 -1
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_python_index_integration.py +9 -1
- scip_cli-3.1.0/.pre-commit-config.yaml +0 -20
- scip_cli-3.1.0/scripts/bench_incremental.sh +0 -27
- scip_cli-3.1.0/scripts/bench_incremental_gate.sh +0 -25
- scip_cli-3.1.0/tests/conftest.py +0 -25
- scip_cli-3.1.0/tests/fixtures/typescript-project/package.json +0 -5
- scip_cli-3.1.0/tests/test_analyze_live.py +0 -71
- scip_cli-3.1.0/tests/test_incremental_equivalence.py +0 -81
- {scip_cli-3.1.0 → scip_cli-3.2.0}/.agents/commands/migration-problems.md +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/.github/pull_request_template.md +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/.github/workflows/ci.yml +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/AGENTS.md +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/CODE_OF_CONDUCT.md +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/LICENSE +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/SECURITY.md +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/pyproject.toml +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/analyze/__init__.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/analyze/graph.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/analyze/live.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/analyze/targets.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/cli_args.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/commands/__init__.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/commands/code.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/commands/deps.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/commands/members.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/commands/rdeps.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/commands/refs.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/commands/reindex.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/commands/search.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/commands/skill.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/commands/symbols.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/config.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/debug.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/exclude.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/__init__.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/document_upsert.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/git_delta.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/github_npm.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/incremental.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/orchestrate.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/performance.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/postprocess.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/shard_files.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/shards.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/source_discovery.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/indexing/typescript.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/merge.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/metadata.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/output.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/paths.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/project.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/queries.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/scip_tool.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/scope.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/smoke_config.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/symbols.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/targets.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scip_cli/tsconfig.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scripts/bench.sh +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scripts/bench_fingerprint_smoke.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scripts/bench_postprocess.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scripts/build.sh +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scripts/generate_incremental_bench_fixture.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/scripts/smoke.local.example.json +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/__init__.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/bench_db.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/package.json +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/alpha/src/index.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/alpha/src/util1.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/alpha/src/util2.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/alpha/src/util3.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/alpha/tsconfig.json +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/beta/src/index.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/beta/src/util1.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/beta/src/util2.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/beta/src/util3.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/beta/tsconfig.json +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/index.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/meta.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_00.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_01.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_02.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_03.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_04.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_05.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_06.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_07.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_08.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_09.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_10.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_11.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_12.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_13.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_14.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_15.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_16.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_17.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_18.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_19.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_20.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_21.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_22.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_23.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_24.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_25.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_26.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_27.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_28.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_29.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_30.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_31.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_32.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_33.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_34.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_35.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_36.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_37.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_38.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_39.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_40.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_41.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_42.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_43.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_44.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_45.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_46.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_47.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_48.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_49.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_50.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_51.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_52.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_53.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_54.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_55.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_56.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_57.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_58.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/src/modules/module_59.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/bulk/tsconfig.json +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/gamma/src/index.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/gamma/src/util1.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/gamma/src/util2.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/gamma/src/util3.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/incremental-bench/packages/gamma/tsconfig.json +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/__tests__/fixtureOnly.spec.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/app/handler.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/config.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/consumer.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/dead.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/domain/i18n/en.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/domain/i18n/index.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/domain/i18n/useLocale.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/domain/labels/index.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/events/streamTypes.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/gateway/index.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/helper.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/hooks/useHookA.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/hooks/useHookB.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/hooks/useItems.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/index.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/integrations/inferenceClient.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/lib/handler.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/loaders/useInference.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/models/MutationAggregate.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/pages/panelPage.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/rules/applyRule.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/types/a.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/types/b.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/ui/Button.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/ui/LazyPanel.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/ui/buttonConsumer.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/ui/menuModule.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/user.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/widget.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/src/widgets/OrphanWidget.ts +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/fixtures/typescript-project/tsconfig.json +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/incremental_equivalence.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/perf_util.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_analyze_graph.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_analyze_perf.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_bench_queries.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_composability.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_config.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_document_upsert.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_e2e_perf.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_git_delta.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_incremental_shards.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_index_batching.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_index_performance.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_index_prune.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_indexer_env.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_indexer_failure_message.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_merge.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_metadata.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_multi_symbol.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_pure_functions.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_qualified_symbols.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_reindex.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_scip_tool.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_scope.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_shard_files.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_source_discovery.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_sql.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_symbols_freq.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_targets.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_tsconfig.py +0 -0
- {scip_cli-3.1.0 → scip_cli-3.2.0}/tests/test_typescript_projects.py +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Dogfood analyze on this repo
|
|
2
|
+
|
|
3
|
+
Human-invoked pass before broad review. From repo root with editable `scip-cli` on PATH:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
scip-cli reindex
|
|
7
|
+
scip-cli analyze --limit 25
|
|
8
|
+
scip-cli analyze --priority high --limit 25
|
|
9
|
+
scip-cli analyze scip_cli --limit 15
|
|
10
|
+
scip-cli analyze scip_cli/queries.py --limit 20
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Interpret README § *Finding easy wins with analyze* (cycles → dead exports → same-file → stale types). Fix or extend `analyze` per `agent.mdc` § Analyze feedback loop before spawning review subagents.
|
|
14
|
+
|
|
15
|
+
Do not commit unless the user asks.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
argument-hint: "[major | minor | patch]"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Release scip-cli (tag + GitHub)
|
|
6
|
+
|
|
7
|
+
Bump level: **`$ARGUMENTS`** — must be exactly `major`, `minor`, or `patch`. Compute the next semver from `scip_cli/__init__.py` (same rules as `scripts/publish.sh`: patch +1; minor +1 and patch 0; major +1 and minor/patch 0). Tag and release **`vX.Y.Z`** for that computed version.
|
|
8
|
+
|
|
9
|
+
## Commit messages (this repo)
|
|
10
|
+
|
|
11
|
+
- **Day-to-day:** sentence case, verb first — e.g. `Add entrypoint fixtures`, `Pass indexer binary name to npx fallback`. **Not** Conventional Commits (`feat(scope):`, `chore:`, …).
|
|
12
|
+
- **Version bump commit:** subject **only** `vX.Y.Z` (same string as the tag), e.g. `v3.2.0`.
|
|
13
|
+
|
|
14
|
+
Do not commit, tag, or push unless the user invoked this release command.
|
|
15
|
+
|
|
16
|
+
## Preflight
|
|
17
|
+
|
|
18
|
+
1. Repo root; working tree clean before the bump commit.
|
|
19
|
+
2. `./scripts/test.sh`
|
|
20
|
+
3. If `$ARGUMENTS` is missing or not `major`/`minor`/`patch`, stop and ask.
|
|
21
|
+
4. After bump, `git rev-parse "vX.Y.Z"` must fail (tag must not exist yet).
|
|
22
|
+
|
|
23
|
+
## Bump version
|
|
24
|
+
|
|
25
|
+
Use the bump logic in `scripts/publish.sh` (or run that script’s Python block with `BUMP_LEVEL=$ARGUMENTS`). Then:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git add scip_cli/__init__.py
|
|
29
|
+
git commit -m "vX.Y.Z"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Tag (non-interactive — never open the editor)
|
|
33
|
+
|
|
34
|
+
Always pass **both** tag name and message on the command line:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git tag -a "vX.Y.Z" -m "vX.Y.Z"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Do **not** run bare `git tag vX.Y.Z` (Git may open an editor for the annotation).
|
|
41
|
+
|
|
42
|
+
Push branch and tag:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
git push origin HEAD "vX.Y.Z"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## GitHub release (`gh`)
|
|
49
|
+
|
|
50
|
+
Read `~/.claude/skills/gh/references/releases.md`. Use the repo scripts:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
GH_SCRIPTS="${GH_SCRIPTS:-$HOME/.claude/skills/gh/scripts}"
|
|
54
|
+
REPO="$(gh repo view --json nameWithOwner -q .nameWithOwner 2>/dev/null || echo flesler/scip-cli)"
|
|
55
|
+
|
|
56
|
+
"$GH_SCRIPTS/release-notes.sh" X.Y.Z --install '```bash
|
|
57
|
+
pip install scip-cli=={{VERSION}}
|
|
58
|
+
```'
|
|
59
|
+
|
|
60
|
+
"$GH_SCRIPTS/sync-github-release.sh" "$REPO" X.Y.Z \
|
|
61
|
+
--install '```bash
|
|
62
|
+
pip install scip-cli=={{VERSION}}
|
|
63
|
+
```' \
|
|
64
|
+
--execute
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Do not** run `gh release create` by hand unless the user rejects the script path. **Do not** upload PyPI (`twine`) or run full `./scripts/publish.sh` unless the user explicitly asks.
|
|
68
|
+
|
|
69
|
+
Report: bump level, new version, tag pushed, release URL, PyPI skipped unless requested.
|
|
@@ -7,6 +7,8 @@ alwaysApply: true
|
|
|
7
7
|
|
|
8
8
|
**Work from repo root.** CLI usage, flags, and user gotchas: `scip-cli skill` (source: `scip_cli/SKILL.md`). Read once per task — do not duplicate SKILL here.
|
|
9
9
|
|
|
10
|
+
**Cursor:** Skills in `.cursor/skills/` (`test`, `sql-bench`, `new-command`) — folder name = frontmatter `name:`; agent reads when relevant. Slash commands in `.cursor/commands/` only for workflows you invoke (`dogfood`, `migration-problems`, `release`); never pair the same workflow as both.
|
|
11
|
+
|
|
10
12
|
**Almost always:** bare `scip-cli` on PATH must be **this checkout live** (`pip install -e ".[dev]"`). All examples use `scip-cli` — never `.venv/bin/scip-cli`, `python -m scip_cli`, or other paths. Only swap to PyPI briefly to smoke-test a release.
|
|
11
13
|
|
|
12
14
|
## Bootstrap
|
|
@@ -34,11 +36,11 @@ Node.js + `npx` required for integration tests (`scip-typescript`). Optional: `S
|
|
|
34
36
|
|Full suite|`pytest`|
|
|
35
37
|
|E2e loop|`pytest tests/test_e2e.py tests/test_e2e_analyze_patterns.py`|
|
|
36
38
|
|Lint / format|`ruff check .` / `ruff format .`|
|
|
37
|
-
|Typecheck|`basedpyright scip_cli/`|
|
|
39
|
+
|Typecheck|`basedpyright --warnings scip_cli/ scripts/`|
|
|
38
40
|
|
|
39
|
-
Pre-commit
|
|
41
|
+
Pre-commit, CI, and publish: `./scripts/test.sh` (same gate). No pre-push hook. E2e before commit on command changes.
|
|
40
42
|
|
|
41
|
-
**Use `scripts/test.sh`** before committing to catch all issues (lint, format, types, tests). This matches what pre-commit
|
|
43
|
+
**Use `scripts/test.sh`** before committing to catch all issues (lint, format, types, tests). This matches what pre-commit and CI run.
|
|
42
44
|
|
|
43
45
|
## Improving this repo (do this before review subagents)
|
|
44
46
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: new-command
|
|
3
|
+
description: Read when adding or changing a scip-cli CLI subcommand.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# New or changed CLI command
|
|
7
|
+
|
|
8
|
+
User-facing reference lives in `scip_cli/SKILL.md` + `README.md` (must match `scip_cli/__main__.py` flags). Run `scip-cli skill` to verify dump.
|
|
9
|
+
|
|
10
|
+
## Checklist
|
|
11
|
+
|
|
12
|
+
1. **`scip_cli/commands/<name>.py`** — `main(args)`; thin handler. Use `session.setup()` for index DB unless the command is `reindex` / `skill`.
|
|
13
|
+
2. **`scip_cli/__main__.py`** — import; `add_parser`; wire `dispatch["<name>"] = <module>.main`.
|
|
14
|
+
3. **Shared flags** — reuse `scip_cli/cli_args.py` (`add_path_argument`, `add_limit_argument`, …) when siblings use them.
|
|
15
|
+
4. **SQL** — keep queries in `scip_cli/queries.py` or `scip_cli/analyze/`, not fat command modules.
|
|
16
|
+
5. **Docs** — quick-guide row + `### <name>` section in `scip_cli/SKILL.md`; bullet in README § Commands.
|
|
17
|
+
6. **Tests** — `tests/test_e2e.py` (or `test_e2e_analyze_patterns.py` for analyze-only); add `scip_cli.commands.<name>.setup` to `tests/e2e_harness.py` `COMMAND_SETUP_PATHS`.
|
|
18
|
+
7. **Verify** — follow skill `test`; run narrowed pytest then e2e loop.
|
|
19
|
+
|
|
20
|
+
## Patterns
|
|
21
|
+
|
|
22
|
+
- **Read-only DB:** `db, project_root = setup()` in `try` / `finally: db.close()`. Connection already has `configure_read_connection` via `get_db`.
|
|
23
|
+
- **Errors:** raise `RuntimeError` or let `sqlite3.Error` bubble — `__main__.main` maps them to stderr + exit code.
|
|
24
|
+
- **Output:** stdout = records; stderr = warnings (match existing commands).
|
|
25
|
+
|
|
26
|
+
## Map
|
|
27
|
+
|
|
28
|
+
|Concern|Path|
|
|
29
|
+
|---|---|
|
|
30
|
+
|Entry / argparse|`scip_cli/__main__.py`|
|
|
31
|
+
|Handlers|`scip_cli/commands/`|
|
|
32
|
+
|Index open|`scip_cli/session.py`, `scip_cli/indexing/core.py`|
|
|
33
|
+
|User skill install|`scip-cli skill <path>` copies `scip_cli/SKILL.md`|
|
|
34
|
+
|
|
35
|
+
## Cursor repo conventions
|
|
36
|
+
|
|
37
|
+
- **Skills** (`.cursor/skills/<name>/`, frontmatter `name:` = folder name): agent reads when the task matches — e.g. `test`, `sql-bench`, `new-command`.
|
|
38
|
+
- **Commands** (`.cursor/commands/`): only workflows **you** invoke with slash — e.g. `dogfood`, `migration-problems`. Never duplicate the same workflow as a skill and a command.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sql-bench
|
|
3
|
+
description: Read when changing queries.py, analyze SQL, symbols SQL, or sql.py.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SQL / query performance
|
|
7
|
+
|
|
8
|
+
Small fixture DB hides regressions on 40MB+ indexes. CI perf tests only catch gross mistakes on the tiny project.
|
|
9
|
+
|
|
10
|
+
## Required before commit
|
|
11
|
+
|
|
12
|
+
Touching `scip_cli/queries.py`, `scip_cli/analyze/*`, `scip_cli/symbols.py` SQL, or `scip_cli/sql.py`:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
scripts/bench.sh --baseline # once per change series
|
|
16
|
+
# … edit …
|
|
17
|
+
scripts/bench.sh --compare
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Synthetic scale: `tests/bench_db.py` + `tests/test_bench_queries.py`. Lines `BENCH:<name>:<ms>`; compare table ratio >1.0 = regression.
|
|
21
|
+
|
|
22
|
+
## Correctness vs speed
|
|
23
|
+
|
|
24
|
+
- Behavior / SCIP shapes → fixture e2e (skill `test`).
|
|
25
|
+
- Graph plumbing only → `analyze_db` unit tests.
|
|
26
|
+
|
|
27
|
+
## Optional: real cached index
|
|
28
|
+
|
|
29
|
+
Replace `<project-slug>` under `~/.cache/scip-cli/projects/` — snippet in `agent.mdc` § Large cached index benchmark.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test
|
|
3
|
+
description: Read when running or writing scip-cli tests (pytest, e2e, CI parity).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# scip-cli tests
|
|
7
|
+
|
|
8
|
+
Repo root only. Bootstrap: `.cursor/rules/agent.mdc` (editable install, Node for fixture index).
|
|
9
|
+
|
|
10
|
+
## Pick a suite
|
|
11
|
+
|
|
12
|
+
|Goal|Command|
|
|
13
|
+
|---|---|
|
|
14
|
+
|Pre-commit / CI / publish|`scripts/test.sh`|
|
|
15
|
+
|Full|`pytest`|
|
|
16
|
+
|CLI + fixture index|`pytest tests/test_e2e.py tests/test_e2e_analyze_patterns.py`|
|
|
17
|
+
|One class / test|`pytest tests/test_e2e.py::TestQuery -q`|
|
|
18
|
+
|Analyze unit / graph|`pytest tests/test_analyze_graph.py tests/test_analyze.py`|
|
|
19
|
+
|SQL perf (not correctness)|`scripts/bench.sh` — see skill `sql-bench`|
|
|
20
|
+
|
|
21
|
+
`scripts/test.sh` uses `.venv/bin/{ruff,basedpyright,pytest}`; create venv + `pip install -e ".[dev]"` if missing.
|
|
22
|
+
|
|
23
|
+
## E2e rules
|
|
24
|
+
|
|
25
|
+
- In-process only: `tests/e2e_harness.py` (`CliRunner`, `run_cli`) patches `scip_cli.commands.<cmd>.setup` — **never** subprocess `scip-cli` in tests.
|
|
26
|
+
- **Never** call `reindex` in e2e (mutates `~/.cache/scip-cli`).
|
|
27
|
+
- Session fixture `indexed_fixture` indexes `tests/fixtures/typescript-project/` once (real `scip-typescript`).
|
|
28
|
+
- Stable symbols/paths: add constants to `tests/fixture_catalog.py`; import in tests — do not hardcode fixture paths in test bodies.
|
|
29
|
+
- New CLI command: append `scip_cli.commands.<cmd>.setup` to `COMMAND_SETUP_PATHS` in `e2e_harness.py`.
|
|
30
|
+
|
|
31
|
+
## Fixture vs in-memory DB
|
|
32
|
+
|
|
33
|
+
|Need|Layer|
|
|
34
|
+
|---|---|
|
|
35
|
+
|SCIP symbol shapes, analyze false positives, CLI output|Fixture e2e (`test_e2e*.py`)|
|
|
36
|
+
|Tarjan, section wiring, one-off SQL plumbing|`tests/analyze_db.py` + `test_analyze_graph.py`|
|
|
37
|
+
|
|
38
|
+
Prefer fixture e2e for indexer-dependent behavior. Details: `agent.mdc` § TDD.
|
|
39
|
+
|
|
40
|
+
## After command / flag changes
|
|
41
|
+
|
|
42
|
+
Run e2e loop at minimum before commit; `scripts/test.sh` before push.
|
|
@@ -48,11 +48,10 @@ cd scip-cli
|
|
|
48
48
|
# Install with dev dependencies
|
|
49
49
|
pip install -e ".[dev]"
|
|
50
50
|
|
|
51
|
-
# Install pre-commit
|
|
51
|
+
# Install pre-commit hook (same command as CI — no pre-push hook)
|
|
52
52
|
pre-commit install
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
pytest
|
|
54
|
+
./scripts/test.sh
|
|
56
55
|
|
|
57
56
|
# Run linter
|
|
58
57
|
ruff check .
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: scip-cli
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.2.0
|
|
4
4
|
Summary: Fast code intelligence via SCIP indexes
|
|
5
5
|
Project-URL: Homepage, https://github.com/flesler/scip-cli
|
|
6
6
|
Author: Ariel Flesler
|
|
@@ -26,6 +26,8 @@ Description-Content-Type: text/markdown
|
|
|
26
26
|
|
|
27
27
|
Python CLI for AI agents. Queries SCIP indexes for precise refs, definitions, and repo health analysis — TypeScript/JavaScript, Python, Go, Rust.
|
|
28
28
|
|
|
29
|
+
**Related (optional):** [scip-atlas](https://github.com/flesler/scip-atlas) builds `atlas.db` (git paths, commits, owners) from this cache's `index.db`. [scip-atlas-web](https://github.com/flesler/scip-atlas-web) packs both into a slim DB and a single-file browser explorer. You do not need them for CLI or agent workflows.
|
|
30
|
+
|
|
29
31
|
## Why
|
|
30
32
|
|
|
31
33
|
AI agents waste tokens on grep and file scanning. scip-cli gives them precise, type-aware code navigation in milliseconds — and `analyze` surfaces dead code, cycles, and coupling so agents (and humans) can fix real problems fast.
|
|
@@ -91,7 +93,7 @@ python -m venv .venv && source .venv/bin/activate
|
|
|
91
93
|
pip install -e ".[dev]"
|
|
92
94
|
```
|
|
93
95
|
|
|
94
|
-
Tests and lint: `pytest`, `ruff check .`, `basedpyright scip_cli/` from
|
|
96
|
+
Tests and lint: `scripts/test.sh` (same as CI and pre-commit), or run `pytest`, `ruff check .`, `basedpyright --warnings scip_cli/ scripts/` from `.venv`.
|
|
95
97
|
|
|
96
98
|
### 2. Install prerequisites (optional)
|
|
97
99
|
|
|
@@ -155,6 +157,7 @@ scip-cli <command> [arguments]
|
|
|
155
157
|
- `rdeps <file>` - Find files that depend on a file (`--path`)
|
|
156
158
|
- `deps <symbol|file>` - Find outbound dependencies (what a symbol or file calls) (`--path`, `--paths-only`)
|
|
157
159
|
- `members <symbol>` - List members of a class/interface (`--path`)
|
|
160
|
+
- `query <sql>` - SQL against the project index (`--format tsv|csv|json`, default tsv; read-only unless `--write`)
|
|
158
161
|
- `analyze [target]` - SQL health dashboards (`--limit`, `--per-check-limit`, `--priority`, `--check`, `--include-tests`). No target: project-wide; directory or file path; symbol name. See [Finding easy wins with `analyze`](#finding-easy-wins-with-analyze).
|
|
159
162
|
- `reindex` - Force re-indexing (`--path`, `--tsconfig`, `--exclude`, `--fresh`, `--no-incremental`; incremental by default in git TS repos)
|
|
160
163
|
- `skill [path]` - Install or dump the SKILL.md
|
|
@@ -192,6 +195,10 @@ scip-cli members Widget
|
|
|
192
195
|
# Project health dashboard (or: scip-cli analyze src/foo.ts / scip-cli analyze greet)
|
|
193
196
|
scip-cli analyze
|
|
194
197
|
|
|
198
|
+
# List index tables / columns (read-only SQL)
|
|
199
|
+
scip-cli query "SELECT name FROM sqlite_schema WHERE type='table' ORDER BY 1"
|
|
200
|
+
scip-cli query "PRAGMA table_info(global_symbols)"
|
|
201
|
+
|
|
195
202
|
# Install skill file
|
|
196
203
|
scip-cli skill ~/.claude/skills/scip-cli/SKILL.md
|
|
197
204
|
```
|
|
@@ -227,7 +234,7 @@ scip-cli deps greet --paths-only | sort -u
|
|
|
227
234
|
6. Compacts the database after each reindex (`VACUUM` + WAL checkpoint)
|
|
228
235
|
7. Subsequent queries are SQLite lookups against that cache (not re-indexing)
|
|
229
236
|
|
|
230
|
-
**Incremental reindex (TypeScript, v3.0+):** plain `scip-cli reindex` in a git worktree is incremental by default — reuses unchanged tsconfig shards via `shards/manifest.json` (`git_commit` + per-shard `tsconfig_digest`). Dirty shards reindex only changed files (git delta → importer closure → fork `--files`) and upsert into the live `index.db`. Use `--no-incremental` or `--fresh` for a full rebuild; `--unversioned` and non-git projects always full-reindex. Bench locally with `scripts/bench_incremental_gate.
|
|
237
|
+
**Incremental reindex (TypeScript, v3.0+):** plain `scip-cli reindex` in a git worktree is incremental by default — reuses unchanged tsconfig shards via `shards/manifest.json` (`git_commit` + per-shard `tsconfig_digest`). Dirty shards reindex only changed files (git delta → importer closure → fork `--files`) and upsert into the live `index.db`. Use `--no-incremental` or `--fresh` for a full rebuild; `--unversioned` and non-git projects always full-reindex. Bench locally with `python scripts/bench_incremental_gate.py --branch fixture`.
|
|
231
238
|
|
|
232
239
|
## Configuration
|
|
233
240
|
|
|
@@ -303,7 +310,7 @@ Sections are tagged `[high]`, `[medium]`, `[low]` and listed in that order.
|
|
|
303
310
|
|---|---|---|
|
|
304
311
|
|**high**|Cycles, dead exports, dead files, stale types (unreferenced is omitted when dead exports is on)|Nuke or fix cycles; delete unused; `_` prefix|
|
|
305
312
|
|**medium**|Same-file only, change surface (file target)|Module-private by usage|
|
|
306
|
-
|**low**|
|
|
313
|
+
|**low**|Single-importer files (`[test-only]` when sole importer is tests), test-only consumers, coupling, bottlenecks, hotspots|Noisy on Python (index omits many same-file calls); verify with `rg`|
|
|
307
314
|
|
|
308
315
|
Use `--priority high` for a quick gate; `--priority high,medium` adds context. File drill-down adds change surface and unused imports.
|
|
309
316
|
|
|
@@ -329,7 +336,7 @@ scip-cli analyze scip_cli --limit 15 # directory: scoped project +
|
|
|
329
336
|
|
|
330
337
|
**Defaults:** project-wide and directory analyze skip `tests/`, `*.test.*`, `*.spec.*`, `conftest.py`, and `__tests__/`. Pass `--include-tests` to include them. File-target analyze always includes that file.
|
|
331
338
|
|
|
332
|
-
**Limits:** "Dead export" means no cross-file mentions in the index — not unreachable code. Same-file private helpers are expected. Re-run `reindex` after large changes; the index is a snapshot.
|
|
339
|
+
**Limits:** "Dead export" means no cross-file mentions in the index — not unreachable code. Same-file private helpers are expected. Shebang lines and manifest entrypoints (`package.json` main/bin/scripts with dist→src mapping for TypeScript; Python `pyproject`/`setup.py`/`setup.cfg` scripts) are excluded from project-level dead files and dead exports. Re-run `reindex` after large changes; the index is a snapshot.
|
|
333
340
|
|
|
334
341
|
## Performance
|
|
335
342
|
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
Python CLI for AI agents. Queries SCIP indexes for precise refs, definitions, and repo health analysis — TypeScript/JavaScript, Python, Go, Rust.
|
|
7
7
|
|
|
8
|
+
**Related (optional):** [scip-atlas](https://github.com/flesler/scip-atlas) builds `atlas.db` (git paths, commits, owners) from this cache's `index.db`. [scip-atlas-web](https://github.com/flesler/scip-atlas-web) packs both into a slim DB and a single-file browser explorer. You do not need them for CLI or agent workflows.
|
|
9
|
+
|
|
8
10
|
## Why
|
|
9
11
|
|
|
10
12
|
AI agents waste tokens on grep and file scanning. scip-cli gives them precise, type-aware code navigation in milliseconds — and `analyze` surfaces dead code, cycles, and coupling so agents (and humans) can fix real problems fast.
|
|
@@ -70,7 +72,7 @@ python -m venv .venv && source .venv/bin/activate
|
|
|
70
72
|
pip install -e ".[dev]"
|
|
71
73
|
```
|
|
72
74
|
|
|
73
|
-
Tests and lint: `pytest`, `ruff check .`, `basedpyright scip_cli/` from
|
|
75
|
+
Tests and lint: `scripts/test.sh` (same as CI and pre-commit), or run `pytest`, `ruff check .`, `basedpyright --warnings scip_cli/ scripts/` from `.venv`.
|
|
74
76
|
|
|
75
77
|
### 2. Install prerequisites (optional)
|
|
76
78
|
|
|
@@ -134,6 +136,7 @@ scip-cli <command> [arguments]
|
|
|
134
136
|
- `rdeps <file>` - Find files that depend on a file (`--path`)
|
|
135
137
|
- `deps <symbol|file>` - Find outbound dependencies (what a symbol or file calls) (`--path`, `--paths-only`)
|
|
136
138
|
- `members <symbol>` - List members of a class/interface (`--path`)
|
|
139
|
+
- `query <sql>` - SQL against the project index (`--format tsv|csv|json`, default tsv; read-only unless `--write`)
|
|
137
140
|
- `analyze [target]` - SQL health dashboards (`--limit`, `--per-check-limit`, `--priority`, `--check`, `--include-tests`). No target: project-wide; directory or file path; symbol name. See [Finding easy wins with `analyze`](#finding-easy-wins-with-analyze).
|
|
138
141
|
- `reindex` - Force re-indexing (`--path`, `--tsconfig`, `--exclude`, `--fresh`, `--no-incremental`; incremental by default in git TS repos)
|
|
139
142
|
- `skill [path]` - Install or dump the SKILL.md
|
|
@@ -171,6 +174,10 @@ scip-cli members Widget
|
|
|
171
174
|
# Project health dashboard (or: scip-cli analyze src/foo.ts / scip-cli analyze greet)
|
|
172
175
|
scip-cli analyze
|
|
173
176
|
|
|
177
|
+
# List index tables / columns (read-only SQL)
|
|
178
|
+
scip-cli query "SELECT name FROM sqlite_schema WHERE type='table' ORDER BY 1"
|
|
179
|
+
scip-cli query "PRAGMA table_info(global_symbols)"
|
|
180
|
+
|
|
174
181
|
# Install skill file
|
|
175
182
|
scip-cli skill ~/.claude/skills/scip-cli/SKILL.md
|
|
176
183
|
```
|
|
@@ -206,7 +213,7 @@ scip-cli deps greet --paths-only | sort -u
|
|
|
206
213
|
6. Compacts the database after each reindex (`VACUUM` + WAL checkpoint)
|
|
207
214
|
7. Subsequent queries are SQLite lookups against that cache (not re-indexing)
|
|
208
215
|
|
|
209
|
-
**Incremental reindex (TypeScript, v3.0+):** plain `scip-cli reindex` in a git worktree is incremental by default — reuses unchanged tsconfig shards via `shards/manifest.json` (`git_commit` + per-shard `tsconfig_digest`). Dirty shards reindex only changed files (git delta → importer closure → fork `--files`) and upsert into the live `index.db`. Use `--no-incremental` or `--fresh` for a full rebuild; `--unversioned` and non-git projects always full-reindex. Bench locally with `scripts/bench_incremental_gate.
|
|
216
|
+
**Incremental reindex (TypeScript, v3.0+):** plain `scip-cli reindex` in a git worktree is incremental by default — reuses unchanged tsconfig shards via `shards/manifest.json` (`git_commit` + per-shard `tsconfig_digest`). Dirty shards reindex only changed files (git delta → importer closure → fork `--files`) and upsert into the live `index.db`. Use `--no-incremental` or `--fresh` for a full rebuild; `--unversioned` and non-git projects always full-reindex. Bench locally with `python scripts/bench_incremental_gate.py --branch fixture`.
|
|
210
217
|
|
|
211
218
|
## Configuration
|
|
212
219
|
|
|
@@ -282,7 +289,7 @@ Sections are tagged `[high]`, `[medium]`, `[low]` and listed in that order.
|
|
|
282
289
|
|---|---|---|
|
|
283
290
|
|**high**|Cycles, dead exports, dead files, stale types (unreferenced is omitted when dead exports is on)|Nuke or fix cycles; delete unused; `_` prefix|
|
|
284
291
|
|**medium**|Same-file only, change surface (file target)|Module-private by usage|
|
|
285
|
-
|**low**|
|
|
292
|
+
|**low**|Single-importer files (`[test-only]` when sole importer is tests), test-only consumers, coupling, bottlenecks, hotspots|Noisy on Python (index omits many same-file calls); verify with `rg`|
|
|
286
293
|
|
|
287
294
|
Use `--priority high` for a quick gate; `--priority high,medium` adds context. File drill-down adds change surface and unused imports.
|
|
288
295
|
|
|
@@ -308,7 +315,7 @@ scip-cli analyze scip_cli --limit 15 # directory: scoped project +
|
|
|
308
315
|
|
|
309
316
|
**Defaults:** project-wide and directory analyze skip `tests/`, `*.test.*`, `*.spec.*`, `conftest.py`, and `__tests__/`. Pass `--include-tests` to include them. File-target analyze always includes that file.
|
|
310
317
|
|
|
311
|
-
**Limits:** "Dead export" means no cross-file mentions in the index — not unreachable code. Same-file private helpers are expected. Re-run `reindex` after large changes; the index is a snapshot.
|
|
318
|
+
**Limits:** "Dead export" means no cross-file mentions in the index — not unreachable code. Same-file private helpers are expected. Shebang lines and manifest entrypoints (`package.json` main/bin/scripts with dist→src mapping for TypeScript; Python `pyproject`/`setup.py`/`setup.cfg` scripts) are excluded from project-level dead files and dead exports. Re-run `reindex` after large changes; the index is a snapshot.
|
|
312
319
|
|
|
313
320
|
## Performance
|
|
314
321
|
|
|
@@ -19,6 +19,7 @@ TypeScript/JavaScript, Python, Go, Rust — not GraphQL, CSS, or other files. Ru
|
|
|
19
19
|
|What does this use?|`deps target`|Outbound deps (symbol or file)|
|
|
20
20
|
|Class members|`members Class`|Methods/fields + line ranges|
|
|
21
21
|
|Health / risk|`analyze`|SQL dashboard — project, dir, file, or symbol|
|
|
22
|
+
|Raw SQL|`query "SELECT …"`|Rows from `index.db` (`--format tsv|csv|json`)|
|
|
22
23
|
|
|
23
24
|
Default `--limit` is **10** on query commands unless noted. Stdout = records; stderr = warnings/progress. Pipe with `--paths-only` / `--names-only`.
|
|
24
25
|
|
|
@@ -103,6 +104,22 @@ members [--limit N] [--path PATH] [--names-only] <symbol>
|
|
|
103
104
|
|
|
104
105
|
`start:end kind name`. Prefix match under parent; missing ranges filled from source when needed.
|
|
105
106
|
|
|
107
|
+
### query
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
query [--format tsv|csv|json] [--write] <sql> [...]
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
SQL against the cached project `index.db`. **Read-only by default** (`PRAGMA query_only`); `--write` allows mutations (commits after each statement). Default `--format` is **tsv** (header row + tab-separated values). `csv` and `json` (array of objects) are also supported. Prefer `reindex` over hand-editing the cache.
|
|
114
|
+
|
|
115
|
+
Introspect schema (SQLite catalog + `PRAGMA`):
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
query "SELECT name FROM sqlite_schema WHERE type='table' ORDER BY 1"
|
|
119
|
+
query "PRAGMA table_info(mentions)"
|
|
120
|
+
query "SELECT m.name AS table_name, p.name AS column_name, p.type FROM sqlite_schema m JOIN pragma_table_info(m.name) p WHERE m.type='table' AND m.name NOT LIKE 'sqlite_%' ORDER BY 1, p.cid"
|
|
121
|
+
```
|
|
122
|
+
|
|
106
123
|
### analyze
|
|
107
124
|
|
|
108
125
|
```bash
|
|
@@ -116,9 +133,9 @@ analyze [--limit N] [--per-check-limit N] [--path PATH] [--include-tests] [--pri
|
|
|
116
133
|
|file|File dashboards + top symbols by external consumers|
|
|
117
134
|
|symbol|Pressure, consumers, deps, affected|
|
|
118
135
|
|
|
119
|
-
Priority **high → medium → low**. `--limit` = total finding rows (default 20); headers/truncation don't count. `--per-check-limit` caps each section. Agents: `--limit 40 --per-check-limit 5`. `--priority high` or `high,medium` (`1`/`2`/`3`) skips lower tiers. `--check NAME` (repeatable/comma) ANDs with priority.
|
|
136
|
+
Priority **high → medium → low**. `[high]` cycles, dead exports, dead files, stale types (project unreferenced omitted when dead exports runs; file unreferenced omitted when dead-in-file runs). `[medium]` same-file-only, change surface (file). `[low]` single-importer files (`[test-only]` tag), test-only consumers, coupling, bottlenecks, hotspots. `--limit` = total finding rows (default 20); headers/truncation don't count. `--per-check-limit` caps each section. Agents: `--limit 40 --per-check-limit 5`. `--priority high` or `high,medium` (`1`/`2`/`3`) skips lower tiers. `--check NAME` (repeatable/comma) ANDs with priority.
|
|
120
137
|
|
|
121
|
-
**Easy wins:** cycles, dead exports, dead files (production). Stale types = types with no external refs. Dead = no cross-file refs in index, not `vulture`. Empty `rdeps` on a hit is often a SCIP miss — verify with `rg -F STEM` (basename in `(...)`, same-file hits ignored).
|
|
138
|
+
**Easy wins:** cycles, dead exports, dead files (production). Stale types = types with no external refs. Dead = no cross-file refs in index, not `vulture`. Shebang plus manifest entrypoints (`package.json` main/bin/scripts, dist→src mapping; each Python package for pyproject/setup/setup.cfg) are never project-level dead files/exports. `single_importer_files` rows with only test importers are tagged `[test-only]`. File-scoped `analyze path/to/cli.ts` still reports unused symbols in that file. Empty `rdeps` on a hit is often a SCIP miss — verify with `rg -F STEM` (basename in `(...)`, same-file hits ignored).
|
|
122
139
|
|
|
123
140
|
### reindex
|
|
124
141
|
|
|
@@ -18,7 +18,7 @@ from .cli_args import (
|
|
|
18
18
|
add_paths_only_argument,
|
|
19
19
|
positive_int,
|
|
20
20
|
)
|
|
21
|
-
from .commands import analyze, code, deps, members, rdeps, refs, reindex, search, skill, symbols
|
|
21
|
+
from .commands import analyze, code, deps, members, query, rdeps, refs, reindex, search, skill, symbols
|
|
22
22
|
from .symbols import SymbolKind
|
|
23
23
|
|
|
24
24
|
# Set up debug logging based on SCIP_CLI_DEBUG env var
|
|
@@ -122,6 +122,20 @@ def main() -> None:
|
|
|
122
122
|
members_parser.add_argument("symbol", help="Symbol name")
|
|
123
123
|
|
|
124
124
|
# skill
|
|
125
|
+
query_parser = subparsers.add_parser("query", help="Run SQL against the project index database")
|
|
126
|
+
query_parser.add_argument("sql", nargs="+", help="SQL to execute")
|
|
127
|
+
query_parser.add_argument(
|
|
128
|
+
"--format",
|
|
129
|
+
choices=("tsv", "csv", "json"),
|
|
130
|
+
default="tsv",
|
|
131
|
+
help="Output format (default: tsv)",
|
|
132
|
+
)
|
|
133
|
+
query_parser.add_argument(
|
|
134
|
+
"--write",
|
|
135
|
+
action="store_true",
|
|
136
|
+
help="Allow INSERT/UPDATE/DELETE (default: read-only)",
|
|
137
|
+
)
|
|
138
|
+
|
|
125
139
|
skill_parser = subparsers.add_parser("skill", help="Install or dump the scip-cli SKILL.md")
|
|
126
140
|
skill_parser.add_argument("path", nargs="?", help="Optional file path to write to (creates dirs)")
|
|
127
141
|
|
|
@@ -234,6 +248,7 @@ def main() -> None:
|
|
|
234
248
|
"rdeps": rdeps.main,
|
|
235
249
|
"deps": deps.main,
|
|
236
250
|
"members": members.main,
|
|
251
|
+
"query": query.main,
|
|
237
252
|
"skill": skill.main,
|
|
238
253
|
"analyze": analyze.main,
|
|
239
254
|
"reindex": reindex.main,
|
|
@@ -161,6 +161,11 @@ def is_test_path(relative_path: str) -> bool:
|
|
|
161
161
|
return name == "conftest.py"
|
|
162
162
|
|
|
163
163
|
|
|
164
|
+
def is_package_init_module(relative_path: str) -> bool:
|
|
165
|
+
"""Python package __init__.py — import surface, not a nuke candidate for dead_files."""
|
|
166
|
+
return relative_path.replace("\\", "/").endswith("__init__.py")
|
|
167
|
+
|
|
168
|
+
|
|
164
169
|
def is_dynamic_loader_path(relative_path: str) -> bool:
|
|
165
170
|
"""True for migration files typically loaded by filename; SCIP has no import edge."""
|
|
166
171
|
p = relative_path.replace("\\", "/").lower()
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""CLI entrypoints that SCIP never links via import edges."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from contextvars import ContextVar
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from ...project import Language, detect_language
|
|
9
|
+
from ...source import file_has_shebang
|
|
10
|
+
from . import golang as golang_entrypoints
|
|
11
|
+
from . import python as python_entrypoints
|
|
12
|
+
from . import rust as rust_entrypoints
|
|
13
|
+
from . import typescript as typescript_entrypoints
|
|
14
|
+
from .paths import canonical_rel
|
|
15
|
+
|
|
16
|
+
_DECLARED_LOADERS = {
|
|
17
|
+
Language.TYPESCRIPT: typescript_entrypoints.declared_entrypoint_paths,
|
|
18
|
+
Language.PYTHON: python_entrypoints.declared_entrypoint_paths,
|
|
19
|
+
Language.GOLANG: golang_entrypoints.declared_entrypoint_paths,
|
|
20
|
+
Language.RUST: rust_entrypoints.declared_entrypoint_paths,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class EntrypointIndex:
|
|
25
|
+
"""Declared CLI entrypoints (manifest + shebang) for one analyze pass."""
|
|
26
|
+
|
|
27
|
+
_root: Path | None
|
|
28
|
+
_declared_paths: set[str]
|
|
29
|
+
_shebang_cache: dict[str, bool]
|
|
30
|
+
|
|
31
|
+
def __init__(self, project_root: Path | None) -> None:
|
|
32
|
+
self._root = project_root.resolve() if project_root is not None else None
|
|
33
|
+
self._declared_paths = set()
|
|
34
|
+
self._shebang_cache = {}
|
|
35
|
+
if self._root is not None:
|
|
36
|
+
lang = detect_language(self._root)
|
|
37
|
+
if lang is not None:
|
|
38
|
+
loader = _DECLARED_LOADERS.get(lang)
|
|
39
|
+
if loader is not None:
|
|
40
|
+
self._declared_paths.update(loader(self._root))
|
|
41
|
+
|
|
42
|
+
def is_entrypoint(self, relative_path: str) -> bool:
|
|
43
|
+
if self._root is None:
|
|
44
|
+
return False
|
|
45
|
+
canonical = canonical_rel(relative_path)
|
|
46
|
+
if canonical in self._declared_paths:
|
|
47
|
+
return True
|
|
48
|
+
if python_entrypoints.is_python_entrypoint_file(relative_path):
|
|
49
|
+
return True
|
|
50
|
+
if canonical in self._shebang_cache:
|
|
51
|
+
return self._shebang_cache[canonical]
|
|
52
|
+
has_shebang = file_has_shebang(self._root, relative_path)
|
|
53
|
+
self._shebang_cache[canonical] = has_shebang
|
|
54
|
+
return has_shebang
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
_CURRENT: ContextVar[EntrypointIndex | None] = ContextVar("scip_cli_entrypoint_index", default=None)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def bind_entrypoints(project_root: Path | str | None) -> object:
|
|
61
|
+
root = Path(project_root) if project_root is not None else None
|
|
62
|
+
return _CURRENT.set(EntrypointIndex(root))
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def reset_entrypoints(token) -> None:
|
|
66
|
+
_CURRENT.reset(token)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def is_entrypoint_path(relative_path: str) -> bool:
|
|
70
|
+
index = _CURRENT.get()
|
|
71
|
+
if index is None:
|
|
72
|
+
return False
|
|
73
|
+
return index.is_entrypoint(relative_path)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def entrypoints_bound() -> bool:
|
|
77
|
+
return _CURRENT.get() is not None
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Entrypoints for Go modules (main.go and cmd/*/main.go)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from ...discover import discover_golang_modules
|
|
8
|
+
from .paths import path_in_repo
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def declared_entrypoint_paths(project_root: Path) -> set[str]:
|
|
12
|
+
repo_root = project_root.resolve()
|
|
13
|
+
paths: set[str] = set()
|
|
14
|
+
for mod_rel in discover_golang_modules(repo_root):
|
|
15
|
+
mod_root = repo_root / mod_rel
|
|
16
|
+
if (mod_root / "main.go").is_file():
|
|
17
|
+
paths.add(path_in_repo(repo_root, mod_rel, "main.go"))
|
|
18
|
+
cmd_dir = mod_root / "cmd"
|
|
19
|
+
if not cmd_dir.is_dir():
|
|
20
|
+
continue
|
|
21
|
+
for child in cmd_dir.iterdir():
|
|
22
|
+
if not child.is_dir():
|
|
23
|
+
continue
|
|
24
|
+
main_go = child / "main.go"
|
|
25
|
+
if main_go.is_file():
|
|
26
|
+
rel = main_go.relative_to(mod_root).as_posix()
|
|
27
|
+
paths.add(path_in_repo(repo_root, mod_rel, rel))
|
|
28
|
+
return paths
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Shared path normalization for entrypoint manifests."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def canonical_rel(relative_path: str) -> str:
|
|
9
|
+
return relative_path.replace("\\", "/").lstrip("./")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def path_in_repo(_repo_root: Path, package_rel: Path, path_in_package: str) -> str:
|
|
13
|
+
"""Map a path relative to a package dir to a repo-relative path."""
|
|
14
|
+
rel = path_in_package.replace("\\", "/").lstrip("./")
|
|
15
|
+
if not package_rel.parts:
|
|
16
|
+
return canonical_rel(rel)
|
|
17
|
+
prefix = package_rel.as_posix().strip("/")
|
|
18
|
+
return canonical_rel(f"{prefix}/{rel}")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def normalize_path_under_root(project_root: Path, raw: str, *, extensions: tuple[str, ...]) -> str | None:
|
|
22
|
+
text = raw.strip().strip("'\"")
|
|
23
|
+
if not text:
|
|
24
|
+
return None
|
|
25
|
+
if not any(text.endswith(ext) for ext in extensions):
|
|
26
|
+
return None
|
|
27
|
+
root = project_root.resolve()
|
|
28
|
+
path = Path(text)
|
|
29
|
+
if path.is_absolute():
|
|
30
|
+
try:
|
|
31
|
+
return canonical_rel(str(path.resolve().relative_to(root)))
|
|
32
|
+
except ValueError:
|
|
33
|
+
return None
|
|
34
|
+
return canonical_rel(text)
|