codegraph-brain 0.23.1__tar.gz → 0.23.3__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.
- codegraph_brain-0.23.3/.github/workflows/mcp-registry.yml +81 -0
- codegraph_brain-0.23.3/.release-please-manifest.json +3 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/CHANGELOG.md +15 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/PKG-INFO +1 -1
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/how-to/MCP_REFERENCE.md +37 -12
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/pyproject.toml +1 -1
- codegraph_brain-0.23.3/scripts/mcp_registry_gate.sh +101 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/server.json +2 -2
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/api/mcp_server.py +39 -14
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/cli.py +53 -30
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/render/graph_json.py +22 -8
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_cli.py +108 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_graph_json.py +15 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_mcp_tool_schemas.py +27 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/uv.lock +1 -1
- codegraph_brain-0.23.1/.release-please-manifest.json +0 -3
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/.claude-plugin/marketplace.json +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/.gitattributes +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/.github/test-count-baseline +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/.github/workflows/autodoc.yml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/.github/workflows/ci.yml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/.github/workflows/guardian.yml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/.github/workflows/pr-title.yml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/.github/workflows/release-please.yml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/.gitignore +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/.pre-commit-config.yaml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/.python-version +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/CLAUDE.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/CONTRIBUTING.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/LICENSE +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/Makefile +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/PRIVACY.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/README.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/CURATION.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/calibration.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/experiments/246-cross-vendor/README.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/experiments/246-cross-vendor/free-nemotron-quota-cutoff.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/experiments/401-evidence/README.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/experiments/401-evidence/pr-399-control-rows.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/experiments/401-evidence/pr-399-recording.json +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/experiments/401-evidence/pr-399-treatment-rows.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/experiments/407-no-checker-appeal/README.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/experiments/407-no-checker-appeal/pr-399-control-directive-rows.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/experiments/407-no-checker-appeal/pr-399-control-prohibition-rows.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/pr-122.yaml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/pr-140.yaml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/pr-141.yaml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/pr-142.yaml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/pr-143.yaml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/pr-144.yaml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/pr-278.yaml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/pr-313.yaml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/guardian/results.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian/README.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian/cal_dot_com.json +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian/discourse.json +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian/grafana.json +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian/keycloak.json +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian/sentry.json +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian-judged.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian-p3-judged-run1.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian-p3-judged-run1.jsonl.corrupted-backup +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian-p3-run1.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian-p3-run2.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian-p3-run3.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian-plan.json +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian-repeat-judged.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian-repeat-reviews.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/benchmarks/martian-reviews.jsonl +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/data/.gitkeep +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/AUDIT.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/CASE_STUDY.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/GUARDIAN_LOCAL_BENCH.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/GUARDIAN_REMOTE_OLLAMA.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/architecture/HOW_IT_WORKS.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/architecture/ONTOLOGY.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/architecture/PATTERNS_AND_TRIADS.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/architecture/SELF_PORTRAIT.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/architecture/diagrams/pipeline_flow.mermaid +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/architecture/health_badge.json +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/assets/.gitignore +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/assets/cgis-app-avatar.png +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/assets/cgis-app-avatar.svg +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/assets/generate_avatar.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/examples/.gitkeep +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/how-to/AGENT_ONBOARDING.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/how-to/CLI_USAGE.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/lab-notes/2026-06-11-chunked-review-negative-result.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/ontology/.gitkeep +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/ontology/core.yaml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/ontology/domains.yaml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/ontology/patterns.yaml +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/ontology/tolerances.lock +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/plans/2026-09-09-graph-freshness.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-09-domain-pattern-fingerprint-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-09-pattern-alphabet-motif-basis-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-10-guardian-sprint-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-11-fastapi-di-edges-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-11-guardian-chunked-review-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-11-guardian-chunker-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-11-mcp-drift-validate-fqn-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-11-resolver-split-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-11-symbol-import-edges-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-12-drift-empty-domains-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-12-gate-semantics-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-12-init-ontology-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-12-release-please-ci-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-13-suggest-packages-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-06-13-tangle-anti-pattern-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-07-29-guardian-skeptic-scoring-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-07-30-cgis-fractal-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-07-30-cgis-fractal-plan.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-07-30-chunk-source-filter-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-07-30-chunk-source-filter-plan.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-07-30-genai-client-close-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-07-30-genai-client-close-plan.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-07-30-guardian-precision-bench-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-07-30-guardian-precision-bench-plan.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-07-30-guardian-timeout-retry-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-07-30-guardian-timeout-retry-plan.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-07-31-finder-bug-class-taxonomy.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-08-01-aura-autoevolution-poc.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-08-11-guardian-code-review-bench.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-08-14-review-fingerprint-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-09-05-annotation-graph-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/2026-09-09-graph-freshness-design.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/BLUEPRINT.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/PRD.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/TDD.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-09-fingerprint-drift.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-10-guardian-context-skeptic-inline.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-10-guardian-structured-findings-bench.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-10-motif-basis-part-b.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-10-unified-pattern-alphabet.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-11-fastapi-di-edges.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-11-guardian-chunked-review.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-11-guardian-chunker.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-11-mcp-drift-validate-fqn.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-11-resolver-split.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-12-drift-empty-domains.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-12-gate-semantics.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-12-init-ontology.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-12-release-please-ci.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-12-symbol-import-edges.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-06-13-suggest-packages.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-07-29-guardian-skeptic-scoring.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-08-14-review-fingerprint.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-09-05-annotation-graph-pr1.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/docs/specs/plans/2026-09-05-annotation-graph-pr2.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/glama.json +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/main.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/plugin/.claude-plugin/plugin.json +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/plugin/.mcp.json +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/plugin/README.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/plugin/skills/cgis/SKILL.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/plugin/skills/ingest/SKILL.md +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/release-please-config.json +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/backfill_calibration_fingerprint.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/backfill_review_fingerprint.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/check_pytest_raises.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/check_test_count.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/colab_bench.sh +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/gen_ideal_graph.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/generate_health.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/generate_mcp_ref.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/generate_schema_docs.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/guardian_bench.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/guardian_calibrate.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/guardian_martian.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/guardian_replay_skeptic.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/guardian_review.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/inject_architecture_graph.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/ollama_visitor.sh +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/probe_closure_gap.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/probe_tier_ladder.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/recordings_from_corpus.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/scripts/skeptic_arms.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/__init__.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/__main__.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/api/.gitkeep +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/api/__init__.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/core/.gitkeep +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/core/coverage.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/core/freshness.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/core/generated.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/core/js_globals.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/core/models.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/core/paths.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/extractors/.gitkeep +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/extractors/_python_annotations.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/extractors/_python_ast.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/extractors/_python_classes.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/extractors/_python_functions.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/extractors/_python_imports.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/extractors/_python_types.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/extractors/_typescript_bindings.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/extractors/base.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/extractors/python_extractor.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/extractors/registry.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/extractors/typescript_extractor.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/__init__.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/axes.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/bench.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/calibrate.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/chunked.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/chunker.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/collector.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/core.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/diff_index.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/evidence.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/findings.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/github_poster.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/martian.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/metrics.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/prompts.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/providers/__init__.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/providers/base.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/providers/gemini.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/providers/mistral.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/providers/ollama.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/providers/openrouter.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/recording.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/render.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/review_fingerprint.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/runner.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/guardian/skeptic.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/pipeline.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/py.typed +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/analysis/__init__.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/analysis/analyzer.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/analysis/anomaly.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/analysis/cohesion.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/analysis/health.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/analysis/suggest_service.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/context/__init__.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/context/audit.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/context/context_service.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/context/orphans.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/context/prompt.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/context/snippet.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/drift/__init__.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/drift/_scc.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/drift/drift.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/drift/drift_service.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/drift/fingerprint.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/drift/fractal.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/drift/ontology_init.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/drift/quotient.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/drift/triads.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/engine.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/fqn.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/render/__init__.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/render/mermaid.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/query/render/metrics.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/resolver/.gitkeep +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/resolver/__init__.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/resolver/engine.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/resolver/indices.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/resolver/js_builtins.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/resolver/symbols.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/resolver/uplift.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/storage/.gitkeep +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/src/cgis/storage/sqlite_store.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/integration/.gitkeep +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/self_parsing/.gitkeep +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/self_parsing/__init__.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/self_parsing/conftest.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/self_parsing/test_annotation_calibration.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/self_parsing/test_architecture.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/self_parsing/test_drift.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/self_parsing/test_fractal.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/self_parsing/test_init_ontology_roundtrip.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/self_parsing/test_receiver_resolution.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/self_parsing/test_self_parse.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/self_parsing/test_self_parse_ts.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/self_parsing/test_suggest.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/.gitkeep +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/conftest.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/guardian_stubs.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/review_path_inventory.txt +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test___main__.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_analyzer.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_annotation_edges.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_audit.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_backfill_calibration_fingerprint.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_backfill_review_fingerprint.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_check_pytest_raises.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_check_test_count.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_cohesion.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_context_service.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_di_acceptance.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_drift.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_drift_service.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_extractor_registry.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_fingerprint.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_fqn.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_fractal.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_freshness.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_gen_ideal_graph.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_generate_mcp_ref.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_generated.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_axes.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_bench.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_bench_script.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_calibrate.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_calibrate_script.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_chunked.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_chunker.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_collector.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_core.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_diff_index.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_evidence.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_findings.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_martian.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_martian_script.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_martian_union.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_metrics.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_mistral_sampling.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_ollama_sampling.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_ollama_truncation.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_openrouter.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_poster.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_providers.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_providers_name.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_recording.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_render.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_replay_skeptic.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_review_script.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_runner.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_salvage.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_guardian_skeptic.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_health_scorer.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_import_acceptance.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_inject_architecture_graph.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_mcp_server.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_mermaid.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_metrics.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_models.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_name_load_positions.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_ontology_compliance.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_ontology_init.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_orphans.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_paths.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_patterns_yaml.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_pipeline.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_pipeline_incremental_symbols.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_prompt.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_python_annotations.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_python_extractor.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_query_coverage.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_quotient.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_recordings_from_corpus.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_resolver.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_resolver_indices.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_resolver_js_builtins.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_resolver_language_scope.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_resolver_symbols.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_review_fingerprint_closure.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_review_fingerprint_contract.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_review_fingerprint_digest.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_review_fingerprint_record.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_self_types.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_skeptic_arms.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_snippet.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_sqlite_store.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_suggest_service.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_temperature_source.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_triads.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_typescript_extractor.py +0 -0
- {codegraph_brain-0.23.1 → codegraph_brain-0.23.3}/tests/unit/test_uplift.py +0 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
name: Publish to MCP Registry
|
|
2
|
+
|
|
3
|
+
# A separate workflow file, not a job in release-please.yml: PyPI trusted
|
|
4
|
+
# publishing is bound to that file, so nothing here can mint a PyPI upload token
|
|
5
|
+
# whatever the publisher's environment restriction is (#471).
|
|
6
|
+
#
|
|
7
|
+
# Runs after every Release Please run and publishes only a tagged version the
|
|
8
|
+
# registry does not list yet (scripts/mcp_registry_gate.sh), so ordinary pushes
|
|
9
|
+
# to main are no-ops.
|
|
10
|
+
#
|
|
11
|
+
# A failed Release Please run (PyPI publish or relock) skips this workflow: the
|
|
12
|
+
# red run is the signal. Recover with "Re-run failed jobs" there, or dispatch
|
|
13
|
+
# this workflow on main.
|
|
14
|
+
on:
|
|
15
|
+
workflow_run:
|
|
16
|
+
workflows: ["Release Please"]
|
|
17
|
+
types: [completed]
|
|
18
|
+
branches: [main]
|
|
19
|
+
workflow_dispatch:
|
|
20
|
+
|
|
21
|
+
permissions: {}
|
|
22
|
+
|
|
23
|
+
concurrency:
|
|
24
|
+
group: mcp-registry
|
|
25
|
+
cancel-in-progress: false
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
publish:
|
|
29
|
+
name: Publish server.json
|
|
30
|
+
# Dispatch only from main, so an older branch can't publish its own server.json.
|
|
31
|
+
# The repository check is defence in depth: Release Please never runs for forks.
|
|
32
|
+
if: >-
|
|
33
|
+
(github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main') ||
|
|
34
|
+
(github.event.workflow_run.conclusion == 'success' &&
|
|
35
|
+
github.event.workflow_run.head_repository.full_name == github.repository)
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
permissions:
|
|
38
|
+
contents: read
|
|
39
|
+
# OIDC for `mcp-publisher login github-oidc`: no stored registry secret.
|
|
40
|
+
id-token: write
|
|
41
|
+
env:
|
|
42
|
+
# Pinned and checksum-verified: this job holds a registry identity, so it must
|
|
43
|
+
# not run whatever `releases/latest` happens to be. Bump both together; a
|
|
44
|
+
# binary too old for the registry fails login with "invalid audience".
|
|
45
|
+
MCP_PUBLISHER_VERSION: "1.8.1"
|
|
46
|
+
MCP_PUBLISHER_SHA256: a06c9096dcb9727c13555b6be26c7effa707b01f06a4c561ba7a3635443cf2cc
|
|
47
|
+
steps:
|
|
48
|
+
- name: Checkout the released commit
|
|
49
|
+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
50
|
+
with:
|
|
51
|
+
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
|
|
52
|
+
persist-credentials: false
|
|
53
|
+
|
|
54
|
+
- name: Decide whether to publish
|
|
55
|
+
id: gate
|
|
56
|
+
run: bash scripts/mcp_registry_gate.sh check >> "$GITHUB_OUTPUT"
|
|
57
|
+
|
|
58
|
+
- name: Wait for the version on PyPI
|
|
59
|
+
if: steps.gate.outputs.publish == 'true'
|
|
60
|
+
run: bash scripts/mcp_registry_gate.sh wait-pypi
|
|
61
|
+
|
|
62
|
+
- name: Install mcp-publisher
|
|
63
|
+
if: steps.gate.outputs.publish == 'true'
|
|
64
|
+
run: |
|
|
65
|
+
set -euo pipefail
|
|
66
|
+
url="https://github.com/modelcontextprotocol/registry/releases/download/v${MCP_PUBLISHER_VERSION}/mcp-publisher_linux_amd64.tar.gz"
|
|
67
|
+
curl --proto '=https' --tlsv1.2 -fsSL "$url" -o mcp-publisher.tar.gz
|
|
68
|
+
echo "${MCP_PUBLISHER_SHA256} mcp-publisher.tar.gz" | sha256sum --check --strict
|
|
69
|
+
tar -xzf mcp-publisher.tar.gz mcp-publisher
|
|
70
|
+
|
|
71
|
+
- name: Validate server.json
|
|
72
|
+
if: steps.gate.outputs.publish == 'true'
|
|
73
|
+
run: ./mcp-publisher validate
|
|
74
|
+
|
|
75
|
+
- name: Log in with GitHub OIDC
|
|
76
|
+
if: steps.gate.outputs.publish == 'true'
|
|
77
|
+
run: ./mcp-publisher login github-oidc
|
|
78
|
+
|
|
79
|
+
- name: Publish
|
|
80
|
+
if: steps.gate.outputs.publish == 'true'
|
|
81
|
+
run: ./mcp-publisher publish
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.23.3](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.23.2...codegraph-brain-v0.23.3) (2026-09-17)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Documentation
|
|
7
|
+
|
|
8
|
+
* auto-sync architecture graph and MCP reference ([#480](https://github.com/zaebee/codegraph-brain/issues/480)) ([5379cce](https://github.com/zaebee/codegraph-brain/commit/5379cce927b5fade5e2371503a0cd9e1f8041fc7))
|
|
9
|
+
* **mcp:** say when to use each overlapping graph tool ([#477](https://github.com/zaebee/codegraph-brain/issues/477)) ([f33d764](https://github.com/zaebee/codegraph-brain/commit/f33d764ebdf217359964347aaa1137dc18ced513))
|
|
10
|
+
|
|
11
|
+
## [0.23.2](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.23.1...codegraph-brain-v0.23.2) (2026-09-17)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* **cli:** impact/trace list each neighbour once, JSON each edge once ([#475](https://github.com/zaebee/codegraph-brain/issues/475)) ([9c93b4b](https://github.com/zaebee/codegraph-brain/commit/9c93b4ba5748f99fe2aeb43d698c9d9628e6295a))
|
|
17
|
+
|
|
3
18
|
## [0.23.1](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.23.0...codegraph-brain-v0.23.1) (2026-09-17)
|
|
4
19
|
|
|
5
20
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: codegraph-brain
|
|
3
|
-
Version: 0.23.
|
|
3
|
+
Version: 0.23.3
|
|
4
4
|
Summary: Semantic code graph for AI agents — deterministic FQN resolution, impact analysis and architectural drift gates, exposed over MCP.
|
|
5
5
|
Project-URL: Homepage, https://github.com/zaebee/codegraph-brain
|
|
6
6
|
Project-URL: Repository, https://github.com/zaebee/codegraph-brain
|
|
@@ -7,9 +7,16 @@
|
|
|
7
7
|
|
|
8
8
|
## `cgis_analyze_impact`
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Upstream subgraph of one FQN: everything that reaches it within ``depth`` hops.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Every edge type counts — callers, but also importers, subclasses, type
|
|
13
|
+
references, DI dependents and the enclosing class or file — so this answers
|
|
14
|
+
"what breaks if I change X?". For what X depends on use
|
|
15
|
+
``cgis_trace_flow``; for only the members of a module or class,
|
|
16
|
+
``cgis_get_structure``; for a source-included brief to read before editing
|
|
17
|
+
one symbol, ``cgis_context``.
|
|
18
|
+
|
|
19
|
+
``output_format="mermaid"`` (default)
|
|
13
20
|
returns a diagram; ``"json"`` returns a joinable ``{root, nodes, edges,
|
|
14
21
|
coverage}`` payload with real FQNs — letting an agent compute set
|
|
15
22
|
differences (e.g. "which route handlers never reach ``verify_ownership``?")
|
|
@@ -22,14 +29,14 @@ Analyse transitive upstream callers of a specific FQN.
|
|
|
22
29
|
| :--- | :--- | :---: | :--- |
|
|
23
30
|
| `fqn` | `string` | ✓ | Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up. |
|
|
24
31
|
| `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
|
|
25
|
-
| `depth` | `integer` | | Maximum edge hops upstream. Every edge type counts as a hop —
|
|
32
|
+
| `depth` | `integer` | | Maximum edge hops upstream. Every edge type counts as a hop — callers, importers, subclasses, type references, DI dependents and the enclosing class or file all appear alongside each other. |
|
|
26
33
|
| `output_format` | `string` | | "mermaid" for a diagram, or "json" for a payload with real FQNs (case-insensitive). Any other value returns an error. |
|
|
27
34
|
|
|
28
35
|
---
|
|
29
36
|
|
|
30
37
|
## `cgis_audit_reachability`
|
|
31
38
|
|
|
32
|
-
Reachability/authorization audit — which sources never reach a checkpoint
|
|
39
|
+
Reachability/authorization audit — which sources never reach a checkpoint.
|
|
33
40
|
|
|
34
41
|
The headline use is **IDOR/authz coverage**: list every route handler that does
|
|
35
42
|
NOT transitively reach an ownership check. Reachability follows behavioral edges
|
|
@@ -56,7 +63,14 @@ Reachability/authorization audit — which sources never reach a checkpoint (#17
|
|
|
56
63
|
|
|
57
64
|
## `cgis_context`
|
|
58
65
|
|
|
59
|
-
|
|
66
|
+
Prompt-ready brief on one FQN: its source, class, direct callers and callees.
|
|
67
|
+
|
|
68
|
+
Call this before editing a symbol, instead of reading its files. It follows
|
|
69
|
+
calls only, one hop by default. Source is included when the file is found
|
|
70
|
+
(see ``source_root``), and the domain when the graph was tagged with one.
|
|
71
|
+
For a multi-hop subgraph
|
|
72
|
+
over every edge type without source, use ``cgis_trace_flow`` (downstream) or
|
|
73
|
+
``cgis_analyze_impact`` (upstream).
|
|
60
74
|
|
|
61
75
|
Returns an XML-tagged prompt — the focal node's source, its enclosing class,
|
|
62
76
|
its architectural domain boundary, direct callers (upstream ripple) and
|
|
@@ -115,7 +129,7 @@ Report per-domain architectural drift against declared ideal patterns.
|
|
|
115
129
|
|
|
116
130
|
## `cgis_find_orphans`
|
|
117
131
|
|
|
118
|
-
Classes nothing in production builds, extends or names — dead-code candidates
|
|
132
|
+
Classes nothing in production builds, extends or names — dead-code candidates.
|
|
119
133
|
|
|
120
134
|
Finds classes that no test, type checker or linter flags, because each is
|
|
121
135
|
still imported somewhere: a package re-export keeps a class importable long
|
|
@@ -209,10 +223,13 @@ Report the motif census across the repository's structural tiers.
|
|
|
209
223
|
|
|
210
224
|
## `cgis_get_structure`
|
|
211
225
|
|
|
212
|
-
|
|
226
|
+
Members of a module or class: the classes, functions and methods it contains.
|
|
213
227
|
|
|
214
|
-
|
|
215
|
-
|
|
228
|
+
Follows containment (CONTAINS/DECLARES) only, so no call or import appears.
|
|
229
|
+
For how the code connects use ``cgis_trace_flow`` (what it depends on) or
|
|
230
|
+
``cgis_analyze_impact`` (what depends on it).
|
|
231
|
+
|
|
232
|
+
Matches the CLI ``structure`` command. ``output_format="mermaid"`` (default) returns a
|
|
216
233
|
diagram of the hierarchy rooted at the given FQN; ``"json"`` returns the
|
|
217
234
|
joinable ``{root, nodes, edges}`` payload with real FQNs.
|
|
218
235
|
|
|
@@ -275,7 +292,7 @@ Propose a starter patterns.yaml from the measured graph (read-only).
|
|
|
275
292
|
|
|
276
293
|
## `cgis_metrics`
|
|
277
294
|
|
|
278
|
-
Whole-graph architectural metrics — coupling bottlenecks
|
|
295
|
+
Whole-graph architectural metrics — coupling bottlenecks, God classes, PageRank.
|
|
279
296
|
|
|
280
297
|
Returns JSON ``{bottlenecks, god_classes, critical}`` computed with vectorized
|
|
281
298
|
DuckDB aggregations over the whole graph (fan-in/fan-out coupling,
|
|
@@ -331,7 +348,15 @@ Suggest sub-package boundaries for a package from its dependency communities.
|
|
|
331
348
|
|
|
332
349
|
## `cgis_trace_flow`
|
|
333
350
|
|
|
334
|
-
|
|
351
|
+
Downstream subgraph of one FQN: everything it reaches within ``depth`` hops.
|
|
352
|
+
|
|
353
|
+
Every edge type counts — calls, imports, inheritance, DI dependencies,
|
|
354
|
+
references, and containment (so from a module or class the first hop includes
|
|
355
|
+
its own members) — so this answers "what does X depend on?". For what depends
|
|
356
|
+
on X use
|
|
357
|
+
``cgis_analyze_impact``; for only the members of a module or class,
|
|
358
|
+
``cgis_get_structure``; for a source-included brief to read before editing
|
|
359
|
+
one symbol, ``cgis_context``.
|
|
335
360
|
|
|
336
361
|
``output_format="mermaid"`` (default) returns a human-readable diagram;
|
|
337
362
|
``"json"`` returns a joinable ``{root, nodes, edges, coverage}`` payload
|
|
@@ -346,7 +371,7 @@ Trace the execution call-graph starting from a specific FQN downwards.
|
|
|
346
371
|
| :--- | :--- | :---: | :--- |
|
|
347
372
|
| `fqn` | `string` | ✓ | Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up. |
|
|
348
373
|
| `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
|
|
349
|
-
| `depth` | `integer` | | Maximum edge hops downstream. Every edge type counts as a hop —
|
|
374
|
+
| `depth` | `integer` | | Maximum edge hops downstream. Every edge type counts as a hop — calls, imports, inheritance, DI dependencies, references and containment — so from a module or class the first hop is mostly its own members and imports. |
|
|
350
375
|
| `output_format` | `string` | | "mermaid" for a diagram, or "json" for a payload with real FQNs (case-insensitive). Any other value returns an error. |
|
|
351
376
|
|
|
352
377
|
---
|
|
@@ -7,7 +7,7 @@ packages = ["src/cgis"]
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "codegraph-brain"
|
|
10
|
-
version = "0.23.
|
|
10
|
+
version = "0.23.3"
|
|
11
11
|
description = "Semantic code graph for AI agents — deterministic FQN resolution, impact analysis and architectural drift gates, exposed over MCP."
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
requires-python = ">=3.12"
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Decide whether server.json's version should be published to the MCP Registry,
|
|
3
|
+
# and wait until PyPI can back it (#471).
|
|
4
|
+
#
|
|
5
|
+
# scripts/mcp_registry_gate.sh check → prints publish=true|false (for $GITHUB_OUTPUT)
|
|
6
|
+
# scripts/mcp_registry_gate.sh wait-pypi → blocks until PyPI serves the version
|
|
7
|
+
#
|
|
8
|
+
# `check` is what makes the workflow safe to run after *every* Release Please run:
|
|
9
|
+
# only a tagged release that the registry does not list yet is published, so a
|
|
10
|
+
# docs push to main is a no-op and a re-run never double-publishes.
|
|
11
|
+
#
|
|
12
|
+
# Every lookup fails closed. `publish=false` is printed only on a definite answer
|
|
13
|
+
# (no such tag, version already listed); a network error or an unexpected
|
|
14
|
+
# response exits non-zero, because a silently skipped release is exactly what
|
|
15
|
+
# this automation exists to prevent.
|
|
16
|
+
#
|
|
17
|
+
# `wait-pypi` exists because the registry verifies ownership by fetching
|
|
18
|
+
# pypi.org/pypi/<pkg>/<version>/json and looking for the mcp-name marker, and a
|
|
19
|
+
# fresh upload is not always visible there straight away (0.23.0 and 0.23.1 both
|
|
20
|
+
# failed a `pip install` for a few minutes after the publish job went green).
|
|
21
|
+
set -euo pipefail
|
|
22
|
+
|
|
23
|
+
REGISTRY="${MCP_REGISTRY_URL:-https://registry.modelcontextprotocol.io}"
|
|
24
|
+
PYPI="${PYPI_URL:-https://pypi.org}"
|
|
25
|
+
TAG_PREFIX="${TAG_PREFIX:-codegraph-brain-v}"
|
|
26
|
+
WAIT_SECONDS="${WAIT_SECONDS:-600}"
|
|
27
|
+
POLL_SECONDS="${POLL_SECONDS:-15}"
|
|
28
|
+
|
|
29
|
+
fail() {
|
|
30
|
+
echo "::error::$*" >&2
|
|
31
|
+
exit 1
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
read_field() {
|
|
35
|
+
local filter="$1" label="$2" value
|
|
36
|
+
value=$(jq -r "${filter} // empty" server.json) || fail "server.json is not valid JSON."
|
|
37
|
+
[[ -n "$value" ]] || fail "server.json has no ${label} (${filter})."
|
|
38
|
+
printf '%s' "$value"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
name=$(read_field .name "server name")
|
|
42
|
+
version=$(read_field .version "version")
|
|
43
|
+
package=$(read_field 'first(.packages[]? | select(.registryType == "pypi") | .identifier)' "PyPI package")
|
|
44
|
+
|
|
45
|
+
check() {
|
|
46
|
+
local tag="refs/tags/${TAG_PREFIX}${version}" rc=0
|
|
47
|
+
git ls-remote --exit-code --tags origin "$tag" >/dev/null || rc=$?
|
|
48
|
+
case "$rc" in
|
|
49
|
+
0) ;;
|
|
50
|
+
2)
|
|
51
|
+
echo "No tag ${TAG_PREFIX}${version}: not a release, nothing to publish." >&2
|
|
52
|
+
echo "publish=false"
|
|
53
|
+
return
|
|
54
|
+
;;
|
|
55
|
+
*) fail "git ls-remote for ${tag} failed (exit ${rc}); cannot tell whether this is a release." ;;
|
|
56
|
+
esac
|
|
57
|
+
|
|
58
|
+
# The status alone is not enough: a moved API also answers 404, and a proxy can
|
|
59
|
+
# answer 200 with nothing. Each answer must also carry the body that means it.
|
|
60
|
+
local encoded body status
|
|
61
|
+
encoded=$(jq -rn --arg n "$name" '$n | @uri')
|
|
62
|
+
body=$(mktemp)
|
|
63
|
+
status=$(curl -sS -o "$body" -w '%{http_code}' \
|
|
64
|
+
"${REGISTRY}/v0/servers/${encoded}/versions/${version}") ||
|
|
65
|
+
fail "Registry lookup for ${name} ${version} failed."
|
|
66
|
+
if [[ "$status" == 200 ]] &&
|
|
67
|
+
jq -e --arg n "$name" --arg v "$version" \
|
|
68
|
+
'.server.name == $n and .server.version == $v' "$body" >/dev/null 2>&1; then
|
|
69
|
+
echo "${name} ${version} is already in the registry." >&2
|
|
70
|
+
echo "publish=false"
|
|
71
|
+
elif [[ "$status" == 404 ]] &&
|
|
72
|
+
jq -e '.detail == "Server not found"' "$body" >/dev/null 2>&1; then
|
|
73
|
+
echo "${name} ${version} is released and not in the registry yet." >&2
|
|
74
|
+
echo "publish=true"
|
|
75
|
+
else
|
|
76
|
+
fail "Unexpected registry answer for ${name} ${version}: HTTP ${status}, $(head -c 200 "$body")"
|
|
77
|
+
fi
|
|
78
|
+
rm -f "$body"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
wait_pypi() {
|
|
82
|
+
local marker="mcp-name: ${name}" deadline=$((SECONDS + WAIT_SECONDS))
|
|
83
|
+
until curl -fsS "${PYPI}/pypi/${package}/${version}/json" 2>/dev/null |
|
|
84
|
+
jq -e --arg m "$marker" '(.info.description // "") | contains($m)' >/dev/null 2>&1; do
|
|
85
|
+
if [[ "$SECONDS" -ge "$deadline" ]]; then
|
|
86
|
+
fail "${package} ${version} with '${marker}' not on PyPI after ${WAIT_SECONDS}s." \
|
|
87
|
+
"Publish manually once it is: mcp-publisher login github && mcp-publisher publish"
|
|
88
|
+
fi
|
|
89
|
+
sleep "$POLL_SECONDS"
|
|
90
|
+
done
|
|
91
|
+
echo "${package} ${version} is on PyPI with the mcp-name marker." >&2
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
case "${1:-}" in
|
|
95
|
+
check) check ;;
|
|
96
|
+
wait-pypi) wait_pypi ;;
|
|
97
|
+
*)
|
|
98
|
+
echo "usage: $0 check|wait-pypi" >&2
|
|
99
|
+
exit 2
|
|
100
|
+
;;
|
|
101
|
+
esac
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
"source": "github",
|
|
9
9
|
"id": "1260843154"
|
|
10
10
|
},
|
|
11
|
-
"version": "0.23.
|
|
11
|
+
"version": "0.23.3",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "pypi",
|
|
15
15
|
"registryBaseUrl": "https://pypi.org",
|
|
16
16
|
"identifier": "codegraph-brain",
|
|
17
|
-
"version": "0.23.
|
|
17
|
+
"version": "0.23.3",
|
|
18
18
|
"runtimeHint": "uvx",
|
|
19
19
|
"transport": {
|
|
20
20
|
"type": "stdio"
|
|
@@ -364,13 +364,21 @@ def cgis_trace_flow(
|
|
|
364
364
|
int,
|
|
365
365
|
Field(
|
|
366
366
|
description="Maximum edge hops downstream. Every edge type counts as a hop — "
|
|
367
|
-
"
|
|
368
|
-
"
|
|
367
|
+
"calls, imports, inheritance, DI dependencies, references and containment — so "
|
|
368
|
+
"from a module or class the first hop is mostly its own members and imports."
|
|
369
369
|
),
|
|
370
370
|
] = 3,
|
|
371
371
|
output_format: OutputFormat = "mermaid",
|
|
372
372
|
) -> str:
|
|
373
|
-
"""
|
|
373
|
+
"""Downstream subgraph of one FQN: everything it reaches within ``depth`` hops.
|
|
374
|
+
|
|
375
|
+
Every edge type counts — calls, imports, inheritance, DI dependencies,
|
|
376
|
+
references, and containment (so from a module or class the first hop includes
|
|
377
|
+
its own members) — so this answers "what does X depend on?". For what depends
|
|
378
|
+
on X use
|
|
379
|
+
``cgis_analyze_impact``; for only the members of a module or class,
|
|
380
|
+
``cgis_get_structure``; for a source-included brief to read before editing
|
|
381
|
+
one symbol, ``cgis_context``.
|
|
374
382
|
|
|
375
383
|
``output_format="mermaid"`` (default) returns a human-readable diagram;
|
|
376
384
|
``"json"`` returns a joinable ``{root, nodes, edges, coverage}`` payload
|
|
@@ -417,15 +425,22 @@ def cgis_analyze_impact(
|
|
|
417
425
|
int,
|
|
418
426
|
Field(
|
|
419
427
|
description="Maximum edge hops upstream. Every edge type counts as a hop — "
|
|
420
|
-
"
|
|
421
|
-
"
|
|
428
|
+
"callers, importers, subclasses, type references, DI dependents and the "
|
|
429
|
+
"enclosing class or file all appear alongside each other."
|
|
422
430
|
),
|
|
423
431
|
] = 3,
|
|
424
432
|
output_format: OutputFormat = "mermaid",
|
|
425
433
|
) -> str:
|
|
426
|
-
"""
|
|
434
|
+
"""Upstream subgraph of one FQN: everything that reaches it within ``depth`` hops.
|
|
435
|
+
|
|
436
|
+
Every edge type counts — callers, but also importers, subclasses, type
|
|
437
|
+
references, DI dependents and the enclosing class or file — so this answers
|
|
438
|
+
"what breaks if I change X?". For what X depends on use
|
|
439
|
+
``cgis_trace_flow``; for only the members of a module or class,
|
|
440
|
+
``cgis_get_structure``; for a source-included brief to read before editing
|
|
441
|
+
one symbol, ``cgis_context``.
|
|
427
442
|
|
|
428
|
-
|
|
443
|
+
``output_format="mermaid"`` (default)
|
|
429
444
|
returns a diagram; ``"json"`` returns a joinable ``{root, nodes, edges,
|
|
430
445
|
coverage}`` payload with real FQNs — letting an agent compute set
|
|
431
446
|
differences (e.g. "which route handlers never reach ``verify_ownership``?")
|
|
@@ -471,10 +486,13 @@ def cgis_get_structure(
|
|
|
471
486
|
] = 2,
|
|
472
487
|
output_format: OutputFormat = "mermaid",
|
|
473
488
|
) -> str:
|
|
474
|
-
"""
|
|
489
|
+
"""Members of a module or class: the classes, functions and methods it contains.
|
|
475
490
|
|
|
476
|
-
|
|
477
|
-
|
|
491
|
+
Follows containment (CONTAINS/DECLARES) only, so no call or import appears.
|
|
492
|
+
For how the code connects use ``cgis_trace_flow`` (what it depends on) or
|
|
493
|
+
``cgis_analyze_impact`` (what depends on it).
|
|
494
|
+
|
|
495
|
+
Matches the CLI ``structure`` command. ``output_format="mermaid"`` (default) returns a
|
|
478
496
|
diagram of the hierarchy rooted at the given FQN; ``"json"`` returns the
|
|
479
497
|
joinable ``{root, nodes, edges}`` payload with real FQNs.
|
|
480
498
|
"""
|
|
@@ -785,7 +803,14 @@ def cgis_context(
|
|
|
785
803
|
),
|
|
786
804
|
] = "",
|
|
787
805
|
) -> str:
|
|
788
|
-
"""
|
|
806
|
+
"""Prompt-ready brief on one FQN: its source, class, direct callers and callees.
|
|
807
|
+
|
|
808
|
+
Call this before editing a symbol, instead of reading its files. It follows
|
|
809
|
+
calls only, one hop by default. Source is included when the file is found
|
|
810
|
+
(see ``source_root``), and the domain when the graph was tagged with one.
|
|
811
|
+
For a multi-hop subgraph
|
|
812
|
+
over every edge type without source, use ``cgis_trace_flow`` (downstream) or
|
|
813
|
+
``cgis_analyze_impact`` (upstream).
|
|
789
814
|
|
|
790
815
|
Returns an XML-tagged prompt — the focal node's source, its enclosing class,
|
|
791
816
|
its architectural domain boundary, direct callers (upstream ripple) and
|
|
@@ -836,7 +861,7 @@ def cgis_metrics(
|
|
|
836
861
|
),
|
|
837
862
|
] = None,
|
|
838
863
|
) -> str:
|
|
839
|
-
"""Whole-graph architectural metrics — coupling bottlenecks
|
|
864
|
+
"""Whole-graph architectural metrics — coupling bottlenecks, God classes, PageRank.
|
|
840
865
|
|
|
841
866
|
Returns JSON ``{bottlenecks, god_classes, critical}`` computed with vectorized
|
|
842
867
|
DuckDB aggregations over the whole graph (fan-in/fan-out coupling,
|
|
@@ -894,7 +919,7 @@ def cgis_find_orphans(
|
|
|
894
919
|
bool, Field(description="Include machine-generated classes, which are hidden by default.")
|
|
895
920
|
] = False,
|
|
896
921
|
) -> str:
|
|
897
|
-
"""Classes nothing in production builds, extends or names — dead-code candidates
|
|
922
|
+
"""Classes nothing in production builds, extends or names — dead-code candidates.
|
|
898
923
|
|
|
899
924
|
Finds classes that no test, type checker or linter flags, because each is
|
|
900
925
|
still imported somewhere: a package re-export keeps a class importable long
|
|
@@ -976,7 +1001,7 @@ def cgis_audit_reachability(
|
|
|
976
1001
|
Field(description="Maximum reachability depth; a longer path is reported as a gap."),
|
|
977
1002
|
] = 5,
|
|
978
1003
|
) -> str:
|
|
979
|
-
"""Reachability/authorization audit — which sources never reach a checkpoint
|
|
1004
|
+
"""Reachability/authorization audit — which sources never reach a checkpoint.
|
|
980
1005
|
|
|
981
1006
|
The headline use is **IDOR/authz coverage**: list every route handler that does
|
|
982
1007
|
NOT transitively reach an ownership check. Reachability follows behavioral edges
|
|
@@ -20,6 +20,7 @@ style tags you wrote yourself and pure numbers need no escaping.
|
|
|
20
20
|
|
|
21
21
|
import dataclasses
|
|
22
22
|
import json as _json
|
|
23
|
+
from collections.abc import Callable
|
|
23
24
|
from enum import StrEnum
|
|
24
25
|
from pathlib import Path
|
|
25
26
|
|
|
@@ -318,6 +319,40 @@ def _resolve_cli_fqn(store: SQLiteStore, target: str, kind: str) -> str:
|
|
|
318
319
|
return resolution.resolved
|
|
319
320
|
|
|
320
321
|
|
|
322
|
+
def _tree_neighbours(
|
|
323
|
+
store: SQLiteStore,
|
|
324
|
+
edges: list[Edge],
|
|
325
|
+
neighbour_of: Callable[[Edge], str],
|
|
326
|
+
*,
|
|
327
|
+
allowed_edge_types: frozenset[EdgeType] | None,
|
|
328
|
+
show_external: bool,
|
|
329
|
+
min_confidence: float | None,
|
|
330
|
+
) -> list[tuple[str, Node | None]]:
|
|
331
|
+
"""The neighbours one tree level shows: filtered, in edge order, each id once.
|
|
332
|
+
|
|
333
|
+
One entry per neighbour, not per edge: two call sites are separate edges to the
|
|
334
|
+
same node, and a tree row shows neither line nor edge type to tell them apart
|
|
335
|
+
(#463). A neighbour absent from the store (an unresolved target) comes back with
|
|
336
|
+
``None``, and is dropped with the non-INTERNAL ones when ``show_external`` is off.
|
|
337
|
+
"""
|
|
338
|
+
if allowed_edge_types is not None:
|
|
339
|
+
edges = [e for e in edges if e.type in allowed_edge_types]
|
|
340
|
+
if min_confidence is not None:
|
|
341
|
+
edges = [e for e in edges if e.confidence >= min_confidence]
|
|
342
|
+
ids = list(dict.fromkeys(neighbour_of(e) for e in edges))
|
|
343
|
+
nodes = {n.id: n for n in store.get_nodes(ids)}
|
|
344
|
+
return [
|
|
345
|
+
(node_id, nodes.get(node_id))
|
|
346
|
+
for node_id in ids
|
|
347
|
+
if show_external or _is_internal(nodes.get(node_id))
|
|
348
|
+
]
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
def _is_internal(node: Node | None) -> bool:
|
|
352
|
+
"""True for a stored node from the ingested repository."""
|
|
353
|
+
return node is not None and node.namespace == NodeNamespace.INTERNAL
|
|
354
|
+
|
|
355
|
+
|
|
321
356
|
def build_trace_tree(
|
|
322
357
|
store: SQLiteStore,
|
|
323
358
|
current_id: str,
|
|
@@ -333,21 +368,15 @@ def build_trace_tree(
|
|
|
333
368
|
if current_depth >= max_depth:
|
|
334
369
|
return
|
|
335
370
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
if not show_external and (
|
|
347
|
-
target_node is None or target_node.namespace != NodeNamespace.INTERNAL
|
|
348
|
-
):
|
|
349
|
-
continue
|
|
350
|
-
|
|
371
|
+
callees = _tree_neighbours(
|
|
372
|
+
store,
|
|
373
|
+
store.get_outgoing_edges(current_id),
|
|
374
|
+
lambda edge: edge.target,
|
|
375
|
+
allowed_edge_types=allowed_edge_types,
|
|
376
|
+
show_external=show_external,
|
|
377
|
+
min_confidence=min_confidence,
|
|
378
|
+
)
|
|
379
|
+
for target_id, target_node in callees:
|
|
351
380
|
if target_node:
|
|
352
381
|
label = (
|
|
353
382
|
f"[bold green]{target_node.type.value}[/bold green] "
|
|
@@ -470,21 +499,15 @@ def build_impact_tree(
|
|
|
470
499
|
if current_depth >= max_depth:
|
|
471
500
|
return
|
|
472
501
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
if not show_external and (
|
|
484
|
-
source_node is None or source_node.namespace != NodeNamespace.INTERNAL
|
|
485
|
-
):
|
|
486
|
-
continue
|
|
487
|
-
|
|
502
|
+
callers = _tree_neighbours(
|
|
503
|
+
store,
|
|
504
|
+
store.get_incoming_edges(current_id),
|
|
505
|
+
lambda edge: edge.source,
|
|
506
|
+
allowed_edge_types=allowed_edge_types,
|
|
507
|
+
show_external=show_external,
|
|
508
|
+
min_confidence=min_confidence,
|
|
509
|
+
)
|
|
510
|
+
for source_id, source_node in callers:
|
|
488
511
|
if source_node:
|
|
489
512
|
label = (
|
|
490
513
|
f"[bold magenta]{source_node.type.value}[/bold magenta] "
|
|
@@ -28,6 +28,10 @@ def graph_to_json(
|
|
|
28
28
|
``coverage`` is the traversal's local resolution coverage (#201). A
|
|
29
29
|
structure query follows no calls and passes none, so the key is omitted
|
|
30
30
|
rather than reported as a zero it did not measure.
|
|
31
|
+
|
|
32
|
+
Edges are one per distinct ``(src, type, dst)``, as in the Mermaid view: two
|
|
33
|
+
call sites to the same function are separate graph edges, but without a line
|
|
34
|
+
number the payload would state the same fact twice (#463).
|
|
31
35
|
"""
|
|
32
36
|
payload: dict[str, Any] = {
|
|
33
37
|
"root": root,
|
|
@@ -40,16 +44,26 @@ def graph_to_json(
|
|
|
40
44
|
}
|
|
41
45
|
for node in nodes
|
|
42
46
|
],
|
|
43
|
-
"edges":
|
|
44
|
-
|
|
47
|
+
"edges": _distinct_edges(edges),
|
|
48
|
+
}
|
|
49
|
+
if coverage is not None:
|
|
50
|
+
payload["coverage"] = coverage.model_dump()
|
|
51
|
+
return payload
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _distinct_edges(edges: list[Edge]) -> list[dict[str, Any]]:
|
|
55
|
+
"""Collapse edges sharing ``(src, type, dst)``, first-seen order, highest confidence kept."""
|
|
56
|
+
distinct: dict[tuple[str, str, str], dict[str, Any]] = {}
|
|
57
|
+
for edge in edges:
|
|
58
|
+
key = (edge.source, edge.type.value, edge.target)
|
|
59
|
+
seen = distinct.get(key)
|
|
60
|
+
if seen is None:
|
|
61
|
+
distinct[key] = {
|
|
45
62
|
"src": edge.source,
|
|
46
63
|
"dst": edge.target,
|
|
47
64
|
"type": edge.type.value,
|
|
48
65
|
"confidence": edge.confidence,
|
|
49
66
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if coverage is not None:
|
|
54
|
-
payload["coverage"] = coverage.model_dump()
|
|
55
|
-
return payload
|
|
67
|
+
elif edge.confidence > seen["confidence"]:
|
|
68
|
+
seen["confidence"] = edge.confidence
|
|
69
|
+
return list(distinct.values())
|