repotoire 0.1.2__tar.gz → 0.1.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.
- {repotoire-0.1.2 → repotoire-0.1.3}/PKG-INFO +8 -9
- {repotoire-0.1.2 → repotoire-0.1.3}/pyproject.toml +9 -11
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/__init__.py +2 -0
- repotoire-0.1.3/repotoire/api/v1/routes/graph.py +476 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/__init__.py +8 -90
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/auth.py +33 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/async_antipattern.py +1 -1
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/circular_dependency.py +1 -1
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/data_clumps.py +1 -1
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/dead_code.py +1 -1
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/engine.py +1 -1
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/generator_misuse.py +1 -1
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/graph_algorithms.py +1 -1
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/inappropriate_intimacy.py +1 -1
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/long_parameter_list.py +1 -1
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/message_chain.py +1 -1
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/test_smell.py +1 -1
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/type_hint_coverage.py +1 -1
- repotoire-0.1.3/repotoire/graph/cloud_client.py +215 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/factory.py +8 -18
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/schema.py +2 -2
- {repotoire-0.1.2 → repotoire-0.1.3}/LICENSE +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/README.md +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ai/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ai/contextual.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ai/embeddings.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ai/hybrid.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ai/llm.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ai/reranker.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ai/retrieval.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ai/spacy_clue_generator.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/app.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/auth/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/auth/clerk.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/auth/state_store.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/docs/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/docs/webhooks.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/middleware/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/middleware/usage.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/models.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/account.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/admin/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/admin/overrides.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/analysis.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/analytics.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/audit.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/billing.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/cli_auth.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/code.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/customer_webhooks.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/findings.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/fixes.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/github.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/historical.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/notifications.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/organizations.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/sandbox.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/team.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/usage.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/routes/webhooks.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/schemas/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/schemas/fix.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/schemas/quota_override.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/services/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/services/asset_packager.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/services/asset_storage.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/services/asset_validator.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/services/billing.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/services/changelog.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/services/cloud_storage.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/services/encryption.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/services/gdpr.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/services/github.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/services/marketplace.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/services/notifications.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/services/status_emails.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/services/stripe_service.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/auth/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/auth/clerk.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/auth/password_utils.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/auth/state_store.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/docs/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/docs/webhooks.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/middleware/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/middleware/deprecation.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/middleware/usage.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/middleware/version.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/schemas/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/schemas/fix.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/schemas/quota_override.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/services/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/services/billing.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/services/encryption.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/services/gdpr.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/services/github.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/shared/services/stripe_service.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/account.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/admin/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/admin/changelog.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/admin/overrides.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/admin/reports.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/admin/reviews.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/admin/status.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/analysis.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/analytics.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/audit.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/billing.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/changelog.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/cli_auth.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/code.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/customer_webhooks.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/findings.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/fixes.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/github.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/historical.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/marketplace.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/notifications.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/organizations.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/sandbox.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/status.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/team.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/usage.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/routes/webhooks.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/schemas/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v1/schemas/marketplace.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v2/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/api/v2/routes/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/applicator.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/best_of_n.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/ci.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/engine.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/entitlements.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/languages/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/languages/base.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/languages/go.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/languages/java.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/languages/python.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/languages/typescript.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/learning/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/learning/adaptive.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/learning/models.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/learning/store.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/models.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/reviewer.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/scorer.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/style/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/style/analyzer.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/style/enforcer.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/style/models.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/templates/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/templates/models.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/templates/registry.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/autofix/verifier.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cache/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cache/base.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cache/preview.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cache/scan.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cache/skill.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/api_keys.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/auth_commands.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/credentials.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/graph.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/marketplace.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/marketplace_client.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/marketplace_sync.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/ml.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/monorepo.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/repo_utils.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/sandbox.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/security.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/cli/tier_limits.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/config.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/analysis.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/api_deprecation.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/audit.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/base.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/billing.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/changelog.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/email.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/finding.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/fix.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/gdpr.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/github.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/marketplace.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/organization.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/quota_override.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/repository.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/status.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/uptime.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/user.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/models/webhook.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/repositories/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/repositories/fix.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/repositories/quota_override.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/db/session.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/architectural_bottleneck.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/bandit_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/base.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/core_utility.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/deduplicator.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/degree_centrality.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/duplicate_rust.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/feature_envy.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/god_class.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/graphsage_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/influential_code.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/jscpd_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/lazy_class.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/middle_man.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/ml_bug_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/module_cohesion.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/multimodal_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/mypy_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/pylint_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/radon_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/refused_bequest.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/risk_analyzer.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/root_cause_analyzer.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/ruff_import_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/ruff_lint_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/satd_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/semgrep_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/shotgun_surgery.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/taint_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/temporal_metrics.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/truly_unused_imports.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/voting_engine.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/detectors/vulture_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/github/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/github/pr_analyzer.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/github/pr_commenter.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/base.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/client.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/enricher.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/external_labels.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/falkordb_client.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/incremental_scc.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/migration.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/neo4j_multitenant.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/queries/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/queries/builders.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/queries/patterns.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/queries/traversal.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/graph/tenant_factory.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/historical/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/historical/git_graphiti.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/historical/metrics_collector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/historical/timescale_client.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/hooks/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/hooks/pre_commit.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/integrations/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/integrations/git.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/logging_config.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/marketplace/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/marketplace/analytics.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/marketplace/claude_integration.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/marketplace/claudeai_export.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/marketplace/scanner.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/marketplace/versioning.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/mcp/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/mcp/__main__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/mcp/api_server.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/mcp/execution_env.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/mcp/models.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/mcp/pattern_detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/mcp/resources.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/mcp/schema_generator.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/mcp/server_generator.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/mcp_marketplace/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/mcp_marketplace/http_server.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/mcp_marketplace/server.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/migrations/001_initial_schema.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/migrations/002_add_clue_nodes.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/migrations/003_add_session_nodes.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/migrations/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/migrations/manager.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/migrations/migration.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ml/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ml/bug_predictor.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ml/contrastive_learning.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ml/cross_project_trainer.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ml/graph_embeddings.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ml/graphsage_predictor.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ml/multimodal_analyzer.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ml/multimodal_fusion.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ml/node2vec_embeddings.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ml/similarity.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/ml/training_data.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/models.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/monorepo/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/monorepo/affected.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/monorepo/analyzer.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/monorepo/cross_package.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/monorepo/detector.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/monorepo/models.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/observability/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/observability/metrics.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/observability/tracing.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/parsers/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/parsers/base.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/parsers/base_tree_sitter_parser.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/parsers/python_parser.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/parsers/tree_sitter_adapter.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/parsers/tree_sitter_python.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/pipeline/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/pipeline/ingestion.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/pipeline/temporal_ingestion.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/reporters/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/reporters/html_reporter.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/rules/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/rules/daemon.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/rules/engine.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/rules/validator.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/alerts.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/client.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/code_validator.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/config.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/enforcement.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/exceptions.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/metrics.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/override_service.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/quotas.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/session_tracker.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/skill_executor.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/test_executor.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/tiers.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/tool_executor.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/trial.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/sandbox/usage.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/security/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/security/compliance_reporter.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/security/dependency_scanner.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/security/sbom_generator.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/security/secrets_scanner.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/services/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/services/audit.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/services/email.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/services/github_status.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/services/quality_gates.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/services/webhook_payloads.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/templates/emails/analysis_complete.html +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/templates/emails/analysis_failed.html +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/templates/emails/base.html +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/templates/emails/deletion_cancelled.html +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/templates/emails/deletion_confirmation.html +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/templates/emails/health_regression.html +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/templates/emails/payment_failed.html +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/templates/emails/team_invite.html +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/templates/emails/welcome.html +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/validation.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/workers/__init__.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/workers/analytics_tasks.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/workers/audit_tasks.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/workers/celery_app.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/workers/changelog.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/workers/debounce.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/workers/health_checks.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/workers/hooks.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/workers/limits.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/workers/progress.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/workers/tasks.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/workers/webhook_delivery.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire/workers/webhooks.py +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/CONTRIBUTING.md +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/Cargo.lock +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/Cargo.toml +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/ROADMAP.md +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/benches/duplicate_bench.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/benches/graph_bench.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/benches/node2vec_bench.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/benches/word2vec_bench.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/docs/RUST_ARCHITECTURE.md +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/docs/RUST_DEVELOPMENT.md +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/cfg.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/complexity.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/dataflow.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/duplicate.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/errors.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/graph_algo.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/hashing.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/incremental_scc.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/lcom.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/lib.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/pylint_rules.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/satd.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/similarity.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/taint.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/type_inference.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire-fast/src/word2vec.rs +0 -0
- {repotoire-0.1.2 → repotoire-0.1.3}/repotoire_fast/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: repotoire
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -9,7 +9,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.12
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.13
|
|
11
11
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
12
|
-
Requires-Dist:
|
|
12
|
+
Requires-Dist: falkordb>=1.0.0
|
|
13
13
|
Requires-Dist: openai>=1.0.0
|
|
14
14
|
Requires-Dist: spacy>=3.7.0
|
|
15
15
|
Requires-Dist: click>=8.1.0
|
|
@@ -49,6 +49,12 @@ Requires-Dist: uv-secure>=0.15.0
|
|
|
49
49
|
Requires-Dist: datasets>=2.14.0
|
|
50
50
|
Requires-Dist: sentence-transformers>=2.2.0
|
|
51
51
|
Requires-Dist: accelerate>=0.26.0
|
|
52
|
+
Requires-Dist: mypy>=1.7.0
|
|
53
|
+
Requires-Dist: pylint>=3.0.0
|
|
54
|
+
Requires-Dist: bandit>=1.7.0
|
|
55
|
+
Requires-Dist: radon>=6.0.0
|
|
56
|
+
Requires-Dist: vulture>=2.0.0
|
|
57
|
+
Requires-Dist: semgrep>=1.0.0
|
|
52
58
|
Requires-Dist: pytest>=7.4.0 ; extra == 'dev'
|
|
53
59
|
Requires-Dist: pytest-cov>=4.1.0 ; extra == 'dev'
|
|
54
60
|
Requires-Dist: pytest-xdist>=3.5.0 ; extra == 'dev'
|
|
@@ -81,12 +87,6 @@ Requires-Dist: opentelemetry-api>=1.20.0 ; extra == 'observability'
|
|
|
81
87
|
Requires-Dist: opentelemetry-sdk>=1.20.0 ; extra == 'observability'
|
|
82
88
|
Requires-Dist: opentelemetry-exporter-otlp>=1.20.0 ; extra == 'observability'
|
|
83
89
|
Requires-Dist: sentry-sdk[fastapi,celery,sqlalchemy]>=2.0.0 ; extra == 'observability'
|
|
84
|
-
Requires-Dist: mypy>=1.7.0 ; extra == 'detectors'
|
|
85
|
-
Requires-Dist: pylint>=3.0.0 ; extra == 'detectors'
|
|
86
|
-
Requires-Dist: bandit>=1.7.0 ; extra == 'detectors'
|
|
87
|
-
Requires-Dist: radon>=6.0.0 ; extra == 'detectors'
|
|
88
|
-
Requires-Dist: vulture>=2.0.0 ; extra == 'detectors'
|
|
89
|
-
Requires-Dist: semgrep>=1.0.0 ; extra == 'detectors'
|
|
90
90
|
Requires-Dist: questionary>=2.0.0 ; extra == 'ml'
|
|
91
91
|
Requires-Dist: scikit-learn>=1.3.0 ; extra == 'ml'
|
|
92
92
|
Requires-Dist: joblib>=1.3.0 ; extra == 'ml'
|
|
@@ -105,7 +105,6 @@ Provides-Extra: graphiti
|
|
|
105
105
|
Provides-Extra: security
|
|
106
106
|
Provides-Extra: local-embeddings
|
|
107
107
|
Provides-Extra: observability
|
|
108
|
-
Provides-Extra: detectors
|
|
109
108
|
Provides-Extra: ml
|
|
110
109
|
Provides-Extra: sandbox
|
|
111
110
|
Provides-Extra: voyage
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "repotoire"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.3"
|
|
8
8
|
description = "Graph-Powered Code Health Platform"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -25,7 +25,7 @@ classifiers = [
|
|
|
25
25
|
]
|
|
26
26
|
|
|
27
27
|
dependencies = [
|
|
28
|
-
"
|
|
28
|
+
"falkordb>=1.0.0", # Cloud graph database client
|
|
29
29
|
"openai>=1.0.0",
|
|
30
30
|
"spacy>=3.7.0",
|
|
31
31
|
"click>=8.1.0",
|
|
@@ -68,6 +68,13 @@ dependencies = [
|
|
|
68
68
|
"datasets>=2.14.0", # Required for sentence-transformers fine-tuning
|
|
69
69
|
"sentence-transformers>=2.2.0", # Local embedding models + contrastive learning
|
|
70
70
|
"accelerate>=0.26.0", # Required for PyTorch Trainer
|
|
71
|
+
# Hybrid detector dependencies (core feature)
|
|
72
|
+
"mypy>=1.7.0", # Type checking detector
|
|
73
|
+
"pylint>=3.0.0", # Advanced linting detector
|
|
74
|
+
"bandit>=1.7.0", # Security vulnerability detector
|
|
75
|
+
"radon>=6.0.0", # Complexity metrics detector
|
|
76
|
+
"vulture>=2.0.0", # Dead code detector
|
|
77
|
+
"semgrep>=1.0.0", # Advanced security pattern detector
|
|
71
78
|
]
|
|
72
79
|
|
|
73
80
|
[project.optional-dependencies]
|
|
@@ -131,15 +138,6 @@ observability = [
|
|
|
131
138
|
"sentry-sdk[fastapi,celery,sqlalchemy]>=2.0.0", # Error tracking and performance monitoring (REPO-271)
|
|
132
139
|
]
|
|
133
140
|
|
|
134
|
-
detectors = [
|
|
135
|
-
"mypy>=1.7.0", # Type checking detector
|
|
136
|
-
"pylint>=3.0.0", # Advanced linting detector
|
|
137
|
-
"bandit>=1.7.0", # Security vulnerability detector
|
|
138
|
-
"radon>=6.0.0", # Complexity metrics detector
|
|
139
|
-
"vulture>=2.0.0", # Dead code detector
|
|
140
|
-
"semgrep>=1.0.0", # Advanced security pattern detector
|
|
141
|
-
]
|
|
142
|
-
|
|
143
141
|
ml = [
|
|
144
142
|
"questionary>=2.0.0", # Interactive CLI prompts for active learning
|
|
145
143
|
"scikit-learn>=1.3.0", # ML models for bug prediction and uncertainty sampling
|
|
@@ -19,6 +19,7 @@ from repotoire.api.v1.routes import (
|
|
|
19
19
|
findings,
|
|
20
20
|
fixes,
|
|
21
21
|
github,
|
|
22
|
+
graph,
|
|
22
23
|
historical,
|
|
23
24
|
marketplace,
|
|
24
25
|
notifications,
|
|
@@ -223,6 +224,7 @@ v1_app.include_router(customer_webhooks.router)
|
|
|
223
224
|
v1_app.include_router(findings.router)
|
|
224
225
|
v1_app.include_router(fixes.router)
|
|
225
226
|
v1_app.include_router(github.router)
|
|
227
|
+
v1_app.include_router(graph.router)
|
|
226
228
|
v1_app.include_router(historical.router)
|
|
227
229
|
v1_app.include_router(marketplace.router)
|
|
228
230
|
v1_app.include_router(notifications.router)
|
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
"""Graph proxy API routes for CLI operations.
|
|
2
|
+
|
|
3
|
+
This module provides API endpoints that proxy graph database operations
|
|
4
|
+
to the internal FalkorDB instance. This allows the CLI to perform graph
|
|
5
|
+
operations without direct database access.
|
|
6
|
+
|
|
7
|
+
All operations are authenticated via API key and scoped to the user's
|
|
8
|
+
organization graph.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
from typing import Any, Dict, List, Optional
|
|
14
|
+
from uuid import UUID
|
|
15
|
+
|
|
16
|
+
from fastapi import APIRouter, Depends, Header, HTTPException, status
|
|
17
|
+
from pydantic import BaseModel, Field
|
|
18
|
+
from sqlalchemy import select
|
|
19
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
20
|
+
|
|
21
|
+
from repotoire.api.shared.auth.clerk import get_clerk_client
|
|
22
|
+
from repotoire.db.models import Organization, OrganizationMembership, User
|
|
23
|
+
from repotoire.db.session import get_db
|
|
24
|
+
from repotoire.graph.tenant_factory import get_factory
|
|
25
|
+
from repotoire.logging_config import get_logger
|
|
26
|
+
from repotoire.models import (
|
|
27
|
+
Entity,
|
|
28
|
+
FileEntity,
|
|
29
|
+
ClassEntity,
|
|
30
|
+
FunctionEntity,
|
|
31
|
+
ModuleEntity,
|
|
32
|
+
NodeType,
|
|
33
|
+
Relationship,
|
|
34
|
+
RelationshipType,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
logger = get_logger(__name__)
|
|
38
|
+
|
|
39
|
+
router = APIRouter(prefix="/graph", tags=["graph"])
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# =============================================================================
|
|
43
|
+
# API Key Authentication
|
|
44
|
+
# =============================================================================
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass
|
|
48
|
+
class APIKeyUser:
|
|
49
|
+
"""Authenticated user from API key."""
|
|
50
|
+
|
|
51
|
+
org_id: str # Our internal org UUID
|
|
52
|
+
org_slug: str
|
|
53
|
+
user_id: Optional[str] = None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
async def get_current_api_key_user(
|
|
57
|
+
db: AsyncSession = Depends(get_db),
|
|
58
|
+
authorization: Optional[str] = Header(None, alias="Authorization"),
|
|
59
|
+
) -> APIKeyUser:
|
|
60
|
+
"""Validate API key and return authenticated user with org info."""
|
|
61
|
+
if not authorization:
|
|
62
|
+
raise HTTPException(
|
|
63
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
64
|
+
detail="Missing Authorization header",
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
parts = authorization.split(" ", 1)
|
|
68
|
+
if len(parts) != 2 or parts[0].lower() != "bearer":
|
|
69
|
+
raise HTTPException(
|
|
70
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
71
|
+
detail="Invalid Authorization format. Use: Bearer <api_key>",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
api_key = parts[1]
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
clerk = get_clerk_client()
|
|
78
|
+
api_key_data = await asyncio.to_thread(
|
|
79
|
+
clerk.api_keys.verify_api_key, secret=api_key
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
subject = api_key_data.subject
|
|
83
|
+
clerk_org_id = None
|
|
84
|
+
org = None
|
|
85
|
+
|
|
86
|
+
if subject.startswith("org_"):
|
|
87
|
+
clerk_org_id = subject
|
|
88
|
+
elif hasattr(api_key_data, "org_id") and api_key_data.org_id:
|
|
89
|
+
clerk_org_id = api_key_data.org_id
|
|
90
|
+
elif subject.startswith("user_"):
|
|
91
|
+
# User-scoped key - look up user's organization
|
|
92
|
+
result = await db.execute(
|
|
93
|
+
select(User).where(User.clerk_user_id == subject)
|
|
94
|
+
)
|
|
95
|
+
db_user = result.scalar_one_or_none()
|
|
96
|
+
if not db_user:
|
|
97
|
+
raise HTTPException(
|
|
98
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
99
|
+
detail="User not found",
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
result = await db.execute(
|
|
103
|
+
select(OrganizationMembership).where(
|
|
104
|
+
OrganizationMembership.user_id == db_user.id
|
|
105
|
+
)
|
|
106
|
+
)
|
|
107
|
+
membership = result.scalar_one_or_none()
|
|
108
|
+
if membership:
|
|
109
|
+
result = await db.execute(
|
|
110
|
+
select(Organization).where(
|
|
111
|
+
Organization.id == membership.organization_id
|
|
112
|
+
)
|
|
113
|
+
)
|
|
114
|
+
org = result.scalar_one_or_none()
|
|
115
|
+
if org:
|
|
116
|
+
clerk_org_id = org.clerk_org_id
|
|
117
|
+
|
|
118
|
+
# Look up org by Clerk ID
|
|
119
|
+
if not org and clerk_org_id:
|
|
120
|
+
result = await db.execute(
|
|
121
|
+
select(Organization).where(Organization.clerk_org_id == clerk_org_id)
|
|
122
|
+
)
|
|
123
|
+
org = result.scalar_one_or_none()
|
|
124
|
+
|
|
125
|
+
if not org:
|
|
126
|
+
raise HTTPException(
|
|
127
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
128
|
+
detail="Organization not found",
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
return APIKeyUser(
|
|
132
|
+
org_id=str(org.id),
|
|
133
|
+
org_slug=org.slug,
|
|
134
|
+
user_id=subject if subject.startswith("user_") else None,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
except HTTPException:
|
|
138
|
+
raise
|
|
139
|
+
except Exception as e:
|
|
140
|
+
logger.error(f"API key validation failed: {e}")
|
|
141
|
+
raise HTTPException(
|
|
142
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
143
|
+
detail="Invalid or expired API key",
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
# =============================================================================
|
|
148
|
+
# Request/Response Models
|
|
149
|
+
# =============================================================================
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class QueryRequest(BaseModel):
|
|
153
|
+
"""Request to execute a Cypher query."""
|
|
154
|
+
|
|
155
|
+
query: str = Field(..., description="Cypher query to execute")
|
|
156
|
+
parameters: Optional[Dict[str, Any]] = Field(
|
|
157
|
+
default=None, description="Query parameters"
|
|
158
|
+
)
|
|
159
|
+
timeout: Optional[float] = Field(
|
|
160
|
+
default=None, description="Query timeout in seconds"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class QueryResponse(BaseModel):
|
|
165
|
+
"""Response from a Cypher query."""
|
|
166
|
+
|
|
167
|
+
results: List[Dict[str, Any]] = Field(..., description="Query results")
|
|
168
|
+
count: int = Field(..., description="Number of results")
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class StatsResponse(BaseModel):
|
|
172
|
+
"""Graph statistics response."""
|
|
173
|
+
|
|
174
|
+
stats: Dict[str, int] = Field(..., description="Node/relationship counts")
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class BatchNodesRequest(BaseModel):
|
|
178
|
+
"""Request to batch create nodes."""
|
|
179
|
+
|
|
180
|
+
entities: List[Dict[str, Any]] = Field(..., description="Entities to create")
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class BatchNodesResponse(BaseModel):
|
|
184
|
+
"""Response from batch node creation."""
|
|
185
|
+
|
|
186
|
+
created: Dict[str, str] = Field(
|
|
187
|
+
..., description="Map of qualified_name to node ID"
|
|
188
|
+
)
|
|
189
|
+
count: int = Field(..., description="Number of nodes created")
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class BatchRelationshipsRequest(BaseModel):
|
|
193
|
+
"""Request to batch create relationships."""
|
|
194
|
+
|
|
195
|
+
relationships: List[Dict[str, Any]] = Field(
|
|
196
|
+
..., description="Relationships to create"
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class BatchRelationshipsResponse(BaseModel):
|
|
201
|
+
"""Response from batch relationship creation."""
|
|
202
|
+
|
|
203
|
+
count: int = Field(..., description="Number of relationships created")
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class FileMetadataResponse(BaseModel):
|
|
207
|
+
"""File metadata for incremental ingestion."""
|
|
208
|
+
|
|
209
|
+
metadata: Optional[Dict[str, Any]] = Field(
|
|
210
|
+
None, description="File metadata or None if not found"
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class FilePathsResponse(BaseModel):
|
|
215
|
+
"""List of file paths in the graph."""
|
|
216
|
+
|
|
217
|
+
paths: List[str] = Field(..., description="File paths")
|
|
218
|
+
count: int = Field(..., description="Number of files")
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class DeleteResponse(BaseModel):
|
|
222
|
+
"""Response from delete operation."""
|
|
223
|
+
|
|
224
|
+
deleted: int = Field(..., description="Number of items deleted")
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
# =============================================================================
|
|
228
|
+
# Helper Functions
|
|
229
|
+
# =============================================================================
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def _get_client_for_user(user: APIKeyUser):
|
|
233
|
+
"""Get graph client scoped to user's organization."""
|
|
234
|
+
factory = get_factory()
|
|
235
|
+
return factory.get_client(org_id=UUID(user.org_id), org_slug=user.org_slug)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
# =============================================================================
|
|
239
|
+
# Endpoints
|
|
240
|
+
# =============================================================================
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
@router.post("/query", response_model=QueryResponse)
|
|
244
|
+
async def execute_query(
|
|
245
|
+
request: QueryRequest,
|
|
246
|
+
user: APIKeyUser = Depends(get_current_api_key_user),
|
|
247
|
+
) -> QueryResponse:
|
|
248
|
+
"""Execute a Cypher query on the organization's graph."""
|
|
249
|
+
client = _get_client_for_user(user)
|
|
250
|
+
try:
|
|
251
|
+
results = client.execute_query(
|
|
252
|
+
request.query,
|
|
253
|
+
parameters=request.parameters,
|
|
254
|
+
timeout=request.timeout,
|
|
255
|
+
)
|
|
256
|
+
return QueryResponse(results=results, count=len(results))
|
|
257
|
+
except Exception as e:
|
|
258
|
+
logger.error(f"Query failed: {e}", org_id=user.org_id)
|
|
259
|
+
raise HTTPException(
|
|
260
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
261
|
+
detail=f"Query failed: {str(e)}",
|
|
262
|
+
)
|
|
263
|
+
finally:
|
|
264
|
+
client.close()
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
@router.get("/stats", response_model=StatsResponse)
|
|
268
|
+
async def get_stats(
|
|
269
|
+
user: APIKeyUser = Depends(get_current_api_key_user),
|
|
270
|
+
) -> StatsResponse:
|
|
271
|
+
"""Get graph statistics."""
|
|
272
|
+
client = _get_client_for_user(user)
|
|
273
|
+
try:
|
|
274
|
+
stats = client.get_stats()
|
|
275
|
+
return StatsResponse(stats=stats)
|
|
276
|
+
finally:
|
|
277
|
+
client.close()
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
@router.delete("/clear", response_model=DeleteResponse)
|
|
281
|
+
async def clear_graph(
|
|
282
|
+
user: APIKeyUser = Depends(get_current_api_key_user),
|
|
283
|
+
) -> DeleteResponse:
|
|
284
|
+
"""Clear all nodes and relationships from the graph."""
|
|
285
|
+
client = _get_client_for_user(user)
|
|
286
|
+
try:
|
|
287
|
+
# Get count before clearing for response
|
|
288
|
+
stats = client.get_stats()
|
|
289
|
+
total = sum(stats.values())
|
|
290
|
+
client.clear_graph()
|
|
291
|
+
logger.info(f"Graph cleared", org_id=user.org_id, deleted=total)
|
|
292
|
+
return DeleteResponse(deleted=total)
|
|
293
|
+
finally:
|
|
294
|
+
client.close()
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
@router.post("/batch/nodes", response_model=BatchNodesResponse)
|
|
298
|
+
async def batch_create_nodes(
|
|
299
|
+
request: BatchNodesRequest,
|
|
300
|
+
user: APIKeyUser = Depends(get_current_api_key_user),
|
|
301
|
+
) -> BatchNodesResponse:
|
|
302
|
+
"""Batch create nodes in the graph."""
|
|
303
|
+
client = _get_client_for_user(user)
|
|
304
|
+
try:
|
|
305
|
+
# Convert dicts to appropriate Entity subclass
|
|
306
|
+
entities = []
|
|
307
|
+
for e in request.entities:
|
|
308
|
+
entity_type = e.get("entity_type", "Unknown")
|
|
309
|
+
node_type = NodeType(entity_type) if entity_type in [t.value for t in NodeType] else None
|
|
310
|
+
|
|
311
|
+
# Common fields for all entities
|
|
312
|
+
base_fields = {
|
|
313
|
+
"name": e["name"],
|
|
314
|
+
"qualified_name": e["qualified_name"],
|
|
315
|
+
"file_path": e.get("file_path", ""),
|
|
316
|
+
"line_start": e.get("line_start", 0),
|
|
317
|
+
"line_end": e.get("line_end", 0),
|
|
318
|
+
"docstring": e.get("docstring"),
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
# Create appropriate entity type
|
|
322
|
+
if entity_type == "File":
|
|
323
|
+
entity = FileEntity(
|
|
324
|
+
**base_fields,
|
|
325
|
+
node_type=NodeType.FILE,
|
|
326
|
+
language=e.get("language", "python"),
|
|
327
|
+
loc=e.get("loc", 0),
|
|
328
|
+
hash=e.get("hash"),
|
|
329
|
+
exports=e.get("exports", []),
|
|
330
|
+
)
|
|
331
|
+
elif entity_type == "Class":
|
|
332
|
+
entity = ClassEntity(
|
|
333
|
+
**base_fields,
|
|
334
|
+
node_type=NodeType.CLASS,
|
|
335
|
+
is_abstract=e.get("is_abstract", False),
|
|
336
|
+
complexity=e.get("complexity", 0),
|
|
337
|
+
decorators=e.get("decorators", []),
|
|
338
|
+
)
|
|
339
|
+
elif entity_type == "Function":
|
|
340
|
+
entity = FunctionEntity(
|
|
341
|
+
**base_fields,
|
|
342
|
+
node_type=NodeType.FUNCTION,
|
|
343
|
+
parameters=e.get("parameters", []),
|
|
344
|
+
return_type=e.get("return_type"),
|
|
345
|
+
is_async=e.get("is_async", False),
|
|
346
|
+
decorators=e.get("decorators", []),
|
|
347
|
+
complexity=e.get("complexity", 0),
|
|
348
|
+
is_method=e.get("is_method", False),
|
|
349
|
+
is_static=e.get("is_static", False),
|
|
350
|
+
is_classmethod=e.get("is_classmethod", False),
|
|
351
|
+
is_property=e.get("is_property", False),
|
|
352
|
+
)
|
|
353
|
+
elif entity_type == "Module":
|
|
354
|
+
entity = ModuleEntity(
|
|
355
|
+
**base_fields,
|
|
356
|
+
node_type=NodeType.MODULE,
|
|
357
|
+
is_external=e.get("is_external", False),
|
|
358
|
+
package=e.get("package"),
|
|
359
|
+
)
|
|
360
|
+
else:
|
|
361
|
+
# Fall back to base Entity for unknown types
|
|
362
|
+
entity = Entity(
|
|
363
|
+
**base_fields,
|
|
364
|
+
node_type=node_type,
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
# Set repo_id and repo_slug for multi-tenant isolation
|
|
368
|
+
if e.get("repo_id"):
|
|
369
|
+
entity.repo_id = e["repo_id"]
|
|
370
|
+
if e.get("repo_slug"):
|
|
371
|
+
entity.repo_slug = e["repo_slug"]
|
|
372
|
+
|
|
373
|
+
entities.append(entity)
|
|
374
|
+
|
|
375
|
+
created = client.batch_create_nodes(entities)
|
|
376
|
+
return BatchNodesResponse(created=created, count=len(created))
|
|
377
|
+
except Exception as e:
|
|
378
|
+
logger.error(f"Batch create nodes failed: {e}", org_id=user.org_id)
|
|
379
|
+
raise HTTPException(
|
|
380
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
381
|
+
detail=f"Batch create failed: {str(e)}",
|
|
382
|
+
)
|
|
383
|
+
finally:
|
|
384
|
+
client.close()
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
@router.post("/batch/relationships", response_model=BatchRelationshipsResponse)
|
|
388
|
+
async def batch_create_relationships(
|
|
389
|
+
request: BatchRelationshipsRequest,
|
|
390
|
+
user: APIKeyUser = Depends(get_current_api_key_user),
|
|
391
|
+
) -> BatchRelationshipsResponse:
|
|
392
|
+
"""Batch create relationships in the graph."""
|
|
393
|
+
client = _get_client_for_user(user)
|
|
394
|
+
try:
|
|
395
|
+
# Convert dicts to Relationship objects
|
|
396
|
+
relationships = []
|
|
397
|
+
for r in request.relationships:
|
|
398
|
+
# Parse rel_type from string to enum
|
|
399
|
+
rel_type_str = r.get("rel_type", "CALLS")
|
|
400
|
+
try:
|
|
401
|
+
rel_type = RelationshipType(rel_type_str)
|
|
402
|
+
except ValueError:
|
|
403
|
+
rel_type = RelationshipType.CALLS # Default fallback
|
|
404
|
+
|
|
405
|
+
rel = Relationship(
|
|
406
|
+
source_id=r["source_id"],
|
|
407
|
+
target_id=r["target_id"],
|
|
408
|
+
rel_type=rel_type,
|
|
409
|
+
properties=r.get("properties", {}),
|
|
410
|
+
)
|
|
411
|
+
relationships.append(rel)
|
|
412
|
+
|
|
413
|
+
count = client.batch_create_relationships(relationships)
|
|
414
|
+
return BatchRelationshipsResponse(count=count)
|
|
415
|
+
except Exception as e:
|
|
416
|
+
logger.error(f"Batch create relationships failed: {e}", org_id=user.org_id)
|
|
417
|
+
raise HTTPException(
|
|
418
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
419
|
+
detail=f"Batch create failed: {str(e)}",
|
|
420
|
+
)
|
|
421
|
+
finally:
|
|
422
|
+
client.close()
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
@router.get("/files", response_model=FilePathsResponse)
|
|
426
|
+
async def get_file_paths(
|
|
427
|
+
user: APIKeyUser = Depends(get_current_api_key_user),
|
|
428
|
+
) -> FilePathsResponse:
|
|
429
|
+
"""Get all file paths in the graph."""
|
|
430
|
+
client = _get_client_for_user(user)
|
|
431
|
+
try:
|
|
432
|
+
paths = client.get_all_file_paths()
|
|
433
|
+
return FilePathsResponse(paths=paths, count=len(paths))
|
|
434
|
+
finally:
|
|
435
|
+
client.close()
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
@router.get("/files/{file_path:path}/metadata", response_model=FileMetadataResponse)
|
|
439
|
+
async def get_file_metadata(
|
|
440
|
+
file_path: str,
|
|
441
|
+
user: APIKeyUser = Depends(get_current_api_key_user),
|
|
442
|
+
) -> FileMetadataResponse:
|
|
443
|
+
"""Get metadata for a specific file (for incremental ingestion)."""
|
|
444
|
+
client = _get_client_for_user(user)
|
|
445
|
+
try:
|
|
446
|
+
metadata = client.get_file_metadata(file_path)
|
|
447
|
+
return FileMetadataResponse(metadata=metadata)
|
|
448
|
+
finally:
|
|
449
|
+
client.close()
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
@router.delete("/files/{file_path:path}", response_model=DeleteResponse)
|
|
453
|
+
async def delete_file(
|
|
454
|
+
file_path: str,
|
|
455
|
+
user: APIKeyUser = Depends(get_current_api_key_user),
|
|
456
|
+
) -> DeleteResponse:
|
|
457
|
+
"""Delete a file and its related entities from the graph."""
|
|
458
|
+
client = _get_client_for_user(user)
|
|
459
|
+
try:
|
|
460
|
+
deleted = client.delete_file_entities(file_path)
|
|
461
|
+
return DeleteResponse(deleted=deleted)
|
|
462
|
+
finally:
|
|
463
|
+
client.close()
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
@router.post("/indexes")
|
|
467
|
+
async def create_indexes(
|
|
468
|
+
user: APIKeyUser = Depends(get_current_api_key_user),
|
|
469
|
+
) -> Dict[str, str]:
|
|
470
|
+
"""Create indexes for better query performance."""
|
|
471
|
+
client = _get_client_for_user(user)
|
|
472
|
+
try:
|
|
473
|
+
client.create_indexes()
|
|
474
|
+
return {"status": "ok", "message": "Indexes created"}
|
|
475
|
+
finally:
|
|
476
|
+
client.close()
|