marvisx-cli 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- marvisx_cli-0.1.0/LICENSE +98 -0
- marvisx_cli-0.1.0/MANIFEST.in +12 -0
- marvisx_cli-0.1.0/PKG-INFO +201 -0
- marvisx_cli-0.1.0/README.md +95 -0
- marvisx_cli-0.1.0/core/api/__init__.py +0 -0
- marvisx_cli-0.1.0/core/api/agents/__init__.py +0 -0
- marvisx_cli-0.1.0/core/api/agents/session_health.py +59 -0
- marvisx_cli-0.1.0/core/api/agents/session_manager.py +206 -0
- marvisx_cli-0.1.0/core/api/bin/marvisx-state-hook.py +182 -0
- marvisx_cli-0.1.0/core/api/config.py +533 -0
- marvisx_cli-0.1.0/core/api/db.py +1516 -0
- marvisx_cli-0.1.0/core/api/dependencies/__init__.py +0 -0
- marvisx_cli-0.1.0/core/api/dependencies/tenant.py +34 -0
- marvisx_cli-0.1.0/core/api/main.py +1641 -0
- marvisx_cli-0.1.0/core/api/mcp/__init__.py +8 -0
- marvisx_cli-0.1.0/core/api/mcp/_adapter.py +184 -0
- marvisx_cli-0.1.0/core/api/mcp/server.py +58 -0
- marvisx_cli-0.1.0/core/api/mcp/tools/__init__.py +59 -0
- marvisx_cli-0.1.0/core/api/mcp/tools/brain.py +599 -0
- marvisx_cli-0.1.0/core/api/mcp/tools/graph.py +380 -0
- marvisx_cli-0.1.0/core/api/mcp/tools/handoffs.py +112 -0
- marvisx_cli-0.1.0/core/api/mcp/tools/ingest.py +326 -0
- marvisx_cli-0.1.0/core/api/mcp/tools/learnings.py +144 -0
- marvisx_cli-0.1.0/core/api/mcp/tools/projects.py +99 -0
- marvisx_cli-0.1.0/core/api/mcp/tools/pull_requests.py +173 -0
- marvisx_cli-0.1.0/core/api/mcp/tools/safety.py +111 -0
- marvisx_cli-0.1.0/core/api/mcp/tools/search.py +79 -0
- marvisx_cli-0.1.0/core/api/mcp/tools/tasks.py +258 -0
- marvisx_cli-0.1.0/core/api/middleware/__init__.py +0 -0
- marvisx_cli-0.1.0/core/api/middleware/tool_call_audit.py +111 -0
- marvisx_cli-0.1.0/core/api/models/__init__.py +346 -0
- marvisx_cli-0.1.0/core/api/models/auth.py +48 -0
- marvisx_cli-0.1.0/core/api/models/brain.py +1006 -0
- marvisx_cli-0.1.0/core/api/models/common.py +76 -0
- marvisx_cli-0.1.0/core/api/models/costs.py +91 -0
- marvisx_cli-0.1.0/core/api/models/graph.py +66 -0
- marvisx_cli-0.1.0/core/api/models/graph_cosmo.py +125 -0
- marvisx_cli-0.1.0/core/api/models/graph_pr_impact.py +257 -0
- marvisx_cli-0.1.0/core/api/models/graph_ux.py +141 -0
- marvisx_cli-0.1.0/core/api/models/inbox.py +230 -0
- marvisx_cli-0.1.0/core/api/models/ingest_keys.py +108 -0
- marvisx_cli-0.1.0/core/api/models/kg.py +41 -0
- marvisx_cli-0.1.0/core/api/models/llm_config.py +56 -0
- marvisx_cli-0.1.0/core/api/models/monitoring.py +234 -0
- marvisx_cli-0.1.0/core/api/models/projects.py +161 -0
- marvisx_cli-0.1.0/core/api/models/search.py +42 -0
- marvisx_cli-0.1.0/core/api/models/sessions.py +322 -0
- marvisx_cli-0.1.0/core/api/models/tasks.py +184 -0
- marvisx_cli-0.1.0/core/api/models/teams.py +63 -0
- marvisx_cli-0.1.0/core/api/models/users.py +184 -0
- marvisx_cli-0.1.0/core/api/observability/__init__.py +0 -0
- marvisx_cli-0.1.0/core/api/observability/tracing.py +92 -0
- marvisx_cli-0.1.0/core/api/paths.py +26 -0
- marvisx_cli-0.1.0/core/api/rate_limit.py +24 -0
- marvisx_cli-0.1.0/core/api/rbac.py +112 -0
- marvisx_cli-0.1.0/core/api/routers/__init__.py +0 -0
- marvisx_cli-0.1.0/core/api/routers/_adapter.py +24 -0
- marvisx_cli-0.1.0/core/api/routers/admin_pr_impact.py +230 -0
- marvisx_cli-0.1.0/core/api/routers/admin_settings.py +147 -0
- marvisx_cli-0.1.0/core/api/routers/agent.py +1079 -0
- marvisx_cli-0.1.0/core/api/routers/agent_tokens.py +276 -0
- marvisx_cli-0.1.0/core/api/routers/app_settings.py +112 -0
- marvisx_cli-0.1.0/core/api/routers/audit.py +89 -0
- marvisx_cli-0.1.0/core/api/routers/auth.py +586 -0
- marvisx_cli-0.1.0/core/api/routers/bench.py +161 -0
- marvisx_cli-0.1.0/core/api/routers/brain.py +881 -0
- marvisx_cli-0.1.0/core/api/routers/brain_directions.py +527 -0
- marvisx_cli-0.1.0/core/api/routers/ci_checks.py +140 -0
- marvisx_cli-0.1.0/core/api/routers/comments.py +273 -0
- marvisx_cli-0.1.0/core/api/routers/costs.py +148 -0
- marvisx_cli-0.1.0/core/api/routers/docs_coverage.py +217 -0
- marvisx_cli-0.1.0/core/api/routers/docs_governance.py +63 -0
- marvisx_cli-0.1.0/core/api/routers/documents.py +318 -0
- marvisx_cli-0.1.0/core/api/routers/files.py +163 -0
- marvisx_cli-0.1.0/core/api/routers/finder.py +987 -0
- marvisx_cli-0.1.0/core/api/routers/graph.py +836 -0
- marvisx_cli-0.1.0/core/api/routers/handoffs.py +156 -0
- marvisx_cli-0.1.0/core/api/routers/inbox.py +496 -0
- marvisx_cli-0.1.0/core/api/routers/ingest_api_keys.py +205 -0
- marvisx_cli-0.1.0/core/api/routers/ingest_triage.py +1227 -0
- marvisx_cli-0.1.0/core/api/routers/judge.py +306 -0
- marvisx_cli-0.1.0/core/api/routers/kg.py +336 -0
- marvisx_cli-0.1.0/core/api/routers/learnings.py +253 -0
- marvisx_cli-0.1.0/core/api/routers/llm_config.py +130 -0
- marvisx_cli-0.1.0/core/api/routers/monitoring.py +347 -0
- marvisx_cli-0.1.0/core/api/routers/notifications.py +125 -0
- marvisx_cli-0.1.0/core/api/routers/pr_impact.py +315 -0
- marvisx_cli-0.1.0/core/api/routers/projects.py +1061 -0
- marvisx_cli-0.1.0/core/api/routers/pull_requests.py +312 -0
- marvisx_cli-0.1.0/core/api/routers/push.py +67 -0
- marvisx_cli-0.1.0/core/api/routers/raci.py +228 -0
- marvisx_cli-0.1.0/core/api/routers/search.py +125 -0
- marvisx_cli-0.1.0/core/api/routers/sessions.py +3100 -0
- marvisx_cli-0.1.0/core/api/routers/settings.py +90 -0
- marvisx_cli-0.1.0/core/api/routers/share_repo.py +68 -0
- marvisx_cli-0.1.0/core/api/routers/status_updates.py +96 -0
- marvisx_cli-0.1.0/core/api/routers/tags.py +45 -0
- marvisx_cli-0.1.0/core/api/routers/tasks.py +526 -0
- marvisx_cli-0.1.0/core/api/routers/teams.py +425 -0
- marvisx_cli-0.1.0/core/api/routers/terminal.py +105 -0
- marvisx_cli-0.1.0/core/api/routers/users.py +331 -0
- marvisx_cli-0.1.0/core/api/routers/webhooks.py +330 -0
- marvisx_cli-0.1.0/core/api/runtime_settings.py +84 -0
- marvisx_cli-0.1.0/core/api/security.py +652 -0
- marvisx_cli-0.1.0/core/api/services/__init__.py +0 -0
- marvisx_cli-0.1.0/core/api/services/audit.py +58 -0
- marvisx_cli-0.1.0/core/api/services/auto_approval.py +82 -0
- marvisx_cli-0.1.0/core/api/services/brain/__init__.py +52 -0
- marvisx_cli-0.1.0/core/api/services/brain/baseline.py +230 -0
- marvisx_cli-0.1.0/core/api/services/brain/capabilities.py +75 -0
- marvisx_cli-0.1.0/core/api/services/brain/cascade_rollup.py +388 -0
- marvisx_cli-0.1.0/core/api/services/brain/compound_bridge.py +215 -0
- marvisx_cli-0.1.0/core/api/services/brain/cycle.py +1242 -0
- marvisx_cli-0.1.0/core/api/services/brain/cycle_snapshot.py +371 -0
- marvisx_cli-0.1.0/core/api/services/brain/digest_collector.py +147 -0
- marvisx_cli-0.1.0/core/api/services/brain/direction.py +421 -0
- marvisx_cli-0.1.0/core/api/services/brain/drift.py +356 -0
- marvisx_cli-0.1.0/core/api/services/brain/drift_router.py +409 -0
- marvisx_cli-0.1.0/core/api/services/brain/edge_metrics.py +79 -0
- marvisx_cli-0.1.0/core/api/services/brain/events_reader.py +222 -0
- marvisx_cli-0.1.0/core/api/services/brain/findings.py +1379 -0
- marvisx_cli-0.1.0/core/api/services/brain/findings_reader.py +1006 -0
- marvisx_cli-0.1.0/core/api/services/brain/jobs.py +733 -0
- marvisx_cli-0.1.0/core/api/services/brain/journal.py +206 -0
- marvisx_cli-0.1.0/core/api/services/brain/knowledge_forms.py +92 -0
- marvisx_cli-0.1.0/core/api/services/brain/llm/__init__.py +37 -0
- marvisx_cli-0.1.0/core/api/services/brain/llm/_runner.py +62 -0
- marvisx_cli-0.1.0/core/api/services/brain/llm/base.py +70 -0
- marvisx_cli-0.1.0/core/api/services/brain/llm/cache.py +99 -0
- marvisx_cli-0.1.0/core/api/services/brain/llm/constants.py +46 -0
- marvisx_cli-0.1.0/core/api/services/brain/llm/direction_alignment.py +289 -0
- marvisx_cli-0.1.0/core/api/services/brain/llm/factory.py +132 -0
- marvisx_cli-0.1.0/core/api/services/brain/llm/finding_reasoning.py +98 -0
- marvisx_cli-0.1.0/core/api/services/brain/llm/finding_summary.py +92 -0
- marvisx_cli-0.1.0/core/api/services/brain/llm/grounding.py +46 -0
- marvisx_cli-0.1.0/core/api/services/brain/llm/journal_polish.py +96 -0
- marvisx_cli-0.1.0/core/api/services/brain/llm/local_gateway.py +426 -0
- marvisx_cli-0.1.0/core/api/services/brain/llm/parsers.py +71 -0
- marvisx_cli-0.1.0/core/api/services/brain/llm/router_glue.py +422 -0
- marvisx_cli-0.1.0/core/api/services/brain/memory_ops.py +1677 -0
- marvisx_cli-0.1.0/core/api/services/brain/models.py +140 -0
- marvisx_cli-0.1.0/core/api/services/brain/owner_hint.py +211 -0
- marvisx_cli-0.1.0/core/api/services/brain/recap.py +307 -0
- marvisx_cli-0.1.0/core/api/services/brain/rules/__init__.py +65 -0
- marvisx_cli-0.1.0/core/api/services/brain/rules/_signals.py +205 -0
- marvisx_cli-0.1.0/core/api/services/brain/rules/dr1_activity_without_status.py +108 -0
- marvisx_cli-0.1.0/core/api/services/brain/rules/dr2_decision_without_adr.py +110 -0
- marvisx_cli-0.1.0/core/api/services/brain/rules/dr3_stale_open_loop.py +127 -0
- marvisx_cli-0.1.0/core/api/services/brain/rules/dr4_docs_governance_drift.py +79 -0
- marvisx_cli-0.1.0/core/api/services/brain/rules/dr5_playbook_changed.py +99 -0
- marvisx_cli-0.1.0/core/api/services/brain/rules/dr6_external_update_unpropagated.py +100 -0
- marvisx_cli-0.1.0/core/api/services/brain/rules/dr7_claimed_decision_gap.py +123 -0
- marvisx_cli-0.1.0/core/api/services/brain/rules/dr8_direction_misalignment.py +230 -0
- marvisx_cli-0.1.0/core/api/services/brain/runs_reader.py +485 -0
- marvisx_cli-0.1.0/core/api/services/brain/scope.py +79 -0
- marvisx_cli-0.1.0/core/api/services/brain/sources/__init__.py +46 -0
- marvisx_cli-0.1.0/core/api/services/brain/sources/base.py +86 -0
- marvisx_cli-0.1.0/core/api/services/brain/sources/git_kg.py +393 -0
- marvisx_cli-0.1.0/core/api/services/brain/sources/handoffs.py +157 -0
- marvisx_cli-0.1.0/core/api/services/brain/sources/ingestor.py +130 -0
- marvisx_cli-0.1.0/core/api/services/brain/sources/learnings.py +121 -0
- marvisx_cli-0.1.0/core/api/services/brain/sources/pir_tasks.py +245 -0
- marvisx_cli-0.1.0/core/api/services/brain/watermarks.py +147 -0
- marvisx_cli-0.1.0/core/api/services/brain/ws_emitter.py +170 -0
- marvisx_cli-0.1.0/core/api/services/cc_tasks_reader.py +76 -0
- marvisx_cli-0.1.0/core/api/services/ci_service.py +263 -0
- marvisx_cli-0.1.0/core/api/services/claude_metrics.py +796 -0
- marvisx_cli-0.1.0/core/api/services/codex_metrics.py +364 -0
- marvisx_cli-0.1.0/core/api/services/conversation_reader.py +102 -0
- marvisx_cli-0.1.0/core/api/services/cost_service.py +243 -0
- marvisx_cli-0.1.0/core/api/services/crypto.py +147 -0
- marvisx_cli-0.1.0/core/api/services/docs_governance/__init__.py +1 -0
- marvisx_cli-0.1.0/core/api/services/docs_governance/confidence.py +230 -0
- marvisx_cli-0.1.0/core/api/services/docs_governance/config.py +87 -0
- marvisx_cli-0.1.0/core/api/services/docs_governance/enrichment.py +65 -0
- marvisx_cli-0.1.0/core/api/services/docs_governance/frontmatter_validator.py +83 -0
- marvisx_cli-0.1.0/core/api/services/docs_governance/hard_gates.py +221 -0
- marvisx_cli-0.1.0/core/api/services/docs_governance/triage_orchestrator.py +98 -0
- marvisx_cli-0.1.0/core/api/services/embedding_internal.py +395 -0
- marvisx_cli-0.1.0/core/api/services/embedding_service.py +832 -0
- marvisx_cli-0.1.0/core/api/services/event_dispatcher.py +167 -0
- marvisx_cli-0.1.0/core/api/services/events.py +70 -0
- marvisx_cli-0.1.0/core/api/services/git_ops.py +621 -0
- marvisx_cli-0.1.0/core/api/services/graph_cosmo_service.py +440 -0
- marvisx_cli-0.1.0/core/api/services/graph_ranker.py +306 -0
- marvisx_cli-0.1.0/core/api/services/graph_service.py +1589 -0
- marvisx_cli-0.1.0/core/api/services/inbox.py +800 -0
- marvisx_cli-0.1.0/core/api/services/inbox_digest.py +221 -0
- marvisx_cli-0.1.0/core/api/services/inbox_digest_deep_research.py +80 -0
- marvisx_cli-0.1.0/core/api/services/inbox_digest_jobs.py +595 -0
- marvisx_cli-0.1.0/core/api/services/inbox_gmail_sync.py +167 -0
- marvisx_cli-0.1.0/core/api/services/inbox_llm_classifier.py +906 -0
- marvisx_cli-0.1.0/core/api/services/inbox_source_identity.py +116 -0
- marvisx_cli-0.1.0/core/api/services/inbox_sources.py +456 -0
- marvisx_cli-0.1.0/core/api/services/inbox_taxonomy.py +195 -0
- marvisx_cli-0.1.0/core/api/services/inbox_tldr.py +1079 -0
- marvisx_cli-0.1.0/core/api/services/inbox_triage.py +899 -0
- marvisx_cli-0.1.0/core/api/services/ingest/__init__.py +13 -0
- marvisx_cli-0.1.0/core/api/services/ingest/api_key_auth.py +136 -0
- marvisx_cli-0.1.0/core/api/services/ingest/auto_approve.py +120 -0
- marvisx_cli-0.1.0/core/api/services/ingest/classifier.py +138 -0
- marvisx_cli-0.1.0/core/api/services/ingest/confidence.py +173 -0
- marvisx_cli-0.1.0/core/api/services/ingest/dispatch.py +88 -0
- marvisx_cli-0.1.0/core/api/services/ingest/embedding_router.py +272 -0
- marvisx_cli-0.1.0/core/api/services/ingest/events.py +33 -0
- marvisx_cli-0.1.0/core/api/services/ingest/ignore_patterns.py +79 -0
- marvisx_cli-0.1.0/core/api/services/ingest/image_probe.py +218 -0
- marvisx_cli-0.1.0/core/api/services/ingest/ingress.py +263 -0
- marvisx_cli-0.1.0/core/api/services/ingest/insert_saga.py +793 -0
- marvisx_cli-0.1.0/core/api/services/ingest/llm/__init__.py +13 -0
- marvisx_cli-0.1.0/core/api/services/ingest/llm/anthropic_haiku.py +23 -0
- marvisx_cli-0.1.0/core/api/services/ingest/llm/base.py +59 -0
- marvisx_cli-0.1.0/core/api/services/ingest/llm/byok_provider.py +130 -0
- marvisx_cli-0.1.0/core/api/services/ingest/llm/classification_context.py +301 -0
- marvisx_cli-0.1.0/core/api/services/ingest/llm/config_store.py +246 -0
- marvisx_cli-0.1.0/core/api/services/ingest/llm/factory.py +24 -0
- marvisx_cli-0.1.0/core/api/services/ingest/llm/kg_enricher.py +306 -0
- marvisx_cli-0.1.0/core/api/services/ingest/llm/local_gateway.py +821 -0
- marvisx_cli-0.1.0/core/api/services/ingest/llm/local_vllm.py +23 -0
- marvisx_cli-0.1.0/core/api/services/ingest/llm/openai_nano.py +349 -0
- marvisx_cli-0.1.0/core/api/services/ingest/lock_advisory.py +57 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parser_router.py +1756 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/__init__.py +1 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/docling_parser.py +142 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/docparse_gateway.py +178 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/docx_parser.py +127 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/folder_unpacker.py +85 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/gateway_aux.py +147 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/image_parser.py +251 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/internal_markdown.py +89 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/ocr_gateway.py +117 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/ocr_pdf_parser.py +112 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/pdf_types.py +13 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/transcript_parser.py +445 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/vision_gateway.py +186 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/xlsx_parser.py +91 -0
- marvisx_cli-0.1.0/core/api/services/ingest/parsers/zip_unpacker.py +126 -0
- marvisx_cli-0.1.0/core/api/services/ingest/preflight.py +393 -0
- marvisx_cli-0.1.0/core/api/services/ingest/retry_voyage.py +88 -0
- marvisx_cli-0.1.0/core/api/services/ingest/routing_policy.py +307 -0
- marvisx_cli-0.1.0/core/api/services/ingest/serializers/__init__.py +1 -0
- marvisx_cli-0.1.0/core/api/services/ingest/serializers/xlsx_to_markdown.py +80 -0
- marvisx_cli-0.1.0/core/api/services/ingest/skip_log.py +74 -0
- marvisx_cli-0.1.0/core/api/services/ingest/watcher.py +637 -0
- marvisx_cli-0.1.0/core/api/services/kg/__init__.py +0 -0
- marvisx_cli-0.1.0/core/api/services/kg/audit.py +49 -0
- marvisx_cli-0.1.0/core/api/services/kg/hybrid_search.py +691 -0
- marvisx_cli-0.1.0/core/api/services/kg/lens.py +339 -0
- marvisx_cli-0.1.0/core/api/services/kg/pr_impact.py +770 -0
- marvisx_cli-0.1.0/core/api/services/kg/queries.py +152 -0
- marvisx_cli-0.1.0/core/api/services/kg/ranking.py +89 -0
- marvisx_cli-0.1.0/core/api/services/kg/rrf.py +143 -0
- marvisx_cli-0.1.0/core/api/services/kg_watcher_control.py +161 -0
- marvisx_cli-0.1.0/core/api/services/local_llm/__init__.py +19 -0
- marvisx_cli-0.1.0/core/api/services/local_llm/async_client.py +385 -0
- marvisx_cli-0.1.0/core/api/services/local_llm/client.py +173 -0
- marvisx_cli-0.1.0/core/api/services/local_llm/url_validator.py +44 -0
- marvisx_cli-0.1.0/core/api/services/metrics_collector.py +646 -0
- marvisx_cli-0.1.0/core/api/services/metrics_providers.py +65 -0
- marvisx_cli-0.1.0/core/api/services/model_registry.py +266 -0
- marvisx_cli-0.1.0/core/api/services/model_router.py +137 -0
- marvisx_cli-0.1.0/core/api/services/n8n_client.py +77 -0
- marvisx_cli-0.1.0/core/api/services/newsletter_llm_gateway.py +66 -0
- marvisx_cli-0.1.0/core/api/services/notification_service.py +134 -0
- marvisx_cli-0.1.0/core/api/services/openai_responses.py +55 -0
- marvisx_cli-0.1.0/core/api/services/opencode_metrics.py +375 -0
- marvisx_cli-0.1.0/core/api/services/opencode_sessions.py +173 -0
- marvisx_cli-0.1.0/core/api/services/pii_redactor.py +138 -0
- marvisx_cli-0.1.0/core/api/services/pr_impact_pipeline/__init__.py +21 -0
- marvisx_cli-0.1.0/core/api/services/pr_impact_pipeline/differ.py +421 -0
- marvisx_cli-0.1.0/core/api/services/pr_impact_pipeline/dispatcher.py +415 -0
- marvisx_cli-0.1.0/core/api/services/pr_impact_pipeline/gc.py +93 -0
- marvisx_cli-0.1.0/core/api/services/pr_impact_pipeline/languages.py +192 -0
- marvisx_cli-0.1.0/core/api/services/pr_impact_pipeline/parser.py +178 -0
- marvisx_cli-0.1.0/core/api/services/pr_impact_pipeline/writer.py +394 -0
- marvisx_cli-0.1.0/core/api/services/pr_service.py +1393 -0
- marvisx_cli-0.1.0/core/api/services/project_paths.py +70 -0
- marvisx_cli-0.1.0/core/api/services/project_status_updates.py +265 -0
- marvisx_cli-0.1.0/core/api/services/providers.py +276 -0
- marvisx_cli-0.1.0/core/api/services/push_service.py +170 -0
- marvisx_cli-0.1.0/core/api/services/reminder_service.py +89 -0
- marvisx_cli-0.1.0/core/api/services/runas.py +41 -0
- marvisx_cli-0.1.0/core/api/services/salience_service.py +69 -0
- marvisx_cli-0.1.0/core/api/services/security_collector.py +281 -0
- marvisx_cli-0.1.0/core/api/services/session_catalog.py +385 -0
- marvisx_cli-0.1.0/core/api/services/session_metrics_service.py +301 -0
- marvisx_cli-0.1.0/core/api/services/session_ops.py +272 -0
- marvisx_cli-0.1.0/core/api/services/session_state.py +173 -0
- marvisx_cli-0.1.0/core/api/services/share_links.py +222 -0
- marvisx_cli-0.1.0/core/api/services/task_transitions.py +146 -0
- marvisx_cli-0.1.0/core/api/services/terminal_metrics.py +462 -0
- marvisx_cli-0.1.0/core/api/services/terminal_metrics_dump.py +203 -0
- marvisx_cli-0.1.0/core/api/services/tmux.py +1205 -0
- marvisx_cli-0.1.0/core/api/services/webhook_service.py +422 -0
- marvisx_cli-0.1.0/core/api/services/workspace_sync.py +164 -0
- marvisx_cli-0.1.0/core/api/templates/__init__.py +1 -0
- marvisx_cli-0.1.0/core/api/templates/markdown_share.py +164 -0
- marvisx_cli-0.1.0/core/api/terminal.py +1031 -0
- marvisx_cli-0.1.0/core/api/tests/__init__.py +0 -0
- marvisx_cli-0.1.0/core/api/tests/test_agent_facing_auth_dependencies.py +132 -0
- marvisx_cli-0.1.0/core/api/tests/test_audit_permissions.py +133 -0
- marvisx_cli-0.1.0/core/api/tests/test_backfill_session_conversations.py +90 -0
- marvisx_cli-0.1.0/core/api/tests/test_backfill_working_seconds_msg.py +129 -0
- marvisx_cli-0.1.0/core/api/tests/test_claude_metrics.py +326 -0
- marvisx_cli-0.1.0/core/api/tests/test_codex_metrics.py +189 -0
- marvisx_cli-0.1.0/core/api/tests/test_finder_paths.py +74 -0
- marvisx_cli-0.1.0/core/api/tests/test_git_ops_merge.py +155 -0
- marvisx_cli-0.1.0/core/api/tests/test_learnings_check_search.py +81 -0
- marvisx_cli-0.1.0/core/api/tests/test_metrics_providers.py +133 -0
- marvisx_cli-0.1.0/core/api/tests/test_migration_087.py +164 -0
- marvisx_cli-0.1.0/core/api/tests/test_migration_088.py +94 -0
- marvisx_cli-0.1.0/core/api/tests/test_migration_089.py +116 -0
- marvisx_cli-0.1.0/core/api/tests/test_openai_responses.py +24 -0
- marvisx_cli-0.1.0/core/api/tests/test_opencode_metrics.py +740 -0
- marvisx_cli-0.1.0/core/api/tests/test_opencode_sessions.py +321 -0
- marvisx_cli-0.1.0/core/api/tests/test_pr_workflow_e2e.py +457 -0
- marvisx_cli-0.1.0/core/api/tests/test_projects_handoffs.py +31 -0
- marvisx_cli-0.1.0/core/api/tests/test_providers.py +138 -0
- marvisx_cli-0.1.0/core/api/tests/test_safety_bridge.py +347 -0
- marvisx_cli-0.1.0/core/api/tests/test_session_catalog.py +142 -0
- marvisx_cli-0.1.0/core/api/tests/test_session_conversations.py +512 -0
- marvisx_cli-0.1.0/core/api/tests/test_session_metrics_service.py +270 -0
- marvisx_cli-0.1.0/core/api/tests/test_session_resume_paths.py +548 -0
- marvisx_cli-0.1.0/core/api/tests/test_session_theme_mode_migration.py +56 -0
- marvisx_cli-0.1.0/core/api/tests/test_sessions_rbac.py +131 -0
- marvisx_cli-0.1.0/core/api/tests/test_share_edit.py +398 -0
- marvisx_cli-0.1.0/core/api/tests/test_share_repo.py +200 -0
- marvisx_cli-0.1.0/core/api/tests/test_terminal_session_manager.py +98 -0
- marvisx_cli-0.1.0/core/api/tests/test_terminal_upload.py +34 -0
- marvisx_cli-0.1.0/core/api/tests/test_tmux.py +272 -0
- marvisx_cli-0.1.0/core/api/tests/test_workspace_sync.py +186 -0
- marvisx_cli-0.1.0/core/api/tests/test_ws_ticket_in_memory.py +73 -0
- marvisx_cli-0.1.0/core/api/use_cases/__init__.py +11 -0
- marvisx_cli-0.1.0/core/api/use_cases/_context.py +89 -0
- marvisx_cli-0.1.0/core/api/use_cases/_errors.py +62 -0
- marvisx_cli-0.1.0/core/api/use_cases/_roles.py +16 -0
- marvisx_cli-0.1.0/core/api/use_cases/audit.py +171 -0
- marvisx_cli-0.1.0/core/api/use_cases/brain.py +1232 -0
- marvisx_cli-0.1.0/core/api/use_cases/costs.py +249 -0
- marvisx_cli-0.1.0/core/api/use_cases/graph.py +1153 -0
- marvisx_cli-0.1.0/core/api/use_cases/handoffs.py +506 -0
- marvisx_cli-0.1.0/core/api/use_cases/ingest_triage.py +1229 -0
- marvisx_cli-0.1.0/core/api/use_cases/learnings.py +538 -0
- marvisx_cli-0.1.0/core/api/use_cases/projects.py +705 -0
- marvisx_cli-0.1.0/core/api/use_cases/pull_requests.py +415 -0
- marvisx_cli-0.1.0/core/api/use_cases/search.py +926 -0
- marvisx_cli-0.1.0/core/api/use_cases/tasks.py +1495 -0
- marvisx_cli-0.1.0/core/api/visibility.py +141 -0
- marvisx_cli-0.1.0/core/cli/README.md +126 -0
- marvisx_cli-0.1.0/core/cli/__init__.py +5 -0
- marvisx_cli-0.1.0/core/cli/_index_source.py +632 -0
- marvisx_cli-0.1.0/core/cli/_runtime_ctx.py +160 -0
- marvisx_cli-0.1.0/core/cli/_transmute.py +241 -0
- marvisx_cli-0.1.0/core/cli/marvis_doctor.py +704 -0
- marvisx_cli-0.1.0/core/cli/marvis_feedback.py +396 -0
- marvisx_cli-0.1.0/core/cli/marvis_governance.py +315 -0
- marvisx_cli-0.1.0/core/cli/marvis_hooks.py +515 -0
- marvisx_cli-0.1.0/core/cli/marvis_init.py +757 -0
- marvisx_cli-0.1.0/core/cli/marvis_mcp.py +401 -0
- marvisx_cli-0.1.0/core/cli/marvis_runtime.py +855 -0
- marvisx_cli-0.1.0/core/cli/marvis_telemetry.py +228 -0
- marvisx_cli-0.1.0/core/scripts/_drift_check.py +716 -0
- marvisx_cli-0.1.0/core/scripts/_frontmatter.py +66 -0
- marvisx_cli-0.1.0/core/scripts/_graph_writer.py +189 -0
- marvisx_cli-0.1.0/core/scripts/ast_parser.py +1553 -0
- marvisx_cli-0.1.0/core/scripts/install_hooks/__init__.py +1 -0
- marvisx_cli-0.1.0/core/scripts/install_hooks/_config.sh +109 -0
- marvisx_cli-0.1.0/core/scripts/install_hooks/block-dangerous-bash.sh +23 -0
- marvisx_cli-0.1.0/core/scripts/install_hooks/block-db-direct-write.sh +23 -0
- marvisx_cli-0.1.0/core/scripts/install_hooks/block-push-no-task.sh +23 -0
- marvisx_cli-0.1.0/core/scripts/install_hooks/block-staging-to-prod.sh +23 -0
- marvisx_cli-0.1.0/core/scripts/install_hooks/block-subtree-push.sh +23 -0
- marvisx_cli-0.1.0/core/scripts/install_hooks/config.json +53 -0
- marvisx_cli-0.1.0/core/scripts/install_hooks/enforce-no-merge-main.sh +23 -0
- marvisx_cli-0.1.0/core/scripts/install_hooks/enforce-worktree.sh +23 -0
- marvisx_cli-0.1.0/core/scripts/install_hooks/quality-gate.sh +170 -0
- marvisx_cli-0.1.0/core/scripts/install_hooks/safety_bridge.py +968 -0
- marvisx_cli-0.1.0/core/scripts/install_hooks/secret-scan.sh +23 -0
- marvisx_cli-0.1.0/core/scripts/migrate_spike_node_ids.py +122 -0
- marvisx_cli-0.1.0/core/scripts/populate_artifacts.py +2198 -0
- marvisx_cli-0.1.0/core/scripts/populate_cross_project.py +2457 -0
- marvisx_cli-0.1.0/core/scripts/populate_inbox_nodes.py +357 -0
- marvisx_cli-0.1.0/core/scripts/populate_pr_impact.py +267 -0
- marvisx_cli-0.1.0/core/scripts/populate_project_nodes.py +603 -0
- marvisx_cli-0.1.0/core/scripts/populate_touch_counter.py +337 -0
- marvisx_cli-0.1.0/core/scripts/reparse_failed.py +57 -0
- marvisx_cli-0.1.0/core/scripts/safety_bridge.py +968 -0
- marvisx_cli-0.1.0/core/telemetry/__init__.py +9 -0
- marvisx_cli-0.1.0/core/telemetry/client.py +405 -0
- marvisx_cli-0.1.0/core/telemetry/schema.py +122 -0
- marvisx_cli-0.1.0/core/wizard/__init__.py +65 -0
- marvisx_cli-0.1.0/core/wizard/byok_vault.py +147 -0
- marvisx_cli-0.1.0/core/wizard/defaults.py +58 -0
- marvisx_cli-0.1.0/core/wizard/state.py +117 -0
- marvisx_cli-0.1.0/core/wizard/steps.py +70 -0
- marvisx_cli-0.1.0/core/wizard/validation.py +136 -0
- marvisx_cli-0.1.0/marvisx_cli.egg-info/PKG-INFO +201 -0
- marvisx_cli-0.1.0/marvisx_cli.egg-info/SOURCES.txt +592 -0
- marvisx_cli-0.1.0/marvisx_cli.egg-info/dependency_links.txt +1 -0
- marvisx_cli-0.1.0/marvisx_cli.egg-info/entry_points.txt +3 -0
- marvisx_cli-0.1.0/marvisx_cli.egg-info/requires.txt +47 -0
- marvisx_cli-0.1.0/marvisx_cli.egg-info/top_level.txt +3 -0
- marvisx_cli-0.1.0/migrations/001_initial.sql +33 -0
- marvisx_cli-0.1.0/migrations/002_tasks.sql +30 -0
- marvisx_cli-0.1.0/migrations/003_session_management.sql +7 -0
- marvisx_cli-0.1.0/migrations/004_projects_comments.sql +65 -0
- marvisx_cli-0.1.0/migrations/005_session_intelligence.sql +15 -0
- marvisx_cli-0.1.0/migrations/006_settings.sql +12 -0
- marvisx_cli-0.1.0/migrations/007_task_scoring.sql +12 -0
- marvisx_cli-0.1.0/migrations/008_cost_tracking.sql +31 -0
- marvisx_cli-0.1.0/migrations/009_session_card_metrics.sql +3 -0
- marvisx_cli-0.1.0/migrations/010_monitoring.sql +55 -0
- marvisx_cli-0.1.0/migrations/012_agent_api.sql +21 -0
- marvisx_cli-0.1.0/migrations/013_session_complete.sql +8 -0
- marvisx_cli-0.1.0/migrations/015_pull_requests.sql +43 -0
- marvisx_cli-0.1.0/migrations/015_pull_requests_down.sql +5 -0
- marvisx_cli-0.1.0/migrations/016_users_raci.sql +116 -0
- marvisx_cli-0.1.0/migrations/017_task_cost_entries.sql +87 -0
- marvisx_cli-0.1.0/migrations/018_agents.sql +73 -0
- marvisx_cli-0.1.0/migrations/018_agents_down.sql +13 -0
- marvisx_cli-0.1.0/migrations/019_review_feedback.sql +18 -0
- marvisx_cli-0.1.0/migrations/020_pr_commit_sha.sql +4 -0
- marvisx_cli-0.1.0/migrations/021_webhook_events.sql +18 -0
- marvisx_cli-0.1.0/migrations/022_devx_agent_managed.sql +11 -0
- marvisx_cli-0.1.0/migrations/022_devx_agent_managed_down.sql +6 -0
- marvisx_cli-0.1.0/migrations/023_devx_p1_gate.sql +7 -0
- marvisx_cli-0.1.0/migrations/023_devx_p1_gate_down.sql +3 -0
- marvisx_cli-0.1.0/migrations/024_chat_messages.sql +16 -0
- marvisx_cli-0.1.0/migrations/024_pr_conversation_id.sql +8 -0
- marvisx_cli-0.1.0/migrations/024_task_indexes.sql +21 -0
- marvisx_cli-0.1.0/migrations/024_task_indexes_down.sql +7 -0
- marvisx_cli-0.1.0/migrations/025_audit_log.sql +17 -0
- marvisx_cli-0.1.0/migrations/026_agent_tokens.sql +20 -0
- marvisx_cli-0.1.0/migrations/027_teams_auth_phase_b.sql +35 -0
- marvisx_cli-0.1.0/migrations/028_learnings.sql +23 -0
- marvisx_cli-0.1.0/migrations/029_team_roles.sql +14 -0
- marvisx_cli-0.1.0/migrations/030_finder_pins.sql +10 -0
- marvisx_cli-0.1.0/migrations/031_pr_deploy_status.sql +9 -0
- marvisx_cli-0.1.0/migrations/032_task_reminders.sql +7 -0
- marvisx_cli-0.1.0/migrations/033_events_retry_count.sql +6 -0
- marvisx_cli-0.1.0/migrations/033_session_owner.sql +9 -0
- marvisx_cli-0.1.0/migrations/034_notifications.sql +38 -0
- marvisx_cli-0.1.0/migrations/035_shared_links.sql +15 -0
- marvisx_cli-0.1.0/migrations/036_session_index_upgrade.sql +29 -0
- marvisx_cli-0.1.0/migrations/037_pr_approval.sql +15 -0
- marvisx_cli-0.1.0/migrations/038_pr_submitted_by.sql +6 -0
- marvisx_cli-0.1.0/migrations/039_push_subscriptions.sql +17 -0
- marvisx_cli-0.1.0/migrations/040_semantic_search.sql +16 -0
- marvisx_cli-0.1.0/migrations/041_workspaces.sql +63 -0
- marvisx_cli-0.1.0/migrations/042_oidc_providers.sql +24 -0
- marvisx_cli-0.1.0/migrations/043_ci_checks.sql +31 -0
- marvisx_cli-0.1.0/migrations/044_agent_metrics.sql +30 -0
- marvisx_cli-0.1.0/migrations/045_documents_doc_type.sql +5 -0
- marvisx_cli-0.1.0/migrations/046_salience.sql +13 -0
- marvisx_cli-0.1.0/migrations/047_seed_missing_agents.sql +6 -0
- marvisx_cli-0.1.0/migrations/048_fix_agent_paths_roles.sql +5 -0
- marvisx_cli-0.1.0/migrations/049_agent_role_and_learnings_schema.sql +3 -0
- marvisx_cli-0.1.0/migrations/050_session_provider.sql +2 -0
- marvisx_cli-0.1.0/migrations/051_session_launch_profile.sql +4 -0
- marvisx_cli-0.1.0/migrations/052_session_theme_mode.sql +2 -0
- marvisx_cli-0.1.0/migrations/052_task_kind.sql +4 -0
- marvisx_cli-0.1.0/migrations/053_inbox_items.sql +31 -0
- marvisx_cli-0.1.0/migrations/054_inbox_triage_contract.sql +30 -0
- marvisx_cli-0.1.0/migrations/055_inbox_topic_treatment.sql +12 -0
- marvisx_cli-0.1.0/migrations/056_inbox_treatment_read_save.sql +57 -0
- marvisx_cli-0.1.0/migrations/057_session_theme_mode_backfill.sql +4 -0
- marvisx_cli-0.1.0/migrations/058_inbox_item_status_lifecycle.sql +13 -0
- marvisx_cli-0.1.0/migrations/059_inbox_tldr_and_source_scores.sql +18 -0
- marvisx_cli-0.1.0/migrations/060_newsletter.sql +16 -0
- marvisx_cli-0.1.0/migrations/061_inbox_redesign.sql +69 -0
- marvisx_cli-0.1.0/migrations/062_fix_inbox_sources_backfill.sql +37 -0
- marvisx_cli-0.1.0/migrations/063_task_completion_mode.sql +23 -0
- marvisx_cli-0.1.0/migrations/064_judge_mode_setting.sql +4 -0
- marvisx_cli-0.1.0/migrations/065_knowledge_graph_spike.sql +40 -0
- marvisx_cli-0.1.0/migrations/066_digest_ranking_inputs.sql +10 -0
- marvisx_cli-0.1.0/migrations/066_kg_artifact_nodes.sql +129 -0
- marvisx_cli-0.1.0/migrations/067_inbox_digest_selections.sql +28 -0
- marvisx_cli-0.1.0/migrations/067_kg_temporal.sql +53 -0
- marvisx_cli-0.1.0/migrations/068_inbox_digest_app_settings.sql +9 -0
- marvisx_cli-0.1.0/migrations/068_kg_touch_counter.sql +52 -0
- marvisx_cli-0.1.0/migrations/069_kg_doc_types.sql +117 -0
- marvisx_cli-0.1.0/migrations/070_digest_ranking_inputs_recovery.sql +3 -0
- marvisx_cli-0.1.0/migrations/071_inbox_digest_selections_recovery.sql +3 -0
- marvisx_cli-0.1.0/migrations/072_inbox_digest_app_settings_recovery.sql +3 -0
- marvisx_cli-0.1.0/migrations/073_kg_cross_project.sql +216 -0
- marvisx_cli-0.1.0/migrations/073_kg_cross_project_down.sql +77 -0
- marvisx_cli-0.1.0/migrations/074_kg_infra_types.sql +208 -0
- marvisx_cli-0.1.0/migrations/074_kg_infra_types_down.sql +80 -0
- marvisx_cli-0.1.0/migrations/075_kg_file_state_recovery.sql +35 -0
- marvisx_cli-0.1.0/migrations/075_kg_file_state_recovery_down.sql +5 -0
- marvisx_cli-0.1.0/migrations/076_kg_watcher_state.sql +33 -0
- marvisx_cli-0.1.0/migrations/076_kg_watcher_state_down.sql +3 -0
- marvisx_cli-0.1.0/migrations/077_kg_doc_types_extend.sql +226 -0
- marvisx_cli-0.1.0/migrations/077_kg_doc_types_extend_down.sql +80 -0
- marvisx_cli-0.1.0/migrations/078_kg_fts5.sql +102 -0
- marvisx_cli-0.1.0/migrations/078_kg_fts5_down.sql +14 -0
- marvisx_cli-0.1.0/migrations/079_kg_missing_indexes.sql +31 -0
- marvisx_cli-0.1.0/migrations/079_kg_missing_indexes_down.sql +10 -0
- marvisx_cli-0.1.0/migrations/080_kg_fts5_extended.sql +232 -0
- marvisx_cli-0.1.0/migrations/080_kg_fts5_extended_down.sql +25 -0
- marvisx_cli-0.1.0/migrations/081_kg_lens_indexes.sql +9 -0
- marvisx_cli-0.1.0/migrations/081_kg_lens_indexes_down.sql +3 -0
- marvisx_cli-0.1.0/migrations/082_kg_pins.sql +26 -0
- marvisx_cli-0.1.0/migrations/082_kg_pins_down.sql +14 -0
- marvisx_cli-0.1.0/migrations/083_kg_graph_nodes_degree.sql +20 -0
- marvisx_cli-0.1.0/migrations/083_kg_graph_nodes_degree_down.sql +15 -0
- marvisx_cli-0.1.0/migrations/084_drop_legacy_scheduler_tables.sql +58 -0
- marvisx_cli-0.1.0/migrations/084_drop_legacy_scheduler_tables_down.sql +112 -0
- marvisx_cli-0.1.0/migrations/085_kg_edge_resolves_to.sql +142 -0
- marvisx_cli-0.1.0/migrations/085_kg_edge_resolves_to_down.sql +66 -0
- marvisx_cli-0.1.0/migrations/086_project_status_updates_feed.sql +20 -0
- marvisx_cli-0.1.0/migrations/086_project_status_updates_feed_down.sql +36 -0
- marvisx_cli-0.1.0/migrations/087_session_metrics_dual.sql +50 -0
- marvisx_cli-0.1.0/migrations/087_session_metrics_dual_down.sql +21 -0
- marvisx_cli-0.1.0/migrations/088_rename_context_pct_legacy.sql +23 -0
- marvisx_cli-0.1.0/migrations/088_rename_context_pct_legacy_down.sql +8 -0
- marvisx_cli-0.1.0/migrations/089_session_metrics_equivalent_cost.sql +26 -0
- marvisx_cli-0.1.0/migrations/089_session_metrics_equivalent_cost_down.sql +11 -0
- marvisx_cli-0.1.0/migrations/090_kg_inbox_node_type.sql +26 -0
- marvisx_cli-0.1.0/migrations/090_kg_inbox_node_type_down.sql +20 -0
- marvisx_cli-0.1.0/migrations/091_kg_inbox_node_type_check.sql +265 -0
- marvisx_cli-0.1.0/migrations/091_kg_inbox_node_type_check_down.sql +129 -0
- marvisx_cli-0.1.0/migrations/092_sessions_activity_state_ts.sql +29 -0
- marvisx_cli-0.1.0/migrations/092_sessions_activity_state_ts_down.sql +14 -0
- marvisx_cli-0.1.0/migrations/093_sessions_activity_state_column.sql +29 -0
- marvisx_cli-0.1.0/migrations/093_sessions_activity_state_column_down.sql +10 -0
- marvisx_cli-0.1.0/migrations/094_ingest_pending.sql +55 -0
- marvisx_cli-0.1.0/migrations/094_ingest_pending_down.sql +15 -0
- marvisx_cli-0.1.0/migrations/095_kg_intent_first.sql +77 -0
- marvisx_cli-0.1.0/migrations/095_kg_intent_first_down.sql +25 -0
- marvisx_cli-0.1.0/migrations/096_kg_xlsx_artifact_prefix.sql +17 -0
- marvisx_cli-0.1.0/migrations/096_kg_xlsx_artifact_prefix_down.sql +11 -0
- marvisx_cli-0.1.0/migrations/097_ingest_change_history.sql +37 -0
- marvisx_cli-0.1.0/migrations/097_ingest_change_history_down.sql +13 -0
- marvisx_cli-0.1.0/migrations/098_kg_node_type_business.sql +254 -0
- marvisx_cli-0.1.0/migrations/098_kg_node_type_business_down.sql +195 -0
- marvisx_cli-0.1.0/migrations/099_kg_edges_restore_weight.sql +58 -0
- marvisx_cli-0.1.0/migrations/099_kg_edges_restore_weight_down.sql +12 -0
- marvisx_cli-0.1.0/migrations/100_kg_enriched_at.sql +25 -0
- marvisx_cli-0.1.0/migrations/100_kg_enriched_at_down.sql +12 -0
- marvisx_cli-0.1.0/migrations/101_local_llm_shadow_comparisons.sql +66 -0
- marvisx_cli-0.1.0/migrations/101_local_llm_shadow_comparisons_down.sql +15 -0
- marvisx_cli-0.1.0/migrations/102_promote_llm_costs.sql +69 -0
- marvisx_cli-0.1.0/migrations/102_promote_llm_costs_down.sql +19 -0
- marvisx_cli-0.1.0/migrations/103_ingest_skipped_log.sql +46 -0
- marvisx_cli-0.1.0/migrations/103_ingest_skipped_log_down.sql +15 -0
- marvisx_cli-0.1.0/migrations/120_docs_governance.sql +50 -0
- marvisx_cli-0.1.0/migrations/120_docs_governance_down.sql +11 -0
- marvisx_cli-0.1.0/migrations/121_notification_event_fk_cleanup.sql +21 -0
- marvisx_cli-0.1.0/migrations/121_notification_event_fk_cleanup_down.sql +10 -0
- marvisx_cli-0.1.0/migrations/122_docs_drift_history.sql +34 -0
- marvisx_cli-0.1.0/migrations/122_docs_drift_history_down.sql +15 -0
- marvisx_cli-0.1.0/migrations/123_ingest_parser_waiting_status.sql +69 -0
- marvisx_cli-0.1.0/migrations/123_ingest_parser_waiting_status_down.sql +69 -0
- marvisx_cli-0.1.0/migrations/124_heypocket_recordings.sql +63 -0
- marvisx_cli-0.1.0/migrations/124_heypocket_recordings_down.sql +13 -0
- marvisx_cli-0.1.0/migrations/125_kg_node_type_record.sql +219 -0
- marvisx_cli-0.1.0/migrations/125_kg_node_type_record_down.sql +205 -0
- marvisx_cli-0.1.0/migrations/126_ingest_terminal_upload_source_kind.sql +69 -0
- marvisx_cli-0.1.0/migrations/126_ingest_terminal_upload_source_kind_down.sql +69 -0
- marvisx_cli-0.1.0/migrations/127_brain_v1_substrate.sql +200 -0
- marvisx_cli-0.1.0/migrations/127_brain_v1_substrate_down.sql +32 -0
- marvisx_cli-0.1.0/migrations/128_brain_drift_signals.sql +157 -0
- marvisx_cli-0.1.0/migrations/128_brain_drift_signals_down.sql +23 -0
- marvisx_cli-0.1.0/migrations/129_brain_memory_operations.sql +232 -0
- marvisx_cli-0.1.0/migrations/129_brain_memory_operations_down.sql +27 -0
- marvisx_cli-0.1.0/migrations/130_brain_findings.sql +258 -0
- marvisx_cli-0.1.0/migrations/130_brain_findings_down.sql +29 -0
- marvisx_cli-0.1.0/migrations/132_kg_pr_modifies.sql +242 -0
- marvisx_cli-0.1.0/migrations/132_kg_pr_modifies_down.sql +99 -0
- marvisx_cli-0.1.0/migrations/133_brain_v1_2_direction_schema.sql +476 -0
- marvisx_cli-0.1.0/migrations/133_brain_v1_2_direction_schema_down.sql +273 -0
- marvisx_cli-0.1.0/migrations/134_brain_journal_narrative_polished.sql +8 -0
- marvisx_cli-0.1.0/migrations/134_brain_journal_narrative_polished_down.sql +6 -0
- marvisx_cli-0.1.0/migrations/135_kg_edges_provider.sql +21 -0
- marvisx_cli-0.1.0/migrations/136_documents_fts.sql +56 -0
- marvisx_cli-0.1.0/migrations/137_promote_llm_costs.sql +59 -0
- marvisx_cli-0.1.0/migrations/137_promote_llm_costs_down.sql +19 -0
- marvisx_cli-0.1.0/migrations/138_ingest_api_keys.sql +39 -0
- marvisx_cli-0.1.0/migrations/138_ingest_api_keys_down.sql +8 -0
- marvisx_cli-0.1.0/migrations/139_ingest_pending_ingress.sql +91 -0
- marvisx_cli-0.1.0/migrations/139_ingest_pending_ingress_down.sql +73 -0
- marvisx_cli-0.1.0/migrations/140_ingest_idempotency_quota.sql +45 -0
- marvisx_cli-0.1.0/migrations/140_ingest_idempotency_quota_down.sql +9 -0
- marvisx_cli-0.1.0/migrations/141_ingest_pending_metadata.sql +16 -0
- marvisx_cli-0.1.0/migrations/141_ingest_pending_metadata_down.sql +7 -0
- marvisx_cli-0.1.0/migrations/142_llm_function_config.sql +36 -0
- marvisx_cli-0.1.0/migrations/142_llm_function_config_down.sql +8 -0
- marvisx_cli-0.1.0/migrations/143_kg_code_embeddings.sql +25 -0
- marvisx_cli-0.1.0/migrations/143_kg_code_embeddings_down.sql +5 -0
- marvisx_cli-0.1.0/migrations/__init__.py +4 -0
- marvisx_cli-0.1.0/projects/_template/project.yaml +46 -0
- marvisx_cli-0.1.0/pyproject.toml +209 -0
- marvisx_cli-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
Business Source License 1.1
|
|
2
|
+
|
|
3
|
+
Parameters
|
|
4
|
+
|
|
5
|
+
Licensor: Emilio Martucci
|
|
6
|
+
Licensed Work: MarvisX
|
|
7
|
+
The Licensed Work is (c) 2026 Emilio Martucci.
|
|
8
|
+
Additional Use Grant: You may make production use of the Licensed Work only
|
|
9
|
+
for personal, non-commercial purposes (for example,
|
|
10
|
+
self-hosting it for your own individual use). Any other
|
|
11
|
+
production use is not granted here and requires a separate
|
|
12
|
+
commercial license from the Licensor. Uses that are NOT
|
|
13
|
+
granted include, without limitation: any commercial use;
|
|
14
|
+
any use by, within, or for the benefit of a business,
|
|
15
|
+
company, or other organization; offering the Licensed
|
|
16
|
+
Work (or a modified or adapted version of it) to third
|
|
17
|
+
parties as a hosted or managed service; and using a
|
|
18
|
+
modified or adapted version of the Licensed Work as, or
|
|
19
|
+
as part of, a product or service that competes with the
|
|
20
|
+
Licensor.
|
|
21
|
+
Change Date: 2030-01-01
|
|
22
|
+
Change License: Apache License, Version 2.0
|
|
23
|
+
|
|
24
|
+
-----------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
Notice
|
|
27
|
+
|
|
28
|
+
The Business Source License (this document, or the "License") is not an Open
|
|
29
|
+
Source license. However, the Licensed Work will eventually be made available
|
|
30
|
+
under an Open Source License, as stated in this License.
|
|
31
|
+
|
|
32
|
+
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
|
|
33
|
+
"Business Source License" is a trademark of MariaDB Corporation Ab.
|
|
34
|
+
|
|
35
|
+
Terms
|
|
36
|
+
|
|
37
|
+
The Licensor hereby grants You the right to copy, modify, create derivative
|
|
38
|
+
works, redistribute, and make non-production use of the Licensed Work. The
|
|
39
|
+
Licensor may make an Additional Use Grant, above, permitting limited production
|
|
40
|
+
use.
|
|
41
|
+
|
|
42
|
+
Effective on the Change Date, or the fourth anniversary of the first publicly
|
|
43
|
+
available distribution of a specific version of the Licensed Work under this
|
|
44
|
+
License, whichever comes first, the Licensor hereby grants you rights under the
|
|
45
|
+
terms of the Change License, and the rights granted in the paragraph above
|
|
46
|
+
terminate.
|
|
47
|
+
|
|
48
|
+
If your use of the Licensed Work does not comply with the requirements currently
|
|
49
|
+
in effect as described in this License, you must purchase a commercial license
|
|
50
|
+
from the Licensor, its affiliated entities, or authorized resellers, or you must
|
|
51
|
+
refrain from using the Licensed Work.
|
|
52
|
+
|
|
53
|
+
All copies of the original and modified Licensed Work, and derivative works of
|
|
54
|
+
the Licensed Work, are subject to this License. This License applies separately
|
|
55
|
+
for each version of the Licensed Work and the Change Date may vary for each
|
|
56
|
+
version of the Licensed Work released by Licensor.
|
|
57
|
+
|
|
58
|
+
You must conspicuously display this License on each original or modified copy of
|
|
59
|
+
the Licensed Work. If you receive the Licensed Work in original or modified form
|
|
60
|
+
from a third party, the terms and conditions set forth in this License apply to
|
|
61
|
+
your use of that work.
|
|
62
|
+
|
|
63
|
+
Any use of the Licensed Work in violation of this License will automatically
|
|
64
|
+
terminate your rights under this License for the current and all other versions
|
|
65
|
+
of the Licensed Work.
|
|
66
|
+
|
|
67
|
+
This License does not grant you any right in any trademark or logo of Licensor
|
|
68
|
+
or its affiliates (provided that you may use a trademark or logo of Licensor as
|
|
69
|
+
expressly required by this License).
|
|
70
|
+
|
|
71
|
+
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON AN
|
|
72
|
+
"AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
|
|
73
|
+
OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
|
|
74
|
+
FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
|
|
75
|
+
|
|
76
|
+
MariaDB hereby grants you permission to use this License’s text to license your
|
|
77
|
+
works, and to refer to it using the trademark"Business Source License", as long
|
|
78
|
+
as you comply with the Covenants of Licensor below.
|
|
79
|
+
|
|
80
|
+
Covenants of Licensor
|
|
81
|
+
|
|
82
|
+
In consideration of the right to use this License’s text and the "Business
|
|
83
|
+
Source License" name and trademark, Licensor covenants to MariaDB, and to all
|
|
84
|
+
other recipients of the licensed work to be provided by Licensor:
|
|
85
|
+
|
|
86
|
+
1. To specify as the Change License the GPL Version 2.0 or any later version, or
|
|
87
|
+
a license that is compatible with GPL Version 2.0 or a later version, where
|
|
88
|
+
"compatible" means that software provided under the Change License can be
|
|
89
|
+
included in a program with software provided under GPL Version 2.0 or a later
|
|
90
|
+
version. Licensor may specify additional Change Licenses without limitation.
|
|
91
|
+
|
|
92
|
+
2. To either: (a) specify an additional grant of rights to use that does not
|
|
93
|
+
impose any additional restriction on the right granted in this License, as
|
|
94
|
+
the Additional Use Grant; or (b) insert the text "None".
|
|
95
|
+
|
|
96
|
+
3. To specify a Change Date.
|
|
97
|
+
|
|
98
|
+
4. Not to modify this License in any other way.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Source-distribution manifest.
|
|
2
|
+
#
|
|
3
|
+
# `python -m build --sdist --wheel` builds the wheel FROM the sdist, so any
|
|
4
|
+
# runtime data-file missing from the sdist is also missing from that wheel —
|
|
5
|
+
# even though a DIRECT wheel build (uv build / pip wheel) would include it via
|
|
6
|
+
# [tool.setuptools.package-data]. uv infers sdist contents from the git file
|
|
7
|
+
# list; plain setuptools needs them spelled out here. Keep these globs in sync
|
|
8
|
+
# with [tool.setuptools.package-data] in pyproject.toml (learning 9e527cfa).
|
|
9
|
+
recursive-include migrations *.sql
|
|
10
|
+
recursive-include core/scripts/install_hooks *.sh *.json *.py
|
|
11
|
+
recursive-include core/api/templates *.md *.j2
|
|
12
|
+
recursive-include projects/_template *
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: marvisx-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MarvisX OSS — agent-native company-brain CLI runtime (init, status, brief, triage)
|
|
5
|
+
Author: MarvisX maintainers
|
|
6
|
+
License: BSL-1.1
|
|
7
|
+
Project-URL: Homepage, https://justaskmarvis.com
|
|
8
|
+
Project-URL: Documentation, https://justaskmarvis.com/docs/getting-started
|
|
9
|
+
Project-URL: Source, https://github.com/marvisx/marvisx-oss
|
|
10
|
+
Project-URL: Issues, https://github.com/marvisx/marvisx-oss/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/marvisx/marvisx-oss/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: marvisx,cli,bootstrap,wizard,oss,agent,company-brain
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: Other/Proprietary License
|
|
17
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
24
|
+
Classifier: Topic :: Utilities
|
|
25
|
+
Requires-Python: <3.14,>=3.10
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: typer>=0.12
|
|
29
|
+
Requires-Dist: rich>=13
|
|
30
|
+
Requires-Dist: click>=8
|
|
31
|
+
Requires-Dist: pydantic>=2.5
|
|
32
|
+
Requires-Dist: pydantic-settings>=2.7.0
|
|
33
|
+
Requires-Dist: PyYAML>=6
|
|
34
|
+
Requires-Dist: cryptography>=42
|
|
35
|
+
Requires-Dist: fastapi>=0.115.0
|
|
36
|
+
Requires-Dist: slowapi>=0.1.9
|
|
37
|
+
Requires-Dist: cachetools>=5.3.0
|
|
38
|
+
Requires-Dist: uvicorn[standard]>=0.34.0
|
|
39
|
+
Requires-Dist: uvloop>=0.21.0
|
|
40
|
+
Requires-Dist: aiosqlite>=0.20.0
|
|
41
|
+
Requires-Dist: PyJWT>=2.10.0
|
|
42
|
+
Requires-Dist: bcrypt>=4.2.0
|
|
43
|
+
Requires-Dist: email-validator>=2.2.0
|
|
44
|
+
Requires-Dist: defusedxml>=0.7.1
|
|
45
|
+
Requires-Dist: python-magic>=0.4.27
|
|
46
|
+
Requires-Dist: python-multipart>=0.0.18
|
|
47
|
+
Requires-Dist: filelock>=3.16.0
|
|
48
|
+
Requires-Dist: aiofiles>=24.1.0
|
|
49
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
50
|
+
Requires-Dist: itsdangerous>=2.1.0
|
|
51
|
+
Requires-Dist: pywebpush>=2.0.0
|
|
52
|
+
Requires-Dist: py-vapid>=1.9.0
|
|
53
|
+
Requires-Dist: anthropic<1.0.0,>=0.96.0
|
|
54
|
+
Requires-Dist: openai<2.0.0,>=1.50.0
|
|
55
|
+
Requires-Dist: httpx>=0.28.0
|
|
56
|
+
Requires-Dist: tenacity<10,>=9.1
|
|
57
|
+
Requires-Dist: tree-sitter<0.26,>=0.23.0
|
|
58
|
+
Requires-Dist: tree-sitter-python<0.25,>=0.23.0
|
|
59
|
+
Requires-Dist: tree-sitter-typescript~=0.23.2
|
|
60
|
+
Requires-Dist: pygit2>=1.15.0
|
|
61
|
+
Requires-Dist: markdown-it-py>=3.0.0
|
|
62
|
+
Requires-Dist: watchfiles>=1.1.0
|
|
63
|
+
Requires-Dist: Pillow>=10.0.0
|
|
64
|
+
Requires-Dist: openpyxl>=3.1.0
|
|
65
|
+
Requires-Dist: mcp>=1.12
|
|
66
|
+
Requires-Dist: onnxruntime>=1.18
|
|
67
|
+
Requires-Dist: tokenizers>=0.20
|
|
68
|
+
Requires-Dist: huggingface-hub>=0.24
|
|
69
|
+
Requires-Dist: numpy>=1.26
|
|
70
|
+
Requires-Dist: psutil>=5.9.0
|
|
71
|
+
Provides-Extra: dev
|
|
72
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
73
|
+
Requires-Dist: pytest-cov>=5; extra == "dev"
|
|
74
|
+
Dynamic: license-file
|
|
75
|
+
|
|
76
|
+
# marvis init
|
|
77
|
+
|
|
78
|
+
Interactive bootstrap wizard for MarvisX OSS. Five prompts (license,
|
|
79
|
+
storage, BYOK, first project, recap) reusing the shared `core/wizard/`
|
|
80
|
+
state machine so the CLI and the Console `/welcome` route produce
|
|
81
|
+
byte-identical settings when given the same answers.
|
|
82
|
+
|
|
83
|
+
## Install
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pip install marvisx-cli
|
|
87
|
+
marvis init
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Pre-install (clone and run) works too:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
python -m core.cli.marvis_init init
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Quick start (interactive)
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
marvis init
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
You will be asked:
|
|
103
|
+
|
|
104
|
+
1. **License** — accept BSL 1.1 (`y`/`n`).
|
|
105
|
+
2. **Storage** — projects root path, database backend (`sqlite` or
|
|
106
|
+
`postgres`), and either the SQLite file path or the Postgres DSN.
|
|
107
|
+
3. **LLM provider (BYOK)** — `anthropic`, `openai`, `mac_gateway`,
|
|
108
|
+
`bedrock`, or `skip`. API key prompt is hidden input. Mac gateway
|
|
109
|
+
asks for the base URL.
|
|
110
|
+
4. **First project** — name, slug, and type (`code`, `work`, `system`).
|
|
111
|
+
5. **Recap** — review choices, confirm.
|
|
112
|
+
|
|
113
|
+
On confirmation the wizard writes:
|
|
114
|
+
|
|
115
|
+
- `~/.marvis/settings.yaml` — workspace + storage + llm choice (no
|
|
116
|
+
secrets), chmod 600.
|
|
117
|
+
- `~/.marvis/master.key` + `~/.marvis/byok.vault` — Fernet-encrypted
|
|
118
|
+
API key store (only if a provider was chosen).
|
|
119
|
+
- `<projects_root>/<slug>/project.yaml` — first project seed.
|
|
120
|
+
|
|
121
|
+
## Non-interactive / CI
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
marvis init \
|
|
125
|
+
--accept-bsl \
|
|
126
|
+
--no-interactive \
|
|
127
|
+
--projects-root /var/lib/marvis/projects \
|
|
128
|
+
--db-backend sqlite \
|
|
129
|
+
--db-path /var/lib/marvis/console.db \
|
|
130
|
+
--llm-provider anthropic \
|
|
131
|
+
--llm-api-key "$ANTHROPIC_API_KEY" \
|
|
132
|
+
--project-name "Local Workspace" \
|
|
133
|
+
--project-slug local-workspace \
|
|
134
|
+
--project-type code
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
YAML preset (preferred for repeatable provisioning):
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
marvis init --no-interactive --config init.yaml
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`init.yaml`:
|
|
144
|
+
|
|
145
|
+
```yaml
|
|
146
|
+
welcome:
|
|
147
|
+
bsl_accepted: true
|
|
148
|
+
storage:
|
|
149
|
+
projects_root: /var/lib/marvis/projects
|
|
150
|
+
db_backend: sqlite
|
|
151
|
+
db_path: /var/lib/marvis/console.db
|
|
152
|
+
llm_provider:
|
|
153
|
+
provider: anthropic
|
|
154
|
+
api_key: sk-ant-...
|
|
155
|
+
first_project:
|
|
156
|
+
name: Local Workspace
|
|
157
|
+
slug: local-workspace
|
|
158
|
+
type: code
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Dry run
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
marvis init --dry-run --accept-bsl --no-interactive ...
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Prints the planned filesystem writes and the rendered `settings.yaml`
|
|
168
|
+
without touching the disk. Exit 0.
|
|
169
|
+
|
|
170
|
+
## Exit codes
|
|
171
|
+
|
|
172
|
+
| Code | Meaning |
|
|
173
|
+
| --- | --- |
|
|
174
|
+
| 0 | Success (or dry-run) |
|
|
175
|
+
| 1 | Generic runtime error |
|
|
176
|
+
| 2 | User abort at recap confirmation |
|
|
177
|
+
| 3 | Validation failure (field-level errors printed) |
|
|
178
|
+
|
|
179
|
+
## Tests
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
python -m pytest tests/test_cli_marvis_init.py
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Ten cases cover dry-run, non-interactive flags, YAML preset, BYOK vault
|
|
186
|
+
write, invalid slug rejection, Postgres backend, interactive prompts via
|
|
187
|
+
`CliRunner(input=...)`, BSL gate, and `show-state` JSON dump.
|
|
188
|
+
|
|
189
|
+
## Relation to `core/scripts/marvis-init.sh`
|
|
190
|
+
|
|
191
|
+
`marvis-init.sh` (bash) is a deploy bootstrap: copies
|
|
192
|
+
`deploy/_template/`, renders `.env` with secrets, runs
|
|
193
|
+
`setup-server.sh`, and brings up Docker Compose. It targets server
|
|
194
|
+
administrators provisioning a host.
|
|
195
|
+
|
|
196
|
+
`marvis init` (this Python CLI) is an onboarding wizard: writes
|
|
197
|
+
`settings.yaml` + BYOK vault + first project seed in the user's home.
|
|
198
|
+
It targets OSS users running MarvisX locally.
|
|
199
|
+
|
|
200
|
+
The two flows are complementary and will converge in a later phase. Until
|
|
201
|
+
then both ship side-by-side.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# MarvisX
|
|
2
|
+
|
|
3
|
+
Self-hosted, EU-resident **company brain** for agent-native operations: a cross-project Knowledge Graph, audit-immutable provenance, reflective Brain pipeline, and an agent-native Model Context Protocol surface.
|
|
4
|
+
|
|
5
|
+
Released as a defensive-publication architectural pattern. See the Zenodo preprint: [`10.5281/zenodo.20341860`](https://doi.org/10.5281/zenodo.20341860).
|
|
6
|
+
|
|
7
|
+
## What MarvisX gives you
|
|
8
|
+
|
|
9
|
+
- **Cross-project Knowledge Graph** with 17 deterministic edge types covering code, work-chain artifacts, knowledge-chain documents, cross-project references, and bridge edges. Canonical IDs follow `{prefix}:{kind}:{slug}`.
|
|
10
|
+
- **Foreign-key-immutable audit log** with provenance pinned at the SQLite level. Designed to satisfy the logging surface required by EU Regulation 2024/1689 (AI Act) Article 12.
|
|
11
|
+
- **Brain reflection pipeline** in five layers — substrate, digest and journal, drift checker, memory operations, findings — closed by a Direction-Aware loop.
|
|
12
|
+
- **Constitution-enforced safety rules** enforced by deterministic hook gates and an MCP mirror for providers without native hooks.
|
|
13
|
+
- **Agent-native MCP surface** exposing 91 tools, callable identically from Claude Code, Codex, Gemini, OpenCode, and a web console.
|
|
14
|
+
|
|
15
|
+
## Search and embedding quality
|
|
16
|
+
|
|
17
|
+
MarvisX-OSS Phase 1 defaults to **IBM Granite-Embedding-97m-Multilingual-R2** self-hosted via ONNX, blended with SQLite BM25 keyword search through Reciprocal Rank Fusion. Backend is selectable through `EMBEDDING_MODE`.
|
|
18
|
+
|
|
19
|
+
This is a deliberate tradeoff: EU compliance, self-hosting, and zero external embedding cost come at the cost of retrieval quality that is below commercial managed embedding providers. See [`docs/SEARCH-QUALITY.md`](docs/SEARCH-QUALITY.md) for the benchmark numbers, affected workflows, mitigations available today, and the Phase 2 fine-tune roadmap.
|
|
20
|
+
|
|
21
|
+
## License posture
|
|
22
|
+
|
|
23
|
+
- Code: **Business Source License 1.1**, with an automatic change date converting to **Apache License 2.0** four years after release.
|
|
24
|
+
- Documentation and architectural patterns: **CC-BY 4.0**.
|
|
25
|
+
|
|
26
|
+
The combination is intended to make the architecture freely citable while preserving the ability to ship a self-hosted reference deployment.
|
|
27
|
+
|
|
28
|
+
## Architecture map
|
|
29
|
+
|
|
30
|
+
The system groups capabilities into eight functional domains (`M1 Capture`, `M2 Index`, `M3 Retrieve`, `M4 Reflect`, `M5 Act`, `M6 Agent-native I/O`, `M7 Compliance`, `M8 Productization`). The Knowledge Graph stitches them together with canonical IDs and an audit chain.
|
|
31
|
+
|
|
32
|
+
For the full architectural description, see the Zenodo preprint linked above.
|
|
33
|
+
|
|
34
|
+
## Repository layout
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
core/
|
|
38
|
+
├── api/ # FastAPI service: KG, ingest, brain, MCP transport
|
|
39
|
+
├── console/ # Next.js web console
|
|
40
|
+
├── kb/ # Project-local knowledge base templates
|
|
41
|
+
├── mcp-pir/ # MCP server (stdio) exposing the 91-tool surface
|
|
42
|
+
└── scripts/ # Deployment, migration, and operational scripts
|
|
43
|
+
|
|
44
|
+
deploy/
|
|
45
|
+
└── _template/ # Reference deployment template
|
|
46
|
+
# (Docker Compose + environment scaffolding)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Quick start
|
|
50
|
+
|
|
51
|
+
The reference deployment uses Docker Compose. Clone the repository, copy `deploy/_template/.env.example` to `.env`, populate the required secrets, and bring the stack up:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
cp deploy/_template/.env.example deploy/_template/.env
|
|
55
|
+
cd deploy/_template/
|
|
56
|
+
docker compose up -d
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The Console becomes available on the configured `CONSOLE_PORT` and the API on the configured `API_PORT`. Detailed first-run instructions are inside the deployment template.
|
|
60
|
+
|
|
61
|
+
## Embedding migration from a managed provider
|
|
62
|
+
|
|
63
|
+
If you currently run MarvisX with a managed embedding provider such as Voyage AI, [`docs/MIGRATION-FROM-VOYAGE.md`](docs/MIGRATION-FROM-VOYAGE.md) covers the step-by-step path to the self-hosted Granite backend, including the re-index, KG threshold recalibration, and rollback procedure.
|
|
64
|
+
|
|
65
|
+
## MCP surface
|
|
66
|
+
|
|
67
|
+
MarvisX ships an MCP server exposing 91 tools across 11 categories: project and session context, tasks, handoffs, semantic search, learnings, costs, pull requests, knowledge graph queries, ingest triage, brain reflection layer, and audit-and-monitoring controls.
|
|
68
|
+
|
|
69
|
+
The same surface is used by autonomous agents and by humans through the web console. The intent is parity: any action a user can take through the console, an agent can also take through MCP, and the reverse.
|
|
70
|
+
|
|
71
|
+
## Single-user local runtime (`MARVIS_OSS_LOCAL`)
|
|
72
|
+
|
|
73
|
+
The MCP server runs in-process: it calls the same use_cases the HTTP API calls, against the local SQLite database, with no uvicorn and no Node bridge. In this single-user mode there is no HTTP API in front of the database, so the HTTP audit chokepoint (which in the managed deployment forces every mutation through the API) does not exist.
|
|
74
|
+
|
|
75
|
+
Audit is still recorded: the extracted use_cases write the audit log themselves (`core/api/use_cases/{tasks,pull_requests,audit}.py`), so a mutation issued through MCP still produces an audit row at the use_case level. What is lost is only the additional HTTP-surface chokepoint.
|
|
76
|
+
|
|
77
|
+
Setting `MARVIS_OSS_LOCAL=1` (truthy: `1`/`true`/`yes`/`on`) makes the `block-db-direct-write` safety rule **advisory** — direct writes to a PiR SQLite database are allowed with a warning instead of being blocked. When the variable is unset or falsey the rule is unchanged: direct DB writes are blocked fail-closed, exactly as in the managed deployment. This trade-off is intentional for single-user self-hosting and never weakens the default.
|
|
78
|
+
|
|
79
|
+
**No-fork guarantee.** The HTTP API and the MCP server are not two implementations: both are thin adapters over the same `core/api/use_cases`, differing only in how they fill the per-call `CallerContext`. The proof is the API test suite staying green after the extraction — the same behaviour, exercised through the HTTP surface, over the identical use_cases the MCP server calls.
|
|
80
|
+
|
|
81
|
+
## Documentation
|
|
82
|
+
|
|
83
|
+
- [`docs/SEARCH-QUALITY.md`](docs/SEARCH-QUALITY.md) — search quality expectations, affected workflows, and mitigations
|
|
84
|
+
- [`docs/MIGRATION-FROM-VOYAGE.md`](docs/MIGRATION-FROM-VOYAGE.md) — migration from managed embeddings to Granite
|
|
85
|
+
- [`docs/solutions/architecture-patterns/`](docs/solutions/architecture-patterns/) — architectural decision records
|
|
86
|
+
|
|
87
|
+
## Contributing
|
|
88
|
+
|
|
89
|
+
This is a defensive-publication release. The repository accepts issues for bug reports and clarifications. The architecture itself is documented in the Zenodo preprint; the codebase is intended as the reference implementation of that architecture.
|
|
90
|
+
|
|
91
|
+
## References
|
|
92
|
+
|
|
93
|
+
- Preprint (Zenodo): [`10.5281/zenodo.20341860`](https://doi.org/10.5281/zenodo.20341860)
|
|
94
|
+
- License (code): Business Source License 1.1, change date converts to Apache License 2.0 four years after release
|
|
95
|
+
- License (documentation): CC-BY 4.0
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# v1.0.0 - 2026-03-02 - DevX session health checker (v1: dimension C only)
|
|
2
|
+
"""Session health check — DevX Layer Sprint 3.
|
|
3
|
+
|
|
4
|
+
v1 implementa solo Dimensione C (Continuita): sessione idle senza input richiesto.
|
|
5
|
+
Le dimensioni A (task hygiene), B (context%), D (output quality) sono deferred Sprint 4.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
from datetime import datetime, timezone
|
|
12
|
+
|
|
13
|
+
from core.api.models import SessionInfo
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
IDLE_THRESHOLD_MINUTES = 15
|
|
18
|
+
SESSION_MANAGER_COOLDOWN_MINUTES = 30 # Rate limit: max 1 msg per sessione per 30 min
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class HealthCheckResult:
|
|
23
|
+
session_name: str
|
|
24
|
+
action: str # "send_message" | "escalate" | "ok"
|
|
25
|
+
message: str | None
|
|
26
|
+
escalation_reason: str | None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
async def check_session_health(
|
|
30
|
+
session: SessionInfo,
|
|
31
|
+
last_action_at: datetime | None,
|
|
32
|
+
) -> HealthCheckResult:
|
|
33
|
+
"""v1: Solo dimensione C — sessione idle senza input richiesto.
|
|
34
|
+
|
|
35
|
+
Le dimensioni A, B, D sono deferred alla prossima sprint
|
|
36
|
+
dopo validazione di C in produzione.
|
|
37
|
+
"""
|
|
38
|
+
# Rate limit: non mandare piu di 1 messaggio per cooldown period
|
|
39
|
+
if last_action_at is not None:
|
|
40
|
+
elapsed = (datetime.now(timezone.utc) - last_action_at).total_seconds() / 60
|
|
41
|
+
if elapsed < SESSION_MANAGER_COOLDOWN_MINUTES:
|
|
42
|
+
return HealthCheckResult(session.name, "ok", None, None)
|
|
43
|
+
|
|
44
|
+
# C — Continuita: sessione idle senza input richiesto
|
|
45
|
+
if session.activity_state == "idle" and not _session_waiting_for_input(session):
|
|
46
|
+
return HealthCheckResult(
|
|
47
|
+
session.name,
|
|
48
|
+
"send_message",
|
|
49
|
+
"La sessione sembra ferma. Continua con il task corrente. "
|
|
50
|
+
"Ricorda di aggiornare i task e fare handoff a fine sessione.",
|
|
51
|
+
None,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
return HealthCheckResult(session.name, "ok", None, None)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _session_waiting_for_input(session: SessionInfo) -> bool:
|
|
58
|
+
"""True se la sessione CC sta aspettando input (needs_input activity state)."""
|
|
59
|
+
return session.activity_state == "needs_input"
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# v1.0.0 - 2026-03-02 - DevX Session Manager Agent
|
|
2
|
+
"""Session Manager Agent — DevX Layer Sprint 3.
|
|
3
|
+
|
|
4
|
+
Runs every 10 minutes via host cron or manual trigger.
|
|
5
|
+
Monitors sessions with agent_managed=True, runs health checks, acts on results.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
cd /data/pir && python -m api.agents.session_manager
|
|
9
|
+
"""
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import asyncio
|
|
13
|
+
import json
|
|
14
|
+
import logging
|
|
15
|
+
import os
|
|
16
|
+
from datetime import datetime, timezone
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
import aiosqlite
|
|
20
|
+
|
|
21
|
+
from core.api.config import settings
|
|
22
|
+
from core.api.agents.session_health import check_session_health
|
|
23
|
+
from core.api.models import SessionInfo
|
|
24
|
+
from core.api.services import tmux
|
|
25
|
+
|
|
26
|
+
logger = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
ERRORS_DIR = Path("/data/pir/logs/errors")
|
|
29
|
+
|
|
30
|
+
# ── helpers ──────────────────────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
async def list_agent_managed_sessions() -> list[SessionInfo]:
|
|
33
|
+
"""Return all sessions with agent_managed=True via the sessions API.
|
|
34
|
+
|
|
35
|
+
Uses the internal API endpoint to get live activity_state (computed from tmux,
|
|
36
|
+
not stored in DB). Falls back to empty list on error.
|
|
37
|
+
"""
|
|
38
|
+
import urllib.request
|
|
39
|
+
from core.api.config import settings as cfg
|
|
40
|
+
token = cfg.tasks_api_token if hasattr(cfg, "tasks_api_token") else os.environ.get("TASKS_API_TOKEN", "")
|
|
41
|
+
api_base = os.environ.get("PIR_INTERNAL_BASE", "http://localhost:8100")
|
|
42
|
+
try:
|
|
43
|
+
req = urllib.request.Request(
|
|
44
|
+
f"{api_base}/api/v1/sessions?agent_managed=true",
|
|
45
|
+
headers={
|
|
46
|
+
"Authorization": f"Bearer {token}",
|
|
47
|
+
"X-Agent-Name": "marvisx",
|
|
48
|
+
},
|
|
49
|
+
)
|
|
50
|
+
with urllib.request.urlopen(req, timeout=10) as resp:
|
|
51
|
+
data = json.loads(resp.read())
|
|
52
|
+
return [SessionInfo(**s) for s in data]
|
|
53
|
+
except Exception as exc:
|
|
54
|
+
logger.error("Failed to list agent_managed sessions: %s", exc)
|
|
55
|
+
return []
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
async def get_last_agent_action(db: aiosqlite.Connection, session_name: str) -> datetime | None:
|
|
59
|
+
"""Return the last time an automated action was taken on this session."""
|
|
60
|
+
try:
|
|
61
|
+
cursor = await db.execute(
|
|
62
|
+
"SELECT MAX(created_at) FROM agent_actions WHERE session_name = ?",
|
|
63
|
+
(session_name,),
|
|
64
|
+
)
|
|
65
|
+
row = await cursor.fetchone()
|
|
66
|
+
if row and row[0]:
|
|
67
|
+
# Parse ISO string from SQLite — may be naive (no tz offset)
|
|
68
|
+
ts_str: str = row[0]
|
|
69
|
+
ts_str = ts_str.replace("Z", "+00:00")
|
|
70
|
+
dt = datetime.fromisoformat(ts_str)
|
|
71
|
+
# SQLite stores UTC without offset — assume UTC if naive
|
|
72
|
+
if dt.tzinfo is None:
|
|
73
|
+
dt = dt.replace(tzinfo=timezone.utc)
|
|
74
|
+
return dt
|
|
75
|
+
except Exception as exc:
|
|
76
|
+
logger.warning("Failed to get last agent action for %s: %s", session_name, exc)
|
|
77
|
+
return None
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
async def log_agent_action(
|
|
81
|
+
db: aiosqlite.Connection,
|
|
82
|
+
session_name: str,
|
|
83
|
+
action: str,
|
|
84
|
+
detail: str | None,
|
|
85
|
+
) -> None:
|
|
86
|
+
"""Log an automated action taken on a session."""
|
|
87
|
+
try:
|
|
88
|
+
await db.execute(
|
|
89
|
+
"""
|
|
90
|
+
INSERT INTO agent_actions (agent_name, session_name, action, detail, created_at)
|
|
91
|
+
VALUES (?, ?, ?, ?, ?)
|
|
92
|
+
""",
|
|
93
|
+
("session-manager", session_name, action, detail, datetime.now(timezone.utc).isoformat()),
|
|
94
|
+
)
|
|
95
|
+
await db.commit()
|
|
96
|
+
except Exception as exc:
|
|
97
|
+
logger.error("Failed to log agent action: %s", exc)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
async def send_session_message(session_name: str, text: str) -> bool:
|
|
101
|
+
"""Send a message to a tmux session."""
|
|
102
|
+
try:
|
|
103
|
+
return await tmux.send_keys(session_name, text)
|
|
104
|
+
except Exception as exc:
|
|
105
|
+
logger.error("Failed to send message to session %s: %s", session_name, exc)
|
|
106
|
+
return False
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
async def send_telegram_alert(text: str) -> None:
|
|
110
|
+
"""Send a Telegram alert (best-effort)."""
|
|
111
|
+
import urllib.request
|
|
112
|
+
if not settings.telegram_bot_token or not settings.telegram_owner_chat_id:
|
|
113
|
+
logger.info("Telegram not configured, skipping alert")
|
|
114
|
+
return
|
|
115
|
+
try:
|
|
116
|
+
url = f"https://api.telegram.org/bot{settings.telegram_bot_token}/sendMessage"
|
|
117
|
+
data = json.dumps({
|
|
118
|
+
"chat_id": settings.telegram_owner_chat_id,
|
|
119
|
+
"text": text,
|
|
120
|
+
"parse_mode": "HTML",
|
|
121
|
+
}).encode("utf-8")
|
|
122
|
+
req = urllib.request.Request(
|
|
123
|
+
url, data=data,
|
|
124
|
+
headers={"Content-Type": "application/json"},
|
|
125
|
+
method="POST",
|
|
126
|
+
)
|
|
127
|
+
with urllib.request.urlopen(req, timeout=5) as resp:
|
|
128
|
+
resp.read()
|
|
129
|
+
except Exception as exc:
|
|
130
|
+
logger.warning("Telegram alert failed: %s", exc)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
async def log_error_to_knowledge(session_name: str, error_text: str) -> None:
|
|
134
|
+
"""Log an error to the knowledge errors store for downstream analysis."""
|
|
135
|
+
ERRORS_DIR.mkdir(parents=True, exist_ok=True)
|
|
136
|
+
ts = datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S")
|
|
137
|
+
error_file = ERRORS_DIR / f"{ts}-session-manager-{session_name}.txt"
|
|
138
|
+
try:
|
|
139
|
+
error_file.write_text(
|
|
140
|
+
f"session: {session_name}\nerror: {error_text}\nts: {ts}\n"
|
|
141
|
+
)
|
|
142
|
+
except Exception as exc:
|
|
143
|
+
logger.error("Failed to write error file: %s", exc)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
# ── core loop ────────────────────────────────────────────────────────────────
|
|
147
|
+
|
|
148
|
+
async def _process_session(
|
|
149
|
+
db: aiosqlite.Connection,
|
|
150
|
+
session: SessionInfo,
|
|
151
|
+
) -> None:
|
|
152
|
+
"""Process a single session — isolated to not block others."""
|
|
153
|
+
last_action_at = await get_last_agent_action(db, session.name)
|
|
154
|
+
result = await check_session_health(session, last_action_at)
|
|
155
|
+
|
|
156
|
+
if result.action == "send_message" and result.message:
|
|
157
|
+
success = await send_session_message(session.name, result.message)
|
|
158
|
+
if success:
|
|
159
|
+
await log_agent_action(db, session.name, "health_check:C", result.message)
|
|
160
|
+
logger.info("Sent health check message to session %s", session.name)
|
|
161
|
+
else:
|
|
162
|
+
logger.warning("Failed to send message to session %s", session.name)
|
|
163
|
+
|
|
164
|
+
elif result.action == "escalate" and result.escalation_reason:
|
|
165
|
+
await send_telegram_alert(
|
|
166
|
+
f"<b>DevX Escalation</b> — <code>{session.name}</code>\n\n{result.escalation_reason}"
|
|
167
|
+
)
|
|
168
|
+
await log_agent_action(db, session.name, "escalate", result.escalation_reason)
|
|
169
|
+
logger.warning("Escalated session %s: %s", session.name, result.escalation_reason)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
async def run_session_manager() -> None:
|
|
173
|
+
"""Main loop: monitor agent_managed sessions, run health checks."""
|
|
174
|
+
logger.info("Session Manager starting...")
|
|
175
|
+
from core.api.db import write_db
|
|
176
|
+
async with write_db() as db:
|
|
177
|
+
sessions = await list_agent_managed_sessions()
|
|
178
|
+
if not sessions:
|
|
179
|
+
logger.info("No agent_managed sessions to monitor")
|
|
180
|
+
return
|
|
181
|
+
|
|
182
|
+
logger.info("Checking %d agent_managed session(s)...", len(sessions))
|
|
183
|
+
|
|
184
|
+
results = await asyncio.gather(
|
|
185
|
+
*[_process_session(db, s) for s in sessions],
|
|
186
|
+
return_exceptions=True,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
for session, result in zip(sessions, results):
|
|
190
|
+
if isinstance(result, Exception):
|
|
191
|
+
logger.error(
|
|
192
|
+
"Health check failed for session %s: %s", session.name, result
|
|
193
|
+
)
|
|
194
|
+
await log_error_to_knowledge(session.name, str(result))
|
|
195
|
+
|
|
196
|
+
logger.info("Session Manager complete")
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
# ── CLI entrypoint ────────────────────────────────────────────────────────────
|
|
200
|
+
|
|
201
|
+
if __name__ == "__main__":
|
|
202
|
+
logging.basicConfig(
|
|
203
|
+
level=logging.INFO,
|
|
204
|
+
format="%(asctime)s %(levelname)s %(name)s — %(message)s",
|
|
205
|
+
)
|
|
206
|
+
asyncio.run(run_session_manager())
|