marvisx-cli 0.3.8b1__tar.gz → 0.3.8b3__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.
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/PKG-INFO +1 -1
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/config.py +7 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/db.py +57 -42
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/main.py +14 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/server.py +45 -1
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/graph.py +37 -14
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/learnings.py +3 -3
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/inbox.py +29 -1
- marvisx_cli-0.3.8b3/core/api/services/inbox_digest_deep_research.py +153 -0
- marvisx_cli-0.3.8b3/core/api/tests/test_graph_freshness.py +126 -0
- marvisx_cli-0.3.8b3/core/api/tests/test_learnings_create_pre148.py +95 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/graph.py +137 -1
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/learnings.py +32 -20
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/projects.py +21 -1
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/marvis_doctor.py +49 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/wizard/validation.py +2 -2
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/marvisx_cli.egg-info/PKG-INFO +1 -1
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/marvisx_cli.egg-info/SOURCES.txt +2 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/pyproject.toml +1 -1
- marvisx_cli-0.3.8b1/core/api/services/inbox_digest_deep_research.py +0 -80
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/LICENSE +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/MANIFEST.in +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/README.md +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/agents/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/agents/session_health.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/agents/session_manager.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/bin/marvisx-state-hook.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/dependencies/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/dependencies/tenant.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/_adapter.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/brain.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/handoffs.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/ingest.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/projects.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/pull_requests.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/safety.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/search.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/tasks.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/workflow_playbooks/brainstorm.md +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/workflow_playbooks/compound.md +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/workflow_playbooks/plan.md +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/mcp/tools/workflows.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/middleware/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/middleware/tool_call_audit.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/auth.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/brain.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/common.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/costs.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/graph.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/graph_cosmo.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/graph_pr_impact.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/graph_ux.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/inbox.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/ingest_keys.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/kg.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/llm_config.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/monitoring.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/projects.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/search.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/sessions.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/tasks.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/teams.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/models/users.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/observability/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/observability/tracing.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/paths.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/rate_limit.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/rbac.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/_adapter.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/admin_pr_impact.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/admin_settings.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/agent.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/agent_tokens.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/app_settings.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/audit.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/auth.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/bench.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/brain.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/brain_directions.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/ci_checks.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/comments.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/costs.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/docs_coverage.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/docs_governance.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/documents.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/files.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/finder.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/graph.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/handoffs.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/ingest_api_keys.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/ingest_triage.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/judge.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/kg.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/learnings.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/llm_config.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/monitoring.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/notifications.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/pr_impact.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/projects.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/pull_requests.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/push.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/raci.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/search.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/sessions.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/settings.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/share_repo.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/status_updates.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/tags.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/tasks.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/teams.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/terminal.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/users.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/routers/webhooks.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/runtime_settings.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/security.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/_fts.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/audit.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/auto_approval.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/baseline.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/capabilities.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/cascade_rollup.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/compound_bridge.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/cycle.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/cycle_snapshot.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/digest_collector.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/direction.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/drift.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/drift_router.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/edge_metrics.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/events_reader.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/findings.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/findings_reader.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/jobs.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/journal.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/knowledge_forms.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/llm/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/llm/_runner.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/llm/base.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/llm/cache.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/llm/constants.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/llm/direction_alignment.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/llm/factory.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/llm/finding_reasoning.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/llm/finding_summary.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/llm/grounding.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/llm/journal_polish.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/llm/local_gateway.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/llm/parsers.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/llm/router_glue.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/memory_ops.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/models.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/owner_hint.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/recap.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/rules/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/rules/_signals.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/rules/dr1_activity_without_status.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/rules/dr2_decision_without_adr.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/rules/dr3_stale_open_loop.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/rules/dr4_docs_governance_drift.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/rules/dr5_playbook_changed.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/rules/dr6_external_update_unpropagated.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/rules/dr7_claimed_decision_gap.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/rules/dr8_direction_misalignment.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/runs_reader.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/scope.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/sources/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/sources/base.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/sources/git_kg.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/sources/handoffs.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/sources/ingestor.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/sources/learnings.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/sources/pir_tasks.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/warehouse_consolidate.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/watermarks.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/brain/ws_emitter.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/cc_tasks_reader.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/chunking.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ci_service.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/claude_metrics.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/codex_metrics.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/conversation_reader.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/cost_service.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/crypto.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/docs_governance/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/docs_governance/confidence.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/docs_governance/config.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/docs_governance/enrichment.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/docs_governance/frontmatter_validator.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/docs_governance/hard_gates.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/docs_governance/triage_orchestrator.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/dream_cycle.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/embedding_backends/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/embedding_internal.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/embedding_service.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/event_dispatcher.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/events.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/git_ops.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/graph_cosmo_service.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/graph_ranker.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/graph_service.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/grounding/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/grounding/citations.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/grounding/verifier.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/inbox.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/inbox_digest.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/inbox_digest_jobs.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/inbox_gmail_sync.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/inbox_llm_classifier.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/inbox_source_identity.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/inbox_sources.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/inbox_taxonomy.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/inbox_tldr.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/inbox_triage.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/api_key_auth.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/auto_approve.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/classifier.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/confidence.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/dispatch.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/embedding_router.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/events.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/ignore_patterns.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/image_probe.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/ingress.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/insert_saga.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/llm/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/llm/anthropic_haiku.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/llm/base.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/llm/byok_provider.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/llm/classification_context.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/llm/config_store.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/llm/factory.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/llm/kg_enricher.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/llm/local_gateway.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/llm/local_vllm.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/llm/openai_nano.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/lock_advisory.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parser_router.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/docling_parser.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/docparse_gateway.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/docx_parser.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/folder_unpacker.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/gateway_aux.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/image_parser.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/internal_markdown.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/ocr_gateway.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/ocr_pdf_parser.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/pdf_types.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/transcript_parser.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/vision_gateway.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/xlsx_parser.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/parsers/zip_unpacker.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/preflight.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/routing_policy.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/serializers/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/serializers/xlsx_to_markdown.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/skip_log.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/ingest/watcher.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/kg/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/kg/audit.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/kg/communities.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/kg/community_summary.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/kg/graph_lane.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/kg/hybrid_search.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/kg/lens.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/kg/pr_impact.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/kg/queries.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/kg/ranking.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/kg/rrf.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/kg_watcher_control.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/local_llm/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/local_llm/async_client.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/local_llm/client.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/local_llm/url_validator.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/metrics_collector.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/metrics_providers.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/model_registry.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/model_router.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/n8n_client.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/newsletter_llm_gateway.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/notification_service.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/openai_responses.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/opencode_metrics.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/opencode_sessions.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/pii_redactor.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/pr_impact_pipeline/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/pr_impact_pipeline/differ.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/pr_impact_pipeline/dispatcher.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/pr_impact_pipeline/gc.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/pr_impact_pipeline/languages.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/pr_impact_pipeline/parser.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/pr_impact_pipeline/writer.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/pr_service.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/project_paths.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/project_status_updates.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/providers.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/push_service.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/reminder_service.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/runas.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/salience_service.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/security_collector.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/session_catalog.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/session_metrics_service.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/session_ops.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/session_state.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/share_links.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/task_transitions.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/temporal_tiebreak.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/temporal_write.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/terminal_metrics.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/terminal_metrics_dump.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/tmux.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/webhook_service.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/services/workspace_sync.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/templates/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/templates/markdown_share.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/terminal.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_agent_facing_auth_dependencies.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_audit_permissions.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_backfill_session_conversations.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_backfill_working_seconds_msg.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_claude_metrics.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_codex_metrics.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_config_env_aliases.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_finder_paths.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_git_ops_merge.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_learnings_check_search.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_metrics_providers.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_migration_087.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_migration_088.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_migration_089.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_openai_responses.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_opencode_metrics.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_opencode_sessions.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_pr_workflow_e2e.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_projects_handoffs.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_providers.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_require_scope_empty_deny.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_safety_bridge.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_session_catalog.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_session_conversations.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_session_metrics_service.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_session_resume_paths.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_session_theme_mode_migration.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_sessions_rbac.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_share_edit.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_share_repo.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_terminal_session_manager.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_terminal_upload.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_tmux.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_workspace_sync.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/tests/test_ws_ticket_in_memory.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/_context.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/_errors.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/_roles.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/audit.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/brain.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/costs.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/handoffs.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/ingest_triage.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/pull_requests.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/search.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/use_cases/tasks.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/api/visibility.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/README.md +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/_brain_opportunistic.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/_brain_schedule.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/_index_source.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/_runtime_ctx.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/_transmute.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/_update_check.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/guides/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/guides/marvis-way.md +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/marvis_account.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/marvis_brain.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/marvis_feedback.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/marvis_governance.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/marvis_guide.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/marvis_hooks.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/marvis_init.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/marvis_mcp.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/marvis_runtime.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/cli/marvis_telemetry.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/platform/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/_drift_check.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/_frontmatter.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/_graph_writer.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/ast_parser.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/install_hooks/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/install_hooks/_config.sh +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/install_hooks/block-dangerous-bash.sh +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/install_hooks/block-db-direct-write.sh +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/install_hooks/block-push-no-task.sh +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/install_hooks/block-staging-to-prod.sh +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/install_hooks/block-subtree-push.sh +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/install_hooks/config.json +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/install_hooks/enforce-no-merge-main.sh +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/install_hooks/enforce-worktree.sh +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/install_hooks/quality-gate.sh +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/install_hooks/safety_bridge.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/install_hooks/secret-scan.sh +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/migrate_spike_node_ids.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/populate_artifacts.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/populate_cross_project.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/populate_inbox_nodes.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/populate_pr_impact.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/populate_project_nodes.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/populate_touch_counter.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/reparse_failed.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/scripts/safety_bridge.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/telemetry/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/telemetry/client.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/telemetry/entitlements.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/telemetry/rollup.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/telemetry/schema.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/telemetry/sender.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/wizard/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/wizard/byok_vault.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/wizard/defaults.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/wizard/state.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/core/wizard/steps.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/marvisx_cli.egg-info/dependency_links.txt +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/marvisx_cli.egg-info/entry_points.txt +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/marvisx_cli.egg-info/requires.txt +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/marvisx_cli.egg-info/top_level.txt +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/001_initial.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/002_tasks.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/003_session_management.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/004_projects_comments.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/005_session_intelligence.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/006_settings.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/007_task_scoring.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/008_cost_tracking.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/009_session_card_metrics.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/010_monitoring.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/012_agent_api.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/013_session_complete.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/015_pull_requests.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/015_pull_requests_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/016_users_raci.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/017_task_cost_entries.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/018_agents.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/018_agents_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/019_review_feedback.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/020_pr_commit_sha.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/021_webhook_events.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/022_devx_agent_managed.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/022_devx_agent_managed_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/023_devx_p1_gate.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/023_devx_p1_gate_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/024_chat_messages.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/024_pr_conversation_id.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/024_task_indexes.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/024_task_indexes_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/025_audit_log.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/026_agent_tokens.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/027_teams_auth_phase_b.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/028_learnings.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/029_team_roles.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/030_finder_pins.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/031_pr_deploy_status.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/032_task_reminders.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/033_events_retry_count.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/033_session_owner.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/034_notifications.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/035_shared_links.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/036_session_index_upgrade.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/037_pr_approval.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/038_pr_submitted_by.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/039_push_subscriptions.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/040_semantic_search.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/041_workspaces.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/042_oidc_providers.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/043_ci_checks.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/044_agent_metrics.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/045_documents_doc_type.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/046_salience.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/047_seed_missing_agents.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/048_fix_agent_paths_roles.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/049_agent_role_and_learnings_schema.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/050_session_provider.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/051_session_launch_profile.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/052_session_theme_mode.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/052_task_kind.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/053_inbox_items.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/054_inbox_triage_contract.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/055_inbox_topic_treatment.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/056_inbox_treatment_read_save.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/057_session_theme_mode_backfill.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/058_inbox_item_status_lifecycle.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/059_inbox_tldr_and_source_scores.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/060_newsletter.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/061_inbox_redesign.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/062_fix_inbox_sources_backfill.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/063_task_completion_mode.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/064_judge_mode_setting.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/065_knowledge_graph_spike.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/066_digest_ranking_inputs.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/066_kg_artifact_nodes.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/067_inbox_digest_selections.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/067_kg_temporal.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/068_inbox_digest_app_settings.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/068_kg_touch_counter.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/069_kg_doc_types.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/070_digest_ranking_inputs_recovery.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/071_inbox_digest_selections_recovery.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/072_inbox_digest_app_settings_recovery.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/073_kg_cross_project.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/073_kg_cross_project_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/074_kg_infra_types.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/074_kg_infra_types_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/075_kg_file_state_recovery.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/075_kg_file_state_recovery_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/076_kg_watcher_state.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/076_kg_watcher_state_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/077_kg_doc_types_extend.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/077_kg_doc_types_extend_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/078_kg_fts5.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/078_kg_fts5_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/079_kg_missing_indexes.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/079_kg_missing_indexes_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/080_kg_fts5_extended.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/080_kg_fts5_extended_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/081_kg_lens_indexes.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/081_kg_lens_indexes_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/082_kg_pins.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/082_kg_pins_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/083_kg_graph_nodes_degree.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/083_kg_graph_nodes_degree_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/084_drop_legacy_scheduler_tables.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/084_drop_legacy_scheduler_tables_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/085_kg_edge_resolves_to.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/085_kg_edge_resolves_to_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/086_project_status_updates_feed.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/086_project_status_updates_feed_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/087_session_metrics_dual.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/087_session_metrics_dual_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/088_rename_context_pct_legacy.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/088_rename_context_pct_legacy_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/089_session_metrics_equivalent_cost.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/089_session_metrics_equivalent_cost_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/090_kg_inbox_node_type.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/090_kg_inbox_node_type_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/091_kg_inbox_node_type_check.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/091_kg_inbox_node_type_check_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/092_sessions_activity_state_ts.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/092_sessions_activity_state_ts_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/093_sessions_activity_state_column.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/093_sessions_activity_state_column_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/094_ingest_pending.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/094_ingest_pending_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/095_kg_intent_first.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/095_kg_intent_first_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/096_kg_xlsx_artifact_prefix.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/096_kg_xlsx_artifact_prefix_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/097_ingest_change_history.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/097_ingest_change_history_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/098_kg_node_type_business.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/098_kg_node_type_business_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/099_kg_edges_restore_weight.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/099_kg_edges_restore_weight_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/100_kg_enriched_at.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/100_kg_enriched_at_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/101_local_llm_shadow_comparisons.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/101_local_llm_shadow_comparisons_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/102_promote_llm_costs.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/102_promote_llm_costs_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/103_ingest_skipped_log.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/103_ingest_skipped_log_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/120_docs_governance.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/120_docs_governance_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/121_notification_event_fk_cleanup.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/121_notification_event_fk_cleanup_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/122_docs_drift_history.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/122_docs_drift_history_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/123_ingest_parser_waiting_status.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/123_ingest_parser_waiting_status_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/124_heypocket_recordings.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/124_heypocket_recordings_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/125_kg_node_type_record.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/125_kg_node_type_record_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/126_ingest_terminal_upload_source_kind.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/126_ingest_terminal_upload_source_kind_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/127_brain_v1_substrate.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/127_brain_v1_substrate_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/128_brain_drift_signals.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/128_brain_drift_signals_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/129_brain_memory_operations.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/129_brain_memory_operations_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/130_brain_findings.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/130_brain_findings_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/132_kg_pr_modifies.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/132_kg_pr_modifies_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/133_brain_v1_2_direction_schema.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/133_brain_v1_2_direction_schema_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/134_brain_journal_narrative_polished.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/134_brain_journal_narrative_polished_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/135_kg_edges_provider.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/136_documents_fts.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/137_promote_llm_costs.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/137_promote_llm_costs_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/138_ingest_api_keys.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/138_ingest_api_keys_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/139_ingest_pending_ingress.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/139_ingest_pending_ingress_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/140_ingest_idempotency_quota.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/140_ingest_idempotency_quota_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/141_ingest_pending_metadata.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/141_ingest_pending_metadata_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/142_llm_function_config.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/142_llm_function_config_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/143_kg_code_embeddings.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/143_kg_code_embeddings_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/144_notifications_pending_sync_index.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/145_audit_log_immutable.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/145_audit_log_immutable_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/146_drop_kg_backup_tables.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/146_drop_kg_backup_tables_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/147_chunks.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/147_chunks_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/148_bitemporal_learnings.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/148_bitemporal_learnings_down.sql +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/migrations/__init__.py +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/projects/_template/context.md +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/projects/_template/docs/brainstorms/YYYY-MM-DD-example-brainstorm.md +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/projects/_template/docs/plans/YYYY-MM-DD-example-plan.md +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/projects/_template/docs/solutions/YYYY-MM-DD-example-solution.md +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/projects/_template/input/README.md +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/projects/_template/memory/handoff.md +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/projects/_template/output/README.md +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/projects/_template/project.yaml +0 -0
- {marvisx_cli-0.3.8b1 → marvisx_cli-0.3.8b3}/setup.cfg +0 -0
|
@@ -453,6 +453,13 @@ class Settings(BaseSettings):
|
|
|
453
453
|
graph_lane_weight: float = Field(
|
|
454
454
|
default=0.12, alias="MARVIS_GRAPH_LANE_WEIGHT"
|
|
455
455
|
)
|
|
456
|
+
# #13: when a graph read finds its index stale/behind HEAD, surface the
|
|
457
|
+
# reindex as an EXPLICIT next action (command + auto_reindex marker). Default
|
|
458
|
+
# off; even when on, a read NEVER fires the (heavy, repo-re-parsing) KG
|
|
459
|
+
# reindex itself — re-indexing stays an explicit operation.
|
|
460
|
+
graph_autoreindex_on_drift: bool = Field(
|
|
461
|
+
default=False, alias="MARVIS_GRAPH_AUTOREINDEX_ON_DRIFT"
|
|
462
|
+
)
|
|
456
463
|
|
|
457
464
|
# Track 2 #1 — bi-temporal memory READ path (DEFAULT OFF). When False every
|
|
458
465
|
# learnings read is byte-identical to today (no invalid_at filter, no as_of):
|
|
@@ -118,6 +118,13 @@ async def init_pool(size: int = 2) -> None:
|
|
|
118
118
|
|
|
119
119
|
Pool size=8 supports concurrent deep=true requests (4 parallel KG subqueries × 2 concurrent requests).
|
|
120
120
|
"""
|
|
121
|
+
# Apply any pending schema migrations before opening the pool, so EVERY
|
|
122
|
+
# entry point (CLI, MCP, brain, API) lands on a current schema — not only
|
|
123
|
+
# `marvis init` and the API lifespan. Idempotent and cheap when already
|
|
124
|
+
# current (the API path migrates explicitly first, so this finds nothing).
|
|
125
|
+
# Fail-loud here is a clearer signal than a later "no such column" on the
|
|
126
|
+
# first write against a half-upgraded DB. (#12)
|
|
127
|
+
run_migrations()
|
|
121
128
|
global _pool, _pool_size, _writer
|
|
122
129
|
actual_size = 8 # read-only pool: expanded for KG lens 4-subquery parallel pattern (Phase 7.0)
|
|
123
130
|
_pool = asyncio.Queue(maxsize=actual_size)
|
|
@@ -732,54 +739,62 @@ def _backfill_session_uuids(conn: sqlite3.Connection) -> None:
|
|
|
732
739
|
|
|
733
740
|
|
|
734
741
|
def _seed_users_and_migrate_owner(conn: sqlite3.Connection) -> None:
|
|
735
|
-
"""Migration 016 post-hook: seed the admin user + data-migrate
|
|
742
|
+
"""Migration 016 post-hook: seed the admin user (when configured) + data-migrate
|
|
743
|
+
tasks.owner_id.
|
|
736
744
|
|
|
737
745
|
Runs synchronously inside run_migrations() — do NOT use await here.
|
|
738
|
-
Accepts either PIR_ADMIN_PASSWORD_HASH (pre-hashed, preferred in production)
|
|
739
|
-
or PIR_PASSWORD (plaintext, will be bcrypt-hashed here).
|
|
740
|
-
At least one must be set or the migration aborts.
|
|
741
|
-
|
|
742
|
-
The admin identity is config-driven via the same MARVIS_ADMIN_* vars used by
|
|
743
|
-
the deploy bootstrap (scripts/init.sh), with generic defaults, so a fresh
|
|
744
|
-
install seeds no hardcoded name. On an existing deployment this seed is
|
|
745
|
-
skipped (users already exist), so the defaults never affect a running install.
|
|
746
|
-
"""
|
|
747
|
-
# Prefer pre-hashed password. Canonical var is MARVIS_ADMIN_PASSWORD_HASH;
|
|
748
|
-
# PIR_ADMIN_PASSWORD_HASH stays accepted as a deprecated alias.
|
|
749
|
-
hashed = (
|
|
750
|
-
os.environ.get("MARVIS_ADMIN_PASSWORD_HASH")
|
|
751
|
-
or os.environ.get("PIR_ADMIN_PASSWORD_HASH", "")
|
|
752
|
-
).strip()
|
|
753
|
-
if not hashed:
|
|
754
|
-
import bcrypt
|
|
755
|
-
|
|
756
|
-
seed_password = (
|
|
757
|
-
os.environ.get("MARVIS_PASSWORD")
|
|
758
|
-
or os.environ.get("PIR_PASSWORD", "")
|
|
759
|
-
).strip()
|
|
760
|
-
if not seed_password:
|
|
761
|
-
raise RuntimeError(
|
|
762
|
-
"Migration 016 requires MARVIS_ADMIN_PASSWORD_HASH or MARVIS_PASSWORD "
|
|
763
|
-
"env var (PIR_* aliases still accepted) to seed the admin user. "
|
|
764
|
-
"Set at least one in .env."
|
|
765
|
-
)
|
|
766
|
-
hashed = bcrypt.hashpw(seed_password.encode("utf-8"), bcrypt.gensalt()).decode()
|
|
767
|
-
|
|
768
|
-
admin_id = os.environ.get("MARVIS_ADMIN_USER_ID", "").strip() or "usr_admin"
|
|
769
|
-
admin_slug = os.environ.get("MARVIS_ADMIN_SLUG", "").strip() or "admin"
|
|
770
|
-
admin_name = os.environ.get("MARVIS_ADMIN_DISPLAY_NAME", "").strip() or "Admin"
|
|
771
746
|
|
|
747
|
+
Admin seeding is OPTIONAL and config-driven: the admin user is created only when
|
|
748
|
+
a real credential is present (MARVIS_ADMIN_PASSWORD_HASH or MARVIS_PASSWORD; PIR_*
|
|
749
|
+
aliases accepted). With NO credential — the OSS single-user case, where the CLI
|
|
750
|
+
uses the local single-user context and never logs in with a password — the seed
|
|
751
|
+
is SKIPPED (not aborted), so a fresh-DB boot via init_pool (MCP server / brain,
|
|
752
|
+
which now run migrations) does not crash on a clean install. `marvis init` sets
|
|
753
|
+
MARVIS_PASSWORD before migrating, so it still seeds the admin. The owner_id
|
|
754
|
+
slug→id data migration always runs (idempotent), regardless of seeding.
|
|
755
|
+
|
|
756
|
+
b3 note: the real cleanup is to decouple admin seeding from run_migrations
|
|
757
|
+
entirely — it belongs in `marvis init` / `marvis account`, not in a schema hook.
|
|
758
|
+
"""
|
|
772
759
|
cursor = conn.execute("SELECT COUNT(*) FROM users")
|
|
773
760
|
user_count = cursor.fetchone()[0]
|
|
774
761
|
if user_count == 0:
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
"
|
|
779
|
-
(
|
|
780
|
-
)
|
|
781
|
-
|
|
782
|
-
|
|
762
|
+
# Prefer a pre-hashed password (canonical MARVIS_ADMIN_PASSWORD_HASH;
|
|
763
|
+
# PIR_ADMIN_PASSWORD_HASH stays a deprecated alias).
|
|
764
|
+
hashed = (
|
|
765
|
+
os.environ.get("MARVIS_ADMIN_PASSWORD_HASH")
|
|
766
|
+
or os.environ.get("PIR_ADMIN_PASSWORD_HASH", "")
|
|
767
|
+
).strip()
|
|
768
|
+
if not hashed:
|
|
769
|
+
seed_password = (
|
|
770
|
+
os.environ.get("MARVIS_PASSWORD")
|
|
771
|
+
or os.environ.get("PIR_PASSWORD", "")
|
|
772
|
+
).strip()
|
|
773
|
+
if seed_password:
|
|
774
|
+
import bcrypt
|
|
775
|
+
|
|
776
|
+
hashed = bcrypt.hashpw(
|
|
777
|
+
seed_password.encode("utf-8"), bcrypt.gensalt()
|
|
778
|
+
).decode()
|
|
779
|
+
else:
|
|
780
|
+
logger.warning(
|
|
781
|
+
"Migration 016: no MARVIS_ADMIN_PASSWORD_HASH / MARVIS_PASSWORD in "
|
|
782
|
+
"env — admin user NOT seeded (schema applied). Single-user CLI uses "
|
|
783
|
+
"the local context (no login); create an admin later with `marvis "
|
|
784
|
+
"init` if you want HTTP login."
|
|
785
|
+
)
|
|
786
|
+
if hashed: # seed ONLY when we actually have a credential
|
|
787
|
+
admin_id = os.environ.get("MARVIS_ADMIN_USER_ID", "").strip() or "usr_admin"
|
|
788
|
+
admin_slug = os.environ.get("MARVIS_ADMIN_SLUG", "").strip() or "admin"
|
|
789
|
+
admin_name = os.environ.get("MARVIS_ADMIN_DISPLAY_NAME", "").strip() or "Admin"
|
|
790
|
+
conn.execute(
|
|
791
|
+
"INSERT OR IGNORE INTO users "
|
|
792
|
+
"(id, slug, display_name, type, password_hash, system_role) "
|
|
793
|
+
"VALUES (?, ?, ?, ?, ?, ?)",
|
|
794
|
+
(admin_id, admin_slug, admin_name, "human", hashed, "super_admin"),
|
|
795
|
+
)
|
|
796
|
+
conn.commit()
|
|
797
|
+
logger.info("Migration 016: seeded admin user '%s' (super_admin)", admin_slug)
|
|
783
798
|
|
|
784
799
|
# Data migration: owner_id may contain slug strings (e.g. "emilio") from before
|
|
785
800
|
# the users table existed. Resolve each slug to the corresponding users.id.
|
|
@@ -931,6 +931,20 @@ async def _periodic_inbox_digest() -> None:
|
|
|
931
931
|
result.get("overflow", 0),
|
|
932
932
|
result.get("expired", 0),
|
|
933
933
|
)
|
|
934
|
+
# Invariant guard: every VISIBLE item must be deepened. The 6 UTC
|
|
935
|
+
# precompute is best-effort/one-shot; this sweep catches its failures
|
|
936
|
+
# and items promoted into visible later in the day.
|
|
937
|
+
from core.api.services.inbox_digest_deep_research import (
|
|
938
|
+
sweep_visible_missing_deep_research,
|
|
939
|
+
)
|
|
940
|
+
|
|
941
|
+
sweep = await sweep_visible_missing_deep_research()
|
|
942
|
+
if sweep.get("missing"):
|
|
943
|
+
logger.info(
|
|
944
|
+
"Digest deep-research sweep: deepened %d/%d missing visible items",
|
|
945
|
+
sweep.get("generated", 0),
|
|
946
|
+
sweep.get("missing", 0),
|
|
947
|
+
)
|
|
934
948
|
except asyncio.CancelledError:
|
|
935
949
|
break
|
|
936
950
|
except Exception:
|
|
@@ -34,10 +34,54 @@ from core.api.mcp.tools import register_all
|
|
|
34
34
|
# `app.state` equivalent for a server with no FastAPI `app`). Tools register on
|
|
35
35
|
# this at import time so `from core.api.mcp.server import mcp` already carries the
|
|
36
36
|
# full tool set — the smoke test introspects it without launching stdio.
|
|
37
|
-
|
|
37
|
+
_INSTRUCTIONS = (
|
|
38
|
+
"Marvis is a company-brain MCP for cross-project orchestration and institutional memory.\n"
|
|
39
|
+
"Route by task type (prefer these structured tools over re-deriving context from raw files):\n"
|
|
40
|
+
"- Cold-start / 'state of project X': session_brief(slug) — it also suggests the next tool when the project is cross-project.\n"
|
|
41
|
+
"- 'If I pause / close / de-prioritize project X, what blocks?': project_impact(slug) — the project-level blast radius. "
|
|
42
|
+
"(graph_impact on a 'project:artifact:<slug>' node with depends_on does the same.)\n"
|
|
43
|
+
"- 'What breaks if I change function X' (code level): graph_impact / graph_neighbors on a 'py:function:...' node.\n"
|
|
44
|
+
"- 'What do we already know / what bit us before' (decisions and risky actions): check_learnings(q).\n"
|
|
45
|
+
"- Cross-project discovery by meaning: search(q). Body of ONE known project: get_project(slug) — do not layer search on top of get_project.\n"
|
|
46
|
+
"Before answering an orchestration or planning task, confirm you actually called the relevant "
|
|
47
|
+
"tool (session_brief / project_impact / graph_impact) AND that your answer addresses the task "
|
|
48
|
+
"as asked — do not reply from raw files or pivot to an unrelated skill.\n"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
mcp = FastMCP("marvis", instructions=_INSTRUCTIONS)
|
|
38
52
|
|
|
39
53
|
register_all(mcp)
|
|
40
54
|
|
|
55
|
+
# mcp-ergonomics (tiering): mark the cold-start core always-loaded so clients with
|
|
56
|
+
# MCP tool-search (e.g. Claude Code — the agent that drives the brain) keep these in
|
|
57
|
+
# context and defer the other ~60 tools on demand. A 70-tool surface is well over the
|
|
58
|
+
# ~20-30 threshold where tool-selection accuracy degrades. Additive: clients without
|
|
59
|
+
# tool-search still see every tool (no regression). Best-effort — a FastMCP registry
|
|
60
|
+
# shape change degrades to a no-op, never a boot failure.
|
|
61
|
+
_CORE_TOOLS = frozenset(
|
|
62
|
+
{
|
|
63
|
+
"session_brief",
|
|
64
|
+
"search",
|
|
65
|
+
"check_learnings",
|
|
66
|
+
"list_tasks",
|
|
67
|
+
"get_task",
|
|
68
|
+
"create_task",
|
|
69
|
+
"update_task",
|
|
70
|
+
"get_project",
|
|
71
|
+
"graph_impact",
|
|
72
|
+
"graph_neighbors",
|
|
73
|
+
"project_impact",
|
|
74
|
+
}
|
|
75
|
+
)
|
|
76
|
+
try:
|
|
77
|
+
for _name, _tool in mcp._tool_manager._tools.items():
|
|
78
|
+
if _name in _CORE_TOOLS:
|
|
79
|
+
_m = dict(_tool.meta or {})
|
|
80
|
+
_m["anthropic/alwaysLoad"] = True
|
|
81
|
+
_tool.meta = _m
|
|
82
|
+
except Exception: # pragma: no cover - FastMCP internal-shape guard
|
|
83
|
+
pass
|
|
84
|
+
|
|
41
85
|
|
|
42
86
|
def main() -> None:
|
|
43
87
|
"""Run the MCP server over stdio (the OSS runtime entrypoint).
|
|
@@ -123,10 +123,10 @@ def register(mcp) -> None:
|
|
|
123
123
|
rank: NeighborRank = "none",
|
|
124
124
|
as_of: Annotated[str, Field(pattern=_AS_OF_PATTERN, max_length=32)] | None = None,
|
|
125
125
|
) -> dict[str, Any]:
|
|
126
|
-
"""
|
|
127
|
-
|
|
128
|
-
QUANDO
|
|
129
|
-
RESTITUISCE: list of {node_id, relation, direction, rank_score
|
|
126
|
+
"""1-hop: chi tocca / dipende direttamente da un nodo. Funziona su codice ('py:function:...') E su progetti ('project:artifact:<slug>').
|
|
127
|
+
ORCHESTRAZIONE: per i vicini diretti di un PROGETTO (chi dipende da X) passa node_id='project:artifact:<slug>' con edge_types=['depends_on']. Codice: caller/callee 1-hop di una function.
|
|
128
|
+
QUANDO USARLO: vicinato diretto senza il bundle completo; caller inattesi; time-travel as_of; rank=suspect_write per bug write-through-read. Per il blast radius transitivo usa graph_impact / project_impact.
|
|
129
|
+
RESTITUISCE: list of {node_id, relation, direction, rank_score?, freshness} cap 200."""
|
|
130
130
|
try:
|
|
131
131
|
async with acquire_db() as db:
|
|
132
132
|
# Node proxy hardcodes limit=200 (the surface exposes no limit param).
|
|
@@ -152,7 +152,7 @@ def register(mcp) -> None:
|
|
|
152
152
|
limit: Annotated[int, Field(ge=1, le=100)] = 20,
|
|
153
153
|
type_filter: HotspotTypeFilter = "file",
|
|
154
154
|
) -> dict[str, Any]:
|
|
155
|
-
"""
|
|
155
|
+
"""DORA-style churn ranking: files/functions sorted by touch_count 7d/30d with bus-factor warning — per context completo su un progetto usa get_project(deep=true). Usa questo tool per analisi architetturale di rischio o pianificazione refactor.
|
|
156
156
|
QUANDO USARLO: identificare moduli ad alto rischio prima di una release; trovare ownership gaps (bus_factor=1); pianificare tech debt.
|
|
157
157
|
QUANDO NON USARLO: NOT per context di un progetto specifico -> usa get_project(deep=true). NOT per BFS da un nodo -> usa graph_impact.
|
|
158
158
|
RESTITUISCE: list of {node_id, touch_count_7d, touch_count_30d, authors[], bus_factor} top N."""
|
|
@@ -178,10 +178,10 @@ def register(mcp) -> None:
|
|
|
178
178
|
edge_types: list[EdgeType] | None = None,
|
|
179
179
|
project: Annotated[str, Field(max_length=50, pattern=_PROJECT_PATTERN)] | None = None,
|
|
180
180
|
) -> dict[str, Any]:
|
|
181
|
-
"""
|
|
182
|
-
|
|
183
|
-
QUANDO
|
|
184
|
-
RESTITUISCE: {
|
|
181
|
+
"""Impact / blast radius: 'cosa si rompe — o quali progetti si bloccano — se cambio / pauso / chiudo X?'. BFS sui rami transitivi + ranker sui diretti.
|
|
182
|
+
ORCHESTRAZIONE DI PORTAFOGLIO: per sapere quali PROGETTI si bloccano se pausi/chiudi un progetto, passa node_id='project:artifact:<slug>' con edge_types=['depends_on','mentions','refers_to'] — oppure usa il tool dedicato project_impact(slug). Livello-codice: per 'cosa si rompe se cambio questa function' passa un node 'py:function:...'.
|
|
183
|
+
QUANDO USARLO: prima di pausare/chiudere/de-prioritizzare un progetto (blast radius cross-project); prima di eliminare/rinominare una function critica; dependency cascade analysis; sequenziare lavoro (cosa sblocca cosa).
|
|
184
|
+
RESTITUISCE: {direct (callers/dependents)[], transitive_list[], rank_score, freshness (indexed_sha vs HEAD)} depth configurabile."""
|
|
185
185
|
try:
|
|
186
186
|
async with acquire_db() as db:
|
|
187
187
|
result = await graph_uc.graph_impact(
|
|
@@ -197,15 +197,38 @@ def register(mcp) -> None:
|
|
|
197
197
|
except ServiceError as e:
|
|
198
198
|
raise_mcp_error(e)
|
|
199
199
|
|
|
200
|
+
@mcp.tool()
|
|
201
|
+
async def project_impact(
|
|
202
|
+
slug: Annotated[str, Field(max_length=50, pattern=_PROJECT_PATTERN)],
|
|
203
|
+
depth: Annotated[int, Field(ge=1, le=5)] = 2,
|
|
204
|
+
) -> dict[str, Any]:
|
|
205
|
+
"""Portfolio blast radius: 'se pauso / chiudo / de-prioritizzo questo PROGETTO, quali altri progetti si bloccano?'. Il tool di prima classe per l'orchestrazione cross-progetto — distinto dal grafo-codice.
|
|
206
|
+
Risolve 'project:artifact:<slug>' e fa l'impact BFS sui soli edge progetto->progetto (depends_on / mentions / refers_to). La response porta il segnale freshness (indexed_sha vs HEAD) per non fidarsi di un indice stantio.
|
|
207
|
+
QUANDO USARLO: prima di pausare/chiudere/de-prioritizzare un progetto; sequenziare un portafoglio (cosa sblocca cosa); capire le dipendenze cross-progetto di una decisione.
|
|
208
|
+
RESTITUISCE: {direct_dependents[], transitive_list[], rank_score, freshness}."""
|
|
209
|
+
try:
|
|
210
|
+
async with acquire_db() as db:
|
|
211
|
+
result = await graph_uc.graph_impact(
|
|
212
|
+
LOCAL_CTX,
|
|
213
|
+
db,
|
|
214
|
+
node_id=f"project:artifact:{slug}",
|
|
215
|
+
depth=depth,
|
|
216
|
+
limit=100,
|
|
217
|
+
edge_types=["depends_on", "mentions", "refers_to"],
|
|
218
|
+
project=None,
|
|
219
|
+
)
|
|
220
|
+
return dump(result)
|
|
221
|
+
except ServiceError as e:
|
|
222
|
+
raise_mcp_error(e)
|
|
223
|
+
|
|
200
224
|
@mcp.tool()
|
|
201
225
|
async def graph_context(
|
|
202
226
|
node_id: Annotated[str, Field(pattern=_NODE_ID_PATTERN, max_length=256)],
|
|
203
227
|
per_category_limit: Annotated[int, Field(ge=1, le=20)] = 5,
|
|
204
228
|
project: Annotated[str, Field(max_length=50, pattern=_PROJECT_PATTERN)] | None = None,
|
|
205
229
|
) -> dict[str, Any]:
|
|
206
|
-
"""
|
|
207
|
-
QUANDO USARLO:
|
|
208
|
-
QUANDO NON USARLO: NOT per workflow standard su task/handoff -> usa get_*(deep=true). NOT per vicinato topologico -> usa graph_neighbors.
|
|
230
|
+
"""Rationale chain di un nodo: function/progetto → commit → PR → task → handoff → learning in 1 call. Il PERCHE' dietro qualcosa.
|
|
231
|
+
QUANDO USARLO: perche' esiste / da dove viene una function o una decisione di progetto; audit trail; linkare codice o progetto a un decision record.
|
|
209
232
|
RESTITUISCE: chain {commits[], PR?, task?, handoffs[], learnings[]} per_category_limit configurabile."""
|
|
210
233
|
try:
|
|
211
234
|
async with acquire_db() as db:
|
|
@@ -225,7 +248,7 @@ def register(mcp) -> None:
|
|
|
225
248
|
scope: Annotated[str, Field(max_length=256)],
|
|
226
249
|
limit: Annotated[int, Field(ge=1, le=100)] = 20,
|
|
227
250
|
) -> dict[str, Any]:
|
|
228
|
-
"""
|
|
251
|
+
"""Learnings scoped a un modulo/path specifico via KG — per learnings generici usa check_learnings. Usa questo tool per learnings chirurgici su un file/modulo specifico prima di toccare codice in quella area.
|
|
229
252
|
QUANDO USARLO: 'quali learnings esistono per api.db?' prima di toccare il DB module; scoping pre-deployment di un servizio specifico.
|
|
230
253
|
QUANDO NON USARLO: NOT per ricerca semantica generica pre-azione -> usa check_learnings. NOT per context di un nodo -> usa graph_context.
|
|
231
254
|
RESTITUISCE: list of {learning_id, title, prevention, severity, scope_match_score}."""
|
|
@@ -240,7 +263,7 @@ def register(mcp) -> None:
|
|
|
240
263
|
|
|
241
264
|
@mcp.tool()
|
|
242
265
|
async def graph_capabilities() -> dict[str, Any]:
|
|
243
|
-
"""
|
|
266
|
+
"""KG schema metadata per agent discovery (edge_types + node_kinds + prefixes + versions).
|
|
244
267
|
QUANDO USARLO: prima di costruire query graph_* o validare node_id pattern; cold-start agent discovery.
|
|
245
268
|
QUANDO NON USARLO: per query topologiche -> usa graph_neighbors/impact/context.
|
|
246
269
|
RESTITUISCE: {edge_types[], node_kinds[], node_prefixes[], schema_version}.
|
|
@@ -47,10 +47,10 @@ def register(mcp) -> None:
|
|
|
47
47
|
q: Annotated[str, Field(min_length=1, max_length=500)],
|
|
48
48
|
module: str | None = None,
|
|
49
49
|
) -> dict[str, Any]:
|
|
50
|
-
"""
|
|
50
|
+
"""Cosa sappiamo gia' / cosa ci ha morso: cerca nei learnings (post-mortem + regole di prevenzione) prima di una decisione o di un'azione.
|
|
51
51
|
|
|
52
|
-
QUANDO USARLO:
|
|
53
|
-
QUANDO NON USARLO:
|
|
52
|
+
QUANDO USARLO: prima di qualunque azione production-affecting (deploy, migration, auth change, push, dependency upgrade); E prima di una DECISIONE o di un piano (per non ripetere errori noti e riusare cio' che ha funzionato). Non e' solo un gate pre-deploy: e' la memoria istituzionale a cui attingere quando ragioni. BOUNDARY: create_learning scrive nuovo; check_learnings = semantic match sulla situazione; list_learnings = enumerazione filtrata.
|
|
53
|
+
QUANDO NON USARLO: se hai gia' un file/module path e vuoi learnings scoped -> graph_pattern. Per scrivere un nuovo learning -> create_learning.
|
|
54
54
|
RESTITUISCE: list of {id, title, prevention, severity, module} ranked per rilevanza."""
|
|
55
55
|
try:
|
|
56
56
|
async with acquire_db() as db:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# v1.1.0 - 2026-04-14 - Single-writer: reclassify_inbox_items uses get_write_db (batch 5/6)
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
|
+
import asyncio
|
|
4
5
|
import logging
|
|
5
6
|
import time
|
|
6
7
|
from collections import defaultdict
|
|
@@ -62,6 +63,20 @@ from core.api.services.inbox_triage import (
|
|
|
62
63
|
|
|
63
64
|
logger = logging.getLogger(__name__)
|
|
64
65
|
|
|
66
|
+
|
|
67
|
+
# Strong refs to fire-and-forget on-read deep-research sweeps so the event loop
|
|
68
|
+
# does not garbage-collect them mid-flight; discarded when each completes.
|
|
69
|
+
_background_sweeps: set[asyncio.Task] = set()
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _on_sweep_done(task: asyncio.Task) -> None:
|
|
73
|
+
_background_sweeps.discard(task)
|
|
74
|
+
if task.cancelled():
|
|
75
|
+
return
|
|
76
|
+
exc = task.exception()
|
|
77
|
+
if exc is not None:
|
|
78
|
+
logger.warning("on-read digest deep-research sweep failed: %s", exc)
|
|
79
|
+
|
|
65
80
|
router = APIRouter(prefix="/api/v1/inbox", tags=["inbox"])
|
|
66
81
|
|
|
67
82
|
# ---------------------------------------------------------------------------
|
|
@@ -306,13 +321,26 @@ async def get_current_digest_items(
|
|
|
306
321
|
db: aiosqlite.Connection = Depends(get_db),
|
|
307
322
|
) -> list[dict]:
|
|
308
323
|
workspace_id = user.workspace_id or "ws_default"
|
|
309
|
-
|
|
324
|
+
items = await list_digest_items(
|
|
310
325
|
db,
|
|
311
326
|
workspace_id,
|
|
312
327
|
state="visible",
|
|
313
328
|
domain_key=domain_key,
|
|
314
329
|
limit=limit,
|
|
315
330
|
)
|
|
331
|
+
# On-read safety net (A): kick off deepening of any visible item still
|
|
332
|
+
# missing deep research, non-blocking, so it is ready by the time the user
|
|
333
|
+
# opens it. Idempotent + lock-guarded (no overlap with the scheduler sweep).
|
|
334
|
+
from core.api.services.inbox_digest_deep_research import (
|
|
335
|
+
sweep_visible_missing_deep_research,
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
sweep_task = asyncio.create_task(
|
|
339
|
+
sweep_visible_missing_deep_research(workspace_id=workspace_id)
|
|
340
|
+
)
|
|
341
|
+
_background_sweeps.add(sweep_task)
|
|
342
|
+
sweep_task.add_done_callback(_on_sweep_done)
|
|
343
|
+
return items
|
|
316
344
|
|
|
317
345
|
|
|
318
346
|
@router.get("/digest/overflow")
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import logging
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from fastapi import HTTPException
|
|
8
|
+
|
|
9
|
+
from core.api.services.inbox_tldr import get_or_generate_deep_research
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
# Serializes the on-read trigger and the periodic scheduler so two sweeps never
|
|
14
|
+
# overlap and hammer the gateway for the same items.
|
|
15
|
+
_sweep_lock = asyncio.Lock()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
async def precompute_deep_research_for_items(
|
|
19
|
+
*,
|
|
20
|
+
inbox_item_ids: list[str],
|
|
21
|
+
workspace_id: str,
|
|
22
|
+
cycle_key: str,
|
|
23
|
+
concurrency: int = 1,
|
|
24
|
+
allow_cloud_fallback: bool = False,
|
|
25
|
+
) -> dict[str, Any]:
|
|
26
|
+
"""Best-effort Deep Analysis precompute for a prepared digest cycle."""
|
|
27
|
+
stats: dict[str, Any] = {
|
|
28
|
+
"cycle_key": cycle_key,
|
|
29
|
+
"attempted": 0,
|
|
30
|
+
"generated": 0,
|
|
31
|
+
"cached": 0,
|
|
32
|
+
"failed": 0,
|
|
33
|
+
"skipped": 0,
|
|
34
|
+
"errors": [],
|
|
35
|
+
}
|
|
36
|
+
item_ids = [item_id for item_id in inbox_item_ids if item_id]
|
|
37
|
+
stats["skipped"] = len(inbox_item_ids) - len(item_ids)
|
|
38
|
+
if not item_ids:
|
|
39
|
+
return stats
|
|
40
|
+
|
|
41
|
+
semaphore = asyncio.Semaphore(max(1, concurrency))
|
|
42
|
+
|
|
43
|
+
async def precompute_one(item_id: str) -> None:
|
|
44
|
+
async with semaphore:
|
|
45
|
+
stats["attempted"] += 1
|
|
46
|
+
try:
|
|
47
|
+
result = await get_or_generate_deep_research(
|
|
48
|
+
item_id,
|
|
49
|
+
workspace_id,
|
|
50
|
+
force=False,
|
|
51
|
+
allow_cloud_fallback=allow_cloud_fallback,
|
|
52
|
+
)
|
|
53
|
+
except HTTPException as exc:
|
|
54
|
+
stats["failed"] += 1
|
|
55
|
+
stats["errors"].append(
|
|
56
|
+
{"item_id": item_id, "status_code": exc.status_code}
|
|
57
|
+
)
|
|
58
|
+
logger.warning(
|
|
59
|
+
"Digest Deep Analysis precompute failed for %s cycle=%s status=%s",
|
|
60
|
+
item_id,
|
|
61
|
+
cycle_key,
|
|
62
|
+
exc.status_code,
|
|
63
|
+
)
|
|
64
|
+
return
|
|
65
|
+
except Exception as exc:
|
|
66
|
+
stats["failed"] += 1
|
|
67
|
+
stats["errors"].append(
|
|
68
|
+
{"item_id": item_id, "error": type(exc).__name__}
|
|
69
|
+
)
|
|
70
|
+
logger.warning(
|
|
71
|
+
"Digest Deep Analysis precompute failed for %s cycle=%s: %s",
|
|
72
|
+
item_id,
|
|
73
|
+
cycle_key,
|
|
74
|
+
exc,
|
|
75
|
+
)
|
|
76
|
+
return
|
|
77
|
+
|
|
78
|
+
if result.get("cached"):
|
|
79
|
+
stats["cached"] += 1
|
|
80
|
+
else:
|
|
81
|
+
stats["generated"] += 1
|
|
82
|
+
|
|
83
|
+
await asyncio.gather(*(precompute_one(item_id) for item_id in item_ids))
|
|
84
|
+
return stats
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
async def sweep_visible_missing_deep_research(
|
|
88
|
+
*,
|
|
89
|
+
workspace_id: str = "ws_default",
|
|
90
|
+
limit: int = 50,
|
|
91
|
+
) -> dict[str, Any]:
|
|
92
|
+
"""Deepen any current-cycle VISIBLE digest item still missing deep research.
|
|
93
|
+
|
|
94
|
+
Enforces the invariant "an item shown in the daily visible digest must be
|
|
95
|
+
deepened". Catches both 6 UTC precompute failures (gateway slow/down, no
|
|
96
|
+
retry) and items promoted into the visible set later in the day. Idempotent
|
|
97
|
+
(only targets rows where deep_research is NULL/empty) and serialized by
|
|
98
|
+
``_sweep_lock`` so the periodic scheduler and the on-read trigger never run
|
|
99
|
+
overlapping sweeps. Honors the same digest settings as the 6 UTC run
|
|
100
|
+
(mode/deep_research_enabled/concurrency/allow_cloud_fallback).
|
|
101
|
+
"""
|
|
102
|
+
if _sweep_lock.locked():
|
|
103
|
+
return {"status": "already_running", "attempted": 0}
|
|
104
|
+
|
|
105
|
+
async with _sweep_lock:
|
|
106
|
+
from core.api.db import acquire_db
|
|
107
|
+
from core.api.services.inbox_digest import get_current_digest_cycle_key
|
|
108
|
+
from core.api.services.inbox_digest_jobs import _load_digest_settings
|
|
109
|
+
|
|
110
|
+
async with acquire_db() as db:
|
|
111
|
+
settings = await _load_digest_settings(db)
|
|
112
|
+
if settings.mode == "false" or not settings.deep_research_enabled:
|
|
113
|
+
return {"status": "disabled", "attempted": 0}
|
|
114
|
+
cycle_key = await get_current_digest_cycle_key(db, workspace_id)
|
|
115
|
+
|
|
116
|
+
where = ["s.workspace_id = ?", "s.state = 'visible'"]
|
|
117
|
+
params: list[Any] = [workspace_id]
|
|
118
|
+
if cycle_key:
|
|
119
|
+
where.append("s.digest_cycle_key = ?")
|
|
120
|
+
params.append(cycle_key)
|
|
121
|
+
params.append(limit)
|
|
122
|
+
rows = await (
|
|
123
|
+
await db.execute(
|
|
124
|
+
"SELECT s.inbox_item_id FROM inbox_digest_selections s "
|
|
125
|
+
"JOIN inbox_items i ON i.id = s.inbox_item_id "
|
|
126
|
+
f"WHERE {' AND '.join(where)} "
|
|
127
|
+
"AND (i.deep_research IS NULL OR i.deep_research = '') "
|
|
128
|
+
"ORDER BY s.rank_in_domain ASC LIMIT ?",
|
|
129
|
+
tuple(params),
|
|
130
|
+
)
|
|
131
|
+
).fetchall()
|
|
132
|
+
|
|
133
|
+
missing_ids = [row[0] for row in rows]
|
|
134
|
+
if not missing_ids:
|
|
135
|
+
return {"status": "ok", "attempted": 0, "missing": 0}
|
|
136
|
+
|
|
137
|
+
stats = await precompute_deep_research_for_items(
|
|
138
|
+
inbox_item_ids=missing_ids,
|
|
139
|
+
workspace_id=workspace_id,
|
|
140
|
+
cycle_key=cycle_key or "sweep",
|
|
141
|
+
concurrency=settings.concurrency,
|
|
142
|
+
allow_cloud_fallback=settings.allow_cloud_fallback,
|
|
143
|
+
)
|
|
144
|
+
stats["status"] = "ok"
|
|
145
|
+
stats["missing"] = len(missing_ids)
|
|
146
|
+
logger.info(
|
|
147
|
+
"Digest deep-research sweep: %d visible missing -> generated=%d cached=%d failed=%d",
|
|
148
|
+
len(missing_ids),
|
|
149
|
+
stats.get("generated", 0),
|
|
150
|
+
stats.get("cached", 0),
|
|
151
|
+
stats.get("failed", 0),
|
|
152
|
+
)
|
|
153
|
+
return stats
|