marvisx-cli 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {marvisx_cli-0.1.0/marvisx_cli.egg-info → marvisx_cli-0.2.0}/PKG-INFO +2 -1
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/config.py +28 -2
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/db.py +71 -5
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/main.py +8 -2
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/findings.py +6 -1
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/embedding_service.py +8 -2
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/insert_saga.py +53 -3
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/terminal_metrics_dump.py +30 -11
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/search.py +9 -14
- marvisx_cli-0.2.0/core/cli/marvis_account.py +132 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_init.py +30 -4
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_runtime.py +12 -3
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/telemetry/client.py +1 -1
- marvisx_cli-0.2.0/core/telemetry/entitlements.py +26 -0
- marvisx_cli-0.2.0/core/telemetry/rollup.py +281 -0
- marvisx_cli-0.2.0/core/telemetry/sender.py +224 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0/marvisx_cli.egg-info}/PKG-INFO +2 -1
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/marvisx_cli.egg-info/SOURCES.txt +5 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/marvisx_cli.egg-info/requires.txt +1 -0
- marvisx_cli-0.2.0/migrations/144_notifications_pending_sync_index.sql +14 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/pyproject.toml +8 -1
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/LICENSE +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/MANIFEST.in +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/README.md +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/agents/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/agents/session_health.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/agents/session_manager.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/bin/marvisx-state-hook.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/dependencies/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/dependencies/tenant.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/_adapter.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/server.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/brain.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/graph.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/handoffs.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/ingest.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/learnings.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/projects.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/pull_requests.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/safety.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/search.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/tasks.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/middleware/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/middleware/tool_call_audit.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/auth.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/brain.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/common.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/costs.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/graph.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/graph_cosmo.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/graph_pr_impact.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/graph_ux.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/inbox.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/ingest_keys.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/kg.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/llm_config.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/monitoring.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/projects.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/search.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/sessions.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/tasks.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/teams.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/users.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/observability/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/observability/tracing.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/paths.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/rate_limit.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/rbac.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/_adapter.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/admin_pr_impact.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/admin_settings.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/agent.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/agent_tokens.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/app_settings.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/audit.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/auth.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/bench.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/brain.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/brain_directions.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/ci_checks.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/comments.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/costs.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/docs_coverage.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/docs_governance.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/documents.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/files.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/finder.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/graph.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/handoffs.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/inbox.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/ingest_api_keys.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/ingest_triage.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/judge.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/kg.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/learnings.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/llm_config.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/monitoring.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/notifications.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/pr_impact.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/projects.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/pull_requests.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/push.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/raci.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/search.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/sessions.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/settings.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/share_repo.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/status_updates.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/tags.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/tasks.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/teams.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/terminal.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/users.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/webhooks.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/runtime_settings.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/security.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/audit.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/auto_approval.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/baseline.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/capabilities.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/cascade_rollup.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/compound_bridge.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/cycle.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/cycle_snapshot.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/digest_collector.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/direction.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/drift.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/drift_router.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/edge_metrics.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/events_reader.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/findings_reader.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/jobs.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/journal.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/knowledge_forms.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/_runner.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/base.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/cache.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/constants.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/direction_alignment.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/factory.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/finding_reasoning.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/finding_summary.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/grounding.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/journal_polish.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/local_gateway.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/parsers.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/router_glue.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/memory_ops.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/models.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/owner_hint.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/recap.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/_signals.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr1_activity_without_status.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr2_decision_without_adr.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr3_stale_open_loop.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr4_docs_governance_drift.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr5_playbook_changed.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr6_external_update_unpropagated.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr7_claimed_decision_gap.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr8_direction_misalignment.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/runs_reader.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/scope.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/sources/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/sources/base.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/sources/git_kg.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/sources/handoffs.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/sources/ingestor.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/sources/learnings.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/sources/pir_tasks.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/watermarks.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/ws_emitter.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/cc_tasks_reader.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ci_service.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/claude_metrics.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/codex_metrics.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/conversation_reader.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/cost_service.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/crypto.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/docs_governance/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/docs_governance/confidence.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/docs_governance/config.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/docs_governance/enrichment.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/docs_governance/frontmatter_validator.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/docs_governance/hard_gates.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/docs_governance/triage_orchestrator.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/embedding_internal.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/event_dispatcher.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/events.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/git_ops.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/graph_cosmo_service.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/graph_ranker.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/graph_service.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_digest.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_digest_deep_research.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_digest_jobs.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_gmail_sync.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_llm_classifier.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_source_identity.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_sources.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_taxonomy.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_tldr.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_triage.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/api_key_auth.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/auto_approve.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/classifier.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/confidence.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/dispatch.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/embedding_router.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/events.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/ignore_patterns.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/image_probe.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/ingress.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/anthropic_haiku.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/base.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/byok_provider.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/classification_context.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/config_store.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/factory.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/kg_enricher.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/local_gateway.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/local_vllm.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/openai_nano.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/lock_advisory.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parser_router.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/docling_parser.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/docparse_gateway.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/docx_parser.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/folder_unpacker.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/gateway_aux.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/image_parser.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/internal_markdown.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/ocr_gateway.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/ocr_pdf_parser.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/pdf_types.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/transcript_parser.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/vision_gateway.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/xlsx_parser.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/zip_unpacker.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/preflight.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/retry_voyage.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/routing_policy.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/serializers/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/serializers/xlsx_to_markdown.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/skip_log.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/watcher.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/audit.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/hybrid_search.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/lens.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/pr_impact.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/queries.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/ranking.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/rrf.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg_watcher_control.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/local_llm/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/local_llm/async_client.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/local_llm/client.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/local_llm/url_validator.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/metrics_collector.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/metrics_providers.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/model_registry.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/model_router.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/n8n_client.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/newsletter_llm_gateway.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/notification_service.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/openai_responses.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/opencode_metrics.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/opencode_sessions.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pii_redactor.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_impact_pipeline/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_impact_pipeline/differ.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_impact_pipeline/dispatcher.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_impact_pipeline/gc.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_impact_pipeline/languages.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_impact_pipeline/parser.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_impact_pipeline/writer.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_service.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/project_paths.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/project_status_updates.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/providers.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/push_service.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/reminder_service.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/runas.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/salience_service.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/security_collector.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/session_catalog.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/session_metrics_service.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/session_ops.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/session_state.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/share_links.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/task_transitions.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/terminal_metrics.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/tmux.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/webhook_service.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/workspace_sync.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/templates/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/templates/markdown_share.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/terminal.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_agent_facing_auth_dependencies.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_audit_permissions.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_backfill_session_conversations.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_backfill_working_seconds_msg.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_claude_metrics.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_codex_metrics.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_finder_paths.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_git_ops_merge.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_learnings_check_search.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_metrics_providers.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_migration_087.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_migration_088.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_migration_089.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_openai_responses.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_opencode_metrics.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_opencode_sessions.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_pr_workflow_e2e.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_projects_handoffs.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_providers.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_safety_bridge.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_session_catalog.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_session_conversations.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_session_metrics_service.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_session_resume_paths.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_session_theme_mode_migration.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_sessions_rbac.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_share_edit.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_share_repo.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_terminal_session_manager.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_terminal_upload.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_tmux.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_workspace_sync.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_ws_ticket_in_memory.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/_context.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/_errors.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/_roles.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/audit.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/brain.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/costs.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/graph.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/handoffs.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/ingest_triage.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/learnings.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/projects.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/pull_requests.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/tasks.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/visibility.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/README.md +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/_index_source.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/_runtime_ctx.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/_transmute.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_doctor.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_feedback.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_governance.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_hooks.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_mcp.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_telemetry.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/_drift_check.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/_frontmatter.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/_graph_writer.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/ast_parser.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/_config.sh +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/block-dangerous-bash.sh +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/block-db-direct-write.sh +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/block-push-no-task.sh +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/block-staging-to-prod.sh +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/block-subtree-push.sh +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/config.json +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/enforce-no-merge-main.sh +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/enforce-worktree.sh +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/quality-gate.sh +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/safety_bridge.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/secret-scan.sh +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/migrate_spike_node_ids.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/populate_artifacts.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/populate_cross_project.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/populate_inbox_nodes.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/populate_pr_impact.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/populate_project_nodes.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/populate_touch_counter.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/reparse_failed.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/safety_bridge.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/telemetry/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/telemetry/schema.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/wizard/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/wizard/byok_vault.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/wizard/defaults.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/wizard/state.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/wizard/steps.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/wizard/validation.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/marvisx_cli.egg-info/dependency_links.txt +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/marvisx_cli.egg-info/entry_points.txt +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/marvisx_cli.egg-info/top_level.txt +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/001_initial.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/002_tasks.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/003_session_management.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/004_projects_comments.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/005_session_intelligence.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/006_settings.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/007_task_scoring.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/008_cost_tracking.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/009_session_card_metrics.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/010_monitoring.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/012_agent_api.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/013_session_complete.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/015_pull_requests.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/015_pull_requests_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/016_users_raci.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/017_task_cost_entries.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/018_agents.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/018_agents_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/019_review_feedback.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/020_pr_commit_sha.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/021_webhook_events.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/022_devx_agent_managed.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/022_devx_agent_managed_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/023_devx_p1_gate.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/023_devx_p1_gate_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/024_chat_messages.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/024_pr_conversation_id.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/024_task_indexes.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/024_task_indexes_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/025_audit_log.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/026_agent_tokens.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/027_teams_auth_phase_b.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/028_learnings.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/029_team_roles.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/030_finder_pins.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/031_pr_deploy_status.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/032_task_reminders.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/033_events_retry_count.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/033_session_owner.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/034_notifications.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/035_shared_links.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/036_session_index_upgrade.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/037_pr_approval.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/038_pr_submitted_by.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/039_push_subscriptions.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/040_semantic_search.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/041_workspaces.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/042_oidc_providers.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/043_ci_checks.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/044_agent_metrics.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/045_documents_doc_type.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/046_salience.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/047_seed_missing_agents.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/048_fix_agent_paths_roles.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/049_agent_role_and_learnings_schema.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/050_session_provider.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/051_session_launch_profile.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/052_session_theme_mode.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/052_task_kind.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/053_inbox_items.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/054_inbox_triage_contract.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/055_inbox_topic_treatment.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/056_inbox_treatment_read_save.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/057_session_theme_mode_backfill.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/058_inbox_item_status_lifecycle.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/059_inbox_tldr_and_source_scores.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/060_newsletter.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/061_inbox_redesign.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/062_fix_inbox_sources_backfill.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/063_task_completion_mode.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/064_judge_mode_setting.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/065_knowledge_graph_spike.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/066_digest_ranking_inputs.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/066_kg_artifact_nodes.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/067_inbox_digest_selections.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/067_kg_temporal.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/068_inbox_digest_app_settings.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/068_kg_touch_counter.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/069_kg_doc_types.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/070_digest_ranking_inputs_recovery.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/071_inbox_digest_selections_recovery.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/072_inbox_digest_app_settings_recovery.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/073_kg_cross_project.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/073_kg_cross_project_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/074_kg_infra_types.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/074_kg_infra_types_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/075_kg_file_state_recovery.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/075_kg_file_state_recovery_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/076_kg_watcher_state.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/076_kg_watcher_state_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/077_kg_doc_types_extend.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/077_kg_doc_types_extend_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/078_kg_fts5.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/078_kg_fts5_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/079_kg_missing_indexes.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/079_kg_missing_indexes_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/080_kg_fts5_extended.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/080_kg_fts5_extended_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/081_kg_lens_indexes.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/081_kg_lens_indexes_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/082_kg_pins.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/082_kg_pins_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/083_kg_graph_nodes_degree.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/083_kg_graph_nodes_degree_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/084_drop_legacy_scheduler_tables.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/084_drop_legacy_scheduler_tables_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/085_kg_edge_resolves_to.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/085_kg_edge_resolves_to_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/086_project_status_updates_feed.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/086_project_status_updates_feed_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/087_session_metrics_dual.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/087_session_metrics_dual_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/088_rename_context_pct_legacy.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/088_rename_context_pct_legacy_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/089_session_metrics_equivalent_cost.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/089_session_metrics_equivalent_cost_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/090_kg_inbox_node_type.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/090_kg_inbox_node_type_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/091_kg_inbox_node_type_check.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/091_kg_inbox_node_type_check_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/092_sessions_activity_state_ts.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/092_sessions_activity_state_ts_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/093_sessions_activity_state_column.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/093_sessions_activity_state_column_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/094_ingest_pending.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/094_ingest_pending_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/095_kg_intent_first.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/095_kg_intent_first_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/096_kg_xlsx_artifact_prefix.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/096_kg_xlsx_artifact_prefix_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/097_ingest_change_history.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/097_ingest_change_history_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/098_kg_node_type_business.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/098_kg_node_type_business_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/099_kg_edges_restore_weight.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/099_kg_edges_restore_weight_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/100_kg_enriched_at.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/100_kg_enriched_at_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/101_local_llm_shadow_comparisons.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/101_local_llm_shadow_comparisons_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/102_promote_llm_costs.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/102_promote_llm_costs_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/103_ingest_skipped_log.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/103_ingest_skipped_log_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/120_docs_governance.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/120_docs_governance_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/121_notification_event_fk_cleanup.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/121_notification_event_fk_cleanup_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/122_docs_drift_history.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/122_docs_drift_history_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/123_ingest_parser_waiting_status.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/123_ingest_parser_waiting_status_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/124_heypocket_recordings.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/124_heypocket_recordings_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/125_kg_node_type_record.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/125_kg_node_type_record_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/126_ingest_terminal_upload_source_kind.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/126_ingest_terminal_upload_source_kind_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/127_brain_v1_substrate.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/127_brain_v1_substrate_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/128_brain_drift_signals.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/128_brain_drift_signals_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/129_brain_memory_operations.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/129_brain_memory_operations_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/130_brain_findings.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/130_brain_findings_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/132_kg_pr_modifies.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/132_kg_pr_modifies_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/133_brain_v1_2_direction_schema.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/133_brain_v1_2_direction_schema_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/134_brain_journal_narrative_polished.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/134_brain_journal_narrative_polished_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/135_kg_edges_provider.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/136_documents_fts.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/137_promote_llm_costs.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/137_promote_llm_costs_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/138_ingest_api_keys.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/138_ingest_api_keys_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/139_ingest_pending_ingress.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/139_ingest_pending_ingress_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/140_ingest_idempotency_quota.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/140_ingest_idempotency_quota_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/141_ingest_pending_metadata.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/141_ingest_pending_metadata_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/142_llm_function_config.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/142_llm_function_config_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/143_kg_code_embeddings.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/143_kg_code_embeddings_down.sql +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/__init__.py +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/projects/_template/project.yaml +0 -0
- {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: marvisx-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: MarvisX OSS — agent-native company-brain CLI runtime (init, status, brief, triage)
|
|
5
5
|
Author: MarvisX maintainers
|
|
6
6
|
License: BSL-1.1
|
|
@@ -68,6 +68,7 @@ Requires-Dist: tokenizers>=0.20
|
|
|
68
68
|
Requires-Dist: huggingface-hub>=0.24
|
|
69
69
|
Requires-Dist: numpy>=1.26
|
|
70
70
|
Requires-Dist: psutil>=5.9.0
|
|
71
|
+
Requires-Dist: sqlite-vec>=0.1.6
|
|
71
72
|
Provides-Extra: dev
|
|
72
73
|
Requires-Dist: pytest>=8; extra == "dev"
|
|
73
74
|
Requires-Dist: pytest-cov>=5; extra == "dev"
|
|
@@ -8,6 +8,29 @@ from typing import Literal
|
|
|
8
8
|
from pydantic import AliasChoices, Field, SecretStr
|
|
9
9
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
10
10
|
|
|
11
|
+
# Prod (Hetzner/Docker) ships the vec0 loadable at this path; it stays the
|
|
12
|
+
# final fallback so prod keeps working unchanged.
|
|
13
|
+
_VEC0_PATH_PROD_DEFAULT = "/data/pir/lib/vec0"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _default_vec0_path() -> str:
|
|
17
|
+
"""Resolve the vec0 loadable path for sqlite-vec.
|
|
18
|
+
|
|
19
|
+
Order:
|
|
20
|
+
1. ``$VEC0_PATH`` env — handled by pydantic-settings (overrides this
|
|
21
|
+
default_factory when set), so it is NOT re-read here.
|
|
22
|
+
2. The installed ``sqlite_vec`` package's bundled loadable
|
|
23
|
+
(``sqlite_vec.loadable_path()``) — the OSS clean-install path
|
|
24
|
+
(`pip install sqlite-vec`), platform-correct (.so / .dylib).
|
|
25
|
+
3. ``/data/pir/lib/vec0`` — prod fallback.
|
|
26
|
+
"""
|
|
27
|
+
try:
|
|
28
|
+
import sqlite_vec # type: ignore
|
|
29
|
+
|
|
30
|
+
return str(sqlite_vec.loadable_path())
|
|
31
|
+
except Exception: # noqa: BLE001 — missing/old package → prod fallback
|
|
32
|
+
return _VEC0_PATH_PROD_DEFAULT
|
|
33
|
+
|
|
11
34
|
|
|
12
35
|
class Settings(BaseSettings):
|
|
13
36
|
model_config = SettingsConfigDict(
|
|
@@ -381,8 +404,11 @@ class Settings(BaseSettings):
|
|
|
381
404
|
# Voyage AI embeddings
|
|
382
405
|
voyage_api_key: str = ""
|
|
383
406
|
|
|
384
|
-
# sqlite-vec
|
|
385
|
-
vec0_path: str =
|
|
407
|
+
# sqlite-vec: env VEC0_PATH → sqlite_vec.loadable_path() → prod fallback.
|
|
408
|
+
vec0_path: str = Field(
|
|
409
|
+
default_factory=_default_vec0_path,
|
|
410
|
+
validation_alias=AliasChoices("VEC0_PATH"),
|
|
411
|
+
)
|
|
386
412
|
|
|
387
413
|
# LifeOS
|
|
388
414
|
lifeos_data_dir: str = ""
|
|
@@ -101,6 +101,7 @@ _write_lock = asyncio.Lock()
|
|
|
101
101
|
|
|
102
102
|
WRITER_LOCK_EVENT_LIMIT = 500
|
|
103
103
|
WRITER_LOCK_SLOW_WAIT_MS = 50.0
|
|
104
|
+
WRITER_LOCK_SLOW_HOLD_MS = 1000.0 # Fase 0: log writer holds >1s to separate offenders from queued victims
|
|
104
105
|
_writer_metrics_lock = Lock()
|
|
105
106
|
_writer_wait_events: deque[dict[str, Any]] = deque(maxlen=WRITER_LOCK_EVENT_LIMIT)
|
|
106
107
|
_writer_hold_events: deque[dict[str, Any]] = deque(maxlen=WRITER_LOCK_EVENT_LIMIT)
|
|
@@ -291,7 +292,14 @@ def _start_writer_hold(
|
|
|
291
292
|
"blocked_by": blocked_by,
|
|
292
293
|
}
|
|
293
294
|
)
|
|
294
|
-
|
|
295
|
+
if wait_ms >= WRITER_LOCK_SLOW_WAIT_MS:
|
|
296
|
+
logger.warning(
|
|
297
|
+
"SQLite writer lock WAIT %.0fms for %s (blocked_by=%s)",
|
|
298
|
+
wait_ms,
|
|
299
|
+
label,
|
|
300
|
+
(blocked_by or {}).get("label"),
|
|
301
|
+
)
|
|
302
|
+
return holder
|
|
295
303
|
|
|
296
304
|
|
|
297
305
|
def _finish_writer_hold(holder: dict[str, Any]) -> None:
|
|
@@ -312,6 +320,13 @@ def _finish_writer_hold(holder: dict[str, Any]) -> None:
|
|
|
312
320
|
"blocked_by": holder.get("blocked_by"),
|
|
313
321
|
}
|
|
314
322
|
)
|
|
323
|
+
if hold_ms >= WRITER_LOCK_SLOW_HOLD_MS:
|
|
324
|
+
logger.warning(
|
|
325
|
+
"SQLite writer lock HELD %.0fms by %s (waited %.0fms) — offender, not victim",
|
|
326
|
+
hold_ms,
|
|
327
|
+
holder["label"],
|
|
328
|
+
holder.get("wait_ms", 0.0),
|
|
329
|
+
)
|
|
315
330
|
|
|
316
331
|
|
|
317
332
|
def get_writer_lock_snapshot(window_seconds: float = 60.0) -> dict[str, Any]:
|
|
@@ -494,18 +509,69 @@ async def wal_checkpoint() -> tuple[int, int, int]:
|
|
|
494
509
|
# sqlite-vec support
|
|
495
510
|
_vec_table_ready = False
|
|
496
511
|
|
|
512
|
+
# Platform-specific loadable-extension suffixes. The vec0 loadable is `.so` on
|
|
513
|
+
# Linux (prod), `.dylib` on macOS, `.dll` on Windows.
|
|
514
|
+
_VEC0_SUFFIXES = (".so", ".dylib", ".dll")
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
def resolve_vec0_loadable() -> tuple[str | None, bool]:
|
|
518
|
+
"""Resolve the vec0 loadable path, cross-platform.
|
|
519
|
+
|
|
520
|
+
Returns ``(load_arg, found)`` where ``load_arg`` is the argument to pass to
|
|
521
|
+
``SELECT load_extension(?)`` and ``found`` is True when a real loadable file
|
|
522
|
+
exists on disk.
|
|
523
|
+
|
|
524
|
+
Resolution (prod-safe by construction):
|
|
525
|
+
1. ``settings.vec0_path`` when it resolves to a real file: if it already
|
|
526
|
+
carries a known suffix use it as-is, otherwise probe ``.so`` /
|
|
527
|
+
``.dylib`` / ``.dll``. Prod (Linux, ``/data/pir/lib/vec0`` →
|
|
528
|
+
``vec0.so``, set via ``VEC0_PATH``) resolves here and keeps using the
|
|
529
|
+
exact configured path.
|
|
530
|
+
2. Else the installed ``sqlite_vec`` package's own loadable
|
|
531
|
+
(``sqlite_vec.loadable_path()``) — the OSS clean-install path, where
|
|
532
|
+
``/data/pir/lib/vec0`` is absent and the bundled loadable is
|
|
533
|
+
platform-correct (.dylib on macOS, no longer rejected by a hardcoded
|
|
534
|
+
``.so`` check).
|
|
535
|
+
|
|
536
|
+
The suffix-less ``load_arg`` lets SQLite append the platform suffix itself.
|
|
537
|
+
"""
|
|
538
|
+
vec_path = Path(settings.vec0_path)
|
|
539
|
+
if vec_path.suffix:
|
|
540
|
+
if vec_path.exists():
|
|
541
|
+
return (str(vec_path), True)
|
|
542
|
+
else:
|
|
543
|
+
for suffix in _VEC0_SUFFIXES:
|
|
544
|
+
if vec_path.with_suffix(suffix).exists():
|
|
545
|
+
# Pass the suffix-less path; SQLite appends the platform suffix.
|
|
546
|
+
return (str(vec_path), True)
|
|
547
|
+
|
|
548
|
+
try:
|
|
549
|
+
import sqlite_vec # type: ignore
|
|
550
|
+
|
|
551
|
+
pkg_path = Path(str(sqlite_vec.loadable_path()))
|
|
552
|
+
if pkg_path.exists():
|
|
553
|
+
return (str(pkg_path), True)
|
|
554
|
+
# loadable_path() returns a suffix-less base on some builds; probe.
|
|
555
|
+
for suffix in _VEC0_SUFFIXES:
|
|
556
|
+
if pkg_path.with_suffix(suffix).exists():
|
|
557
|
+
return (str(pkg_path), True)
|
|
558
|
+
except Exception: # noqa: BLE001 — package missing/old → settings path is final
|
|
559
|
+
pass
|
|
560
|
+
|
|
561
|
+
# Nothing resolved; return the configured path so callers log a clear miss.
|
|
562
|
+
return (str(vec_path), False)
|
|
563
|
+
|
|
497
564
|
|
|
498
565
|
async def ensure_vec_documents(db: aiosqlite.Connection) -> bool:
|
|
499
566
|
"""Load sqlite-vec on an existing connection and ensure vec_documents exists."""
|
|
500
567
|
global _vec_table_ready
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
if not vec_so.exists():
|
|
568
|
+
load_arg, found = resolve_vec0_loadable()
|
|
569
|
+
if not found or load_arg is None:
|
|
504
570
|
return False
|
|
505
571
|
|
|
506
572
|
if not getattr(db, "_pir_vec_extension_loaded", False):
|
|
507
573
|
await db._execute(db._conn.enable_load_extension, True)
|
|
508
|
-
await db.execute("SELECT load_extension(?)", [
|
|
574
|
+
await db.execute("SELECT load_extension(?)", [load_arg])
|
|
509
575
|
setattr(db, "_pir_vec_extension_loaded", True)
|
|
510
576
|
if not _vec_table_ready:
|
|
511
577
|
await db.execute("""
|
|
@@ -870,11 +870,17 @@ async def _notifications_acted_at_sync_loop() -> None:
|
|
|
870
870
|
async with write_db() as db:
|
|
871
871
|
now = datetime.now(timezone.utc).isoformat()
|
|
872
872
|
await db.execute(
|
|
873
|
+
# Drive off the small still-pending set + idx_notifications_pending_sync
|
|
874
|
+
# (migration 144): NOT IN (pending) is sargable, the prior
|
|
875
|
+
# `!= 'pending'` forced a full scan -> ~15s writer-lock hold.
|
|
876
|
+
# A target_id pointing at a deleted task is now acted too (benign:
|
|
877
|
+
# the task is no longer pending). tasks.id is PK so no NULL in the
|
|
878
|
+
# subquery -> NOT IN is safe.
|
|
873
879
|
"""UPDATE notifications
|
|
874
880
|
SET acted_at = ?, read_at = COALESCE(read_at, ?)
|
|
875
881
|
WHERE acted_at IS NULL AND type = 'task_pending'
|
|
876
|
-
AND target_type = 'task' AND target_id IN (
|
|
877
|
-
SELECT id FROM tasks WHERE status
|
|
882
|
+
AND target_type = 'task' AND target_id NOT IN (
|
|
883
|
+
SELECT id FROM tasks WHERE status = 'pending'
|
|
878
884
|
)""",
|
|
879
885
|
(now, now),
|
|
880
886
|
)
|
|
@@ -1299,7 +1299,12 @@ async def emit_finding_dedup(
|
|
|
1299
1299
|
return (finding_id, False)
|
|
1300
1300
|
|
|
1301
1301
|
# INSERT path
|
|
1302
|
-
finding_id
|
|
1302
|
+
# Finding.finding_id requires exactly 32 chars (min_length=32,
|
|
1303
|
+
# max_length=32), matching the BLAKE2b-16 hex sibling ids
|
|
1304
|
+
# (signal_id/operation_id/event_id). Keep the "fnd_" prefix and pad to
|
|
1305
|
+
# 32 total chars (4 prefix + 28 hex) so every findings endpoint
|
|
1306
|
+
# validates instead of 500-ing.
|
|
1307
|
+
finding_id = f"fnd_{uuid.uuid4().hex[:28]}"
|
|
1303
1308
|
now_iso = _utc_iso(datetime.now(timezone.utc))
|
|
1304
1309
|
if expires_at is None:
|
|
1305
1310
|
expires_iso = _utc_iso(
|
|
@@ -482,9 +482,15 @@ async def embed_task_document(
|
|
|
482
482
|
|
|
483
483
|
|
|
484
484
|
async def _ensure_vec_documents(db: aiosqlite.Connection, vec0_path: str) -> None:
|
|
485
|
-
|
|
485
|
+
# Prefer the shared cross-platform resolver (sqlite_vec package loader /
|
|
486
|
+
# .so / .dylib probe) so macOS (.dylib) loads; fall back to the passed path.
|
|
487
|
+
from core.api.db import resolve_vec0_loadable
|
|
488
|
+
|
|
489
|
+
load_arg, found = resolve_vec0_loadable()
|
|
490
|
+
if not found or load_arg is None:
|
|
491
|
+
load_arg = str(Path(vec0_path))
|
|
486
492
|
await db._execute(db._conn.enable_load_extension, True)
|
|
487
|
-
await db.execute("SELECT load_extension(?)", [
|
|
493
|
+
await db.execute("SELECT load_extension(?)", [load_arg])
|
|
488
494
|
await db.execute("""
|
|
489
495
|
CREATE VIRTUAL TABLE IF NOT EXISTS vec_documents USING vec0(
|
|
490
496
|
doc_id INTEGER PRIMARY KEY,
|
|
@@ -20,8 +20,57 @@ from core.api.services.ingest.events import broadcast_ingest_changed
|
|
|
20
20
|
|
|
21
21
|
logger = logging.getLogger(__name__)
|
|
22
22
|
|
|
23
|
+
# Prod default (Docker): /data/projects exists, so the resolved value stays
|
|
24
|
+
# /data/projects there. Kept as a module-level attribute (not inlined) so it
|
|
25
|
+
# remains an explicit override point — tests monkeypatch it, and a future
|
|
26
|
+
# runtime hook could set it directly. _projects_root() treats any non-default
|
|
27
|
+
# value here as authoritative.
|
|
23
28
|
PROJECTS_ROOT = Path("/data/projects")
|
|
24
29
|
REPO_ROOT = repo_root(__file__)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _projects_root() -> Path:
|
|
33
|
+
"""Resolve the projects root the same way the rest of the runtime does.
|
|
34
|
+
|
|
35
|
+
Order (prod-safe by construction):
|
|
36
|
+
1. The module-level ``PROJECTS_ROOT`` when it has been overridden from its
|
|
37
|
+
``/data/projects`` default (tests monkeypatch it; a runtime hook may
|
|
38
|
+
set it). An explicit override always wins.
|
|
39
|
+
2. ``$MARVIS_PROJECTS_ROOT`` (canonical override, see wizard/defaults.py).
|
|
40
|
+
Prod does NOT set it, so prod is unaffected.
|
|
41
|
+
3. The runtime-applied project dirs (``PROJECT_DIRS[0]``), which
|
|
42
|
+
``runtime_settings.apply_marvis_settings`` populates from
|
|
43
|
+
``~/.marvis/settings.yaml`` ``storage.projects_root`` — but ONLY when
|
|
44
|
+
``/data/projects`` does NOT exist, so prod (where it does) keeps using
|
|
45
|
+
``/data/projects`` rather than the DB-loaded ``~/workspace/projects``.
|
|
46
|
+
4. ``/data/projects`` default.
|
|
47
|
+
|
|
48
|
+
Resolved lazily per-call: the API process applies settings.yaml AFTER this
|
|
49
|
+
module imports, so reading at import time would lock in the bare default.
|
|
50
|
+
"""
|
|
51
|
+
default_root = Path("/data/projects")
|
|
52
|
+
|
|
53
|
+
# 1. Explicit module-level override (tests / runtime hook).
|
|
54
|
+
if PROJECTS_ROOT != default_root:
|
|
55
|
+
return Path(PROJECTS_ROOT).expanduser().resolve()
|
|
56
|
+
|
|
57
|
+
# 2. Canonical env override (OSS non-Docker).
|
|
58
|
+
env_root = os.environ.get("MARVIS_PROJECTS_ROOT")
|
|
59
|
+
if env_root:
|
|
60
|
+
return Path(env_root).expanduser().resolve()
|
|
61
|
+
|
|
62
|
+
# 3. Runtime settings (settings.yaml → PROJECT_DIRS) on non-Docker installs.
|
|
63
|
+
if not default_root.exists():
|
|
64
|
+
try:
|
|
65
|
+
from core.api.routers.projects import PROJECT_DIRS
|
|
66
|
+
|
|
67
|
+
if PROJECT_DIRS:
|
|
68
|
+
return Path(PROJECT_DIRS[0]).expanduser().resolve()
|
|
69
|
+
except Exception: # noqa: BLE001 — never let resolution crash the saga
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
# 4. Prod Docker default.
|
|
73
|
+
return default_root.resolve()
|
|
25
74
|
SUBPROCESS_TIMEOUT_SEC = 60
|
|
26
75
|
|
|
27
76
|
# Phase 1.5 E6: keep-ref so fire-and-forget background tasks don't get GC'd
|
|
@@ -53,7 +102,7 @@ ProjectType = Literal["work", "code", "system"]
|
|
|
53
102
|
|
|
54
103
|
|
|
55
104
|
def _project_root(slug: str) -> Path:
|
|
56
|
-
return (
|
|
105
|
+
return (_projects_root() / slug).resolve()
|
|
57
106
|
|
|
58
107
|
|
|
59
108
|
def _load_project_entry(slug: str) -> tuple[ProjectType, Path | None]:
|
|
@@ -418,12 +467,13 @@ async def _ensure_kg_edge(
|
|
|
418
467
|
},
|
|
419
468
|
ensure_ascii=False,
|
|
420
469
|
)
|
|
470
|
+
projects_root = _projects_root()
|
|
421
471
|
candidate_paths = [
|
|
422
472
|
str(target_path),
|
|
423
|
-
str(target_path.relative_to(
|
|
473
|
+
str(target_path.relative_to(projects_root)),
|
|
424
474
|
]
|
|
425
475
|
if project_slug == "marvisx":
|
|
426
|
-
candidate_paths.append(f"projects/{target_path.relative_to(
|
|
476
|
+
candidate_paths.append(f"projects/{target_path.relative_to(projects_root)}")
|
|
427
477
|
|
|
428
478
|
async with acquire_write_db() as db:
|
|
429
479
|
await db.execute(
|
|
@@ -32,6 +32,22 @@ INTERNET_PROBE_TARGETS = (
|
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
|
|
35
|
+
_PROBE_DISABLED_VALUES = {"0", "off", "false", "no"}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def network_probe_enabled() -> bool:
|
|
39
|
+
"""Whether the periodic internet probe (cloudflare.com/cdn-cgi/trace) runs.
|
|
40
|
+
|
|
41
|
+
Gated by ``$MARVIS_NETWORK_PROBE``: values in {0, off, false, no}
|
|
42
|
+
(case-insensitive) disable the probe — this is what makes an "offline mode"
|
|
43
|
+
honest. Default (env unset / any other value) = ON, so prod is unchanged.
|
|
44
|
+
"""
|
|
45
|
+
raw = os.environ.get("MARVIS_NETWORK_PROBE")
|
|
46
|
+
if raw is None:
|
|
47
|
+
return True
|
|
48
|
+
return raw.strip().lower() not in _PROBE_DISABLED_VALUES
|
|
49
|
+
|
|
50
|
+
|
|
35
51
|
def terminal_metrics_path(
|
|
36
52
|
*,
|
|
37
53
|
now: datetime | None = None,
|
|
@@ -175,17 +191,20 @@ async def terminal_metrics_background_loop(
|
|
|
175
191
|
collector.record_event_loop_lag(max(0.0, (now - expected_wake) * 1000))
|
|
176
192
|
|
|
177
193
|
if now >= next_probe_at:
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
194
|
+
if network_probe_enabled():
|
|
195
|
+
try:
|
|
196
|
+
probe = await sample_internet_probe(collector)
|
|
197
|
+
await append_terminal_metrics_record(
|
|
198
|
+
{
|
|
199
|
+
"kind": "internet_probe",
|
|
200
|
+
"probe": probe,
|
|
201
|
+
},
|
|
202
|
+
output_dir=output_dir,
|
|
203
|
+
)
|
|
204
|
+
except Exception:
|
|
205
|
+
logger.warning(
|
|
206
|
+
"terminal metrics internet probe failed", exc_info=True
|
|
207
|
+
)
|
|
189
208
|
next_probe_at = now + network_interval_seconds
|
|
190
209
|
|
|
191
210
|
if now >= next_dump_at:
|
|
@@ -225,20 +225,17 @@ async def trigger_reindex(
|
|
|
225
225
|
|
|
226
226
|
async def _reindex_type(doc_type: str, workspace_id: str) -> dict:
|
|
227
227
|
"""Reindex a single document type. Returns stats dict."""
|
|
228
|
-
from
|
|
229
|
-
|
|
230
|
-
from core.api.db import _configure_connection
|
|
228
|
+
from core.api.db import _configure_connection, resolve_vec0_loadable
|
|
231
229
|
|
|
232
230
|
db = await aiosqlite.connect(settings.db_path)
|
|
233
231
|
await _configure_connection(db)
|
|
234
232
|
db.row_factory = aiosqlite.Row
|
|
235
233
|
await db.execute("PRAGMA busy_timeout=60000")
|
|
236
234
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if vec_so.exists():
|
|
235
|
+
load_arg, vec_found = resolve_vec0_loadable()
|
|
236
|
+
if vec_found and load_arg is not None:
|
|
240
237
|
await db._execute(db._conn.enable_load_extension, True)
|
|
241
|
-
await db.execute("SELECT load_extension(?)", [
|
|
238
|
+
await db.execute("SELECT load_extension(?)", [load_arg])
|
|
242
239
|
await db.execute("""
|
|
243
240
|
CREATE VIRTUAL TABLE IF NOT EXISTS vec_documents USING vec0(
|
|
244
241
|
doc_id INTEGER PRIMARY KEY,
|
|
@@ -272,8 +269,7 @@ async def _reindex_all_bg(db_path: str) -> None:
|
|
|
272
269
|
Uses a SINGLE connection with vec extension loaded as both db and vec_db.
|
|
273
270
|
Two separate writers to the same DB cause 'database is locked' errors.
|
|
274
271
|
"""
|
|
275
|
-
from
|
|
276
|
-
from core.api.db import _configure_connection
|
|
272
|
+
from core.api.db import _configure_connection, resolve_vec0_loadable
|
|
277
273
|
|
|
278
274
|
logger.info("Reindex all: starting background job")
|
|
279
275
|
try:
|
|
@@ -282,12 +278,11 @@ async def _reindex_all_bg(db_path: str) -> None:
|
|
|
282
278
|
db.row_factory = aiosqlite.Row
|
|
283
279
|
# Higher busy_timeout for background reindex — avoids blocking regular requests
|
|
284
280
|
await db.execute("PRAGMA busy_timeout=60000")
|
|
285
|
-
# Load vec extension on the same connection
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
if vec_so.exists():
|
|
281
|
+
# Load vec extension on the same connection (cross-platform: .so/.dylib)
|
|
282
|
+
load_arg, vec_found = resolve_vec0_loadable()
|
|
283
|
+
if vec_found and load_arg is not None:
|
|
289
284
|
await db._execute(db._conn.enable_load_extension, True)
|
|
290
|
-
await db.execute("SELECT load_extension(?)", [
|
|
285
|
+
await db.execute("SELECT load_extension(?)", [load_arg])
|
|
291
286
|
await db.execute("""
|
|
292
287
|
CREATE VIRTUAL TABLE IF NOT EXISTS vec_documents USING vec0(
|
|
293
288
|
doc_id INTEGER PRIMARY KEY,
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# v1.0.0 - 2026-05-29 - open-core funnel: `marvis account status|link` (opt-in identity)
|
|
2
|
+
"""``marvis account status|link`` — the opt-in account / install-claim surface.
|
|
3
|
+
|
|
4
|
+
Registered onto the SAME Typer ``app`` as ``marvis init`` via ``register(app)``, like
|
|
5
|
+
``marvis_telemetry`` / ``marvis_hooks`` / ``marvis_mcp``.
|
|
6
|
+
|
|
7
|
+
- ``status`` is local-only (no network): shows whether an ``install_id`` and a cloud
|
|
8
|
+
api key exist (presence, not values), the configured endpoints, and the effective
|
|
9
|
+
telemetry state. Safe to paste into a bug report.
|
|
10
|
+
- ``link`` is the explicit opt-in: it provisions the install with the cloud backend
|
|
11
|
+
(mints + stores an api key once) and prints the **claim code** + the dashboard URL.
|
|
12
|
+
The user signs in at the dashboard and pastes the code to attach this install to
|
|
13
|
+
their account (the web side calls ``/v1/installs/claim``). Telemetry being off does
|
|
14
|
+
NOT block ``link`` — it is a deliberate user action, distinct from passive telemetry.
|
|
15
|
+
|
|
16
|
+
Heavy work is avoided: ``status`` only reads ``~/.marvis``; ``link`` does one short,
|
|
17
|
+
fail-silent provisioning POST (≤2s) reusing the sender's contract.
|
|
18
|
+
"""
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
import typer
|
|
24
|
+
|
|
25
|
+
from core.cli._runtime_ctx import console, emit as _emit_result
|
|
26
|
+
|
|
27
|
+
ACCOUNT_URL = "https://justaskmarvis.com/account"
|
|
28
|
+
_PANEL_ACCOUNT = "Account"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def register(app: typer.Typer) -> None:
|
|
32
|
+
"""Attach the ``account`` command group onto an existing app."""
|
|
33
|
+
app.add_typer(
|
|
34
|
+
account_app,
|
|
35
|
+
name="account",
|
|
36
|
+
rich_help_panel=_PANEL_ACCOUNT,
|
|
37
|
+
help="Link this install to a justaskmarvis.com account (opt-in) / inspect it.",
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
account_app = typer.Typer(add_completion=False, no_args_is_help=True)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _claim_code() -> str | None:
|
|
45
|
+
from core.telemetry import client as _tc
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
path = _tc._marvis_dir() / "telemetry_claim_code"
|
|
49
|
+
if path.is_file():
|
|
50
|
+
value = path.read_text(encoding="utf-8").strip()
|
|
51
|
+
return value or None
|
|
52
|
+
except Exception: # noqa: BLE001
|
|
53
|
+
return None
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _status_result() -> dict[str, Any]:
|
|
58
|
+
"""Local-only account snapshot (no network)."""
|
|
59
|
+
from core.telemetry import client as _tc
|
|
60
|
+
from core.telemetry import sender as _sender
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
"telemetry_enabled": _tc._enabled(),
|
|
64
|
+
"install_id_present": (_tc._marvis_dir() / "telemetry_id").is_file(),
|
|
65
|
+
"account_provisioned": _sender._load_key() is not None,
|
|
66
|
+
"claim_code_present": _claim_code() is not None,
|
|
67
|
+
"ingest_endpoint": _sender._endpoint("ingest_endpoint", _sender.DEFAULT_INGEST_ENDPOINT),
|
|
68
|
+
"provision_endpoint": _sender._endpoint("provision_endpoint", _sender.DEFAULT_PROVISION_ENDPOINT),
|
|
69
|
+
"account_url": ACCOUNT_URL,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _link_result() -> dict[str, Any]:
|
|
74
|
+
"""Provision the install (mint+store a key once) and return the claim code. One short POST."""
|
|
75
|
+
from core.telemetry import client as _tc
|
|
76
|
+
from core.telemetry import sender as _sender
|
|
77
|
+
|
|
78
|
+
key = _sender._ensure_key(_tc._install_id())
|
|
79
|
+
return {
|
|
80
|
+
"provisioned": key is not None,
|
|
81
|
+
"claim_code": _claim_code() if key is not None else None,
|
|
82
|
+
"account_url": ACCOUNT_URL,
|
|
83
|
+
"provision_endpoint": _sender._endpoint("provision_endpoint", _sender.DEFAULT_PROVISION_ENDPOINT),
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@account_app.command("status")
|
|
88
|
+
def status_cmd(
|
|
89
|
+
json_out: bool = typer.Option(False, "--json", help="Emit pure JSON to stdout."),
|
|
90
|
+
) -> None:
|
|
91
|
+
"""Show the local account state (presence only, no values; no network)."""
|
|
92
|
+
result = _status_result()
|
|
93
|
+
|
|
94
|
+
def _render(r: dict[str, Any]) -> None:
|
|
95
|
+
from rich.table import Table
|
|
96
|
+
|
|
97
|
+
t = Table(title="marvis account status", show_header=False)
|
|
98
|
+
t.add_row("Telemetry", "[green]on[/]" if r["telemetry_enabled"] else "[yellow]off[/]")
|
|
99
|
+
t.add_row("install_id", "[green]present[/]" if r["install_id_present"] else "[dim]not yet created[/]")
|
|
100
|
+
t.add_row("Account", "[green]provisioned[/]" if r["account_provisioned"] else "[dim]not linked[/]")
|
|
101
|
+
t.add_row("Claim code", "[green]present[/]" if r["claim_code_present"] else "[dim]none[/]")
|
|
102
|
+
t.add_row("Ingest", r["ingest_endpoint"])
|
|
103
|
+
console.print(t)
|
|
104
|
+
if not r["account_provisioned"]:
|
|
105
|
+
console.print(f"[dim]Run [bold]marvis account link[/] to link this install at {r['account_url']}.[/]")
|
|
106
|
+
|
|
107
|
+
_emit_result(result, json_out=json_out, render=_render)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@account_app.command("link")
|
|
111
|
+
def link_cmd(
|
|
112
|
+
json_out: bool = typer.Option(False, "--json", help="Emit pure JSON to stdout."),
|
|
113
|
+
) -> None:
|
|
114
|
+
"""Provision this install and print the claim code to link it to your account."""
|
|
115
|
+
result = _link_result()
|
|
116
|
+
|
|
117
|
+
def _render(r: dict[str, Any]) -> None:
|
|
118
|
+
if not r["provisioned"]:
|
|
119
|
+
console.print(
|
|
120
|
+
f"[yellow]Could not reach {r['provision_endpoint']}.[/] "
|
|
121
|
+
"Check your connection and retry — nothing was changed."
|
|
122
|
+
)
|
|
123
|
+
return
|
|
124
|
+
code = r["claim_code"]
|
|
125
|
+
console.print("[green]Install provisioned.[/] To link it to your account:")
|
|
126
|
+
console.print(f" 1. Sign in at [bold]{r['account_url']}[/]")
|
|
127
|
+
if code:
|
|
128
|
+
console.print(f" 2. Paste this claim code: [bold]{code}[/]")
|
|
129
|
+
else:
|
|
130
|
+
console.print(" 2. Use 'claim install' in the dashboard (claim code issued at first provision).")
|
|
131
|
+
|
|
132
|
+
_emit_result(result, json_out=json_out, render=_render)
|
|
@@ -60,7 +60,18 @@ from core.wizard.defaults import (
|
|
|
60
60
|
)
|
|
61
61
|
|
|
62
62
|
DEFAULT_SETTINGS_FILENAME = "settings.yaml"
|
|
63
|
-
CLI_VERSION = "marvis-init 0.
|
|
63
|
+
CLI_VERSION = "marvis-init 0.2.0"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _default_vault_dir() -> Path:
|
|
67
|
+
"""Resolve the vault dir honoring ``$MARVIS_VAULT_DIR`` → ``~/.marvis``.
|
|
68
|
+
|
|
69
|
+
Mirrors ``core.telemetry.client._marvis_dir()`` so that, when ``--vault-dir``
|
|
70
|
+
is not passed, ``marvis init`` writes to the env-configured vault instead of
|
|
71
|
+
silently polluting the real ``~/.marvis``.
|
|
72
|
+
"""
|
|
73
|
+
env_dir = os.environ.get("MARVIS_VAULT_DIR")
|
|
74
|
+
return Path(env_dir).expanduser() if env_dir else DEFAULT_VAULT_DIR
|
|
64
75
|
BSL_NOTICE = (
|
|
65
76
|
"MarvisX is distributed under the Business Source License 1.1. "
|
|
66
77
|
"Personal, internal and non-commercial use is free; commercial hosting "
|
|
@@ -504,6 +515,12 @@ def _telemetry_root_hook(invoked_subcommand: str | None) -> None:
|
|
|
504
515
|
|
|
505
516
|
_telemetry.maybe_first_run_notice()
|
|
506
517
|
_telemetry.emit("cli_command", {"command": invoked_subcommand or "init"})
|
|
518
|
+
|
|
519
|
+
# Opportunistic daily aggregate rollup (provision + send), throttled 24h,
|
|
520
|
+
# detached + fail-silent — same opt-out gate as emit(). Never blocks the command.
|
|
521
|
+
from core.telemetry import sender as _sender
|
|
522
|
+
|
|
523
|
+
_sender.maybe_send_rollup()
|
|
507
524
|
except Exception: # noqa: BLE001 — telemetry must never affect the command
|
|
508
525
|
pass
|
|
509
526
|
|
|
@@ -570,10 +587,10 @@ def init(
|
|
|
570
587
|
"--dry-run",
|
|
571
588
|
help="Mostra il piano senza scrivere file ne' vault.",
|
|
572
589
|
),
|
|
573
|
-
vault_dir: Path = typer.Option(
|
|
574
|
-
|
|
590
|
+
vault_dir: Path | None = typer.Option(
|
|
591
|
+
None,
|
|
575
592
|
"--vault-dir",
|
|
576
|
-
help="Cartella vault BYOK + settings.yaml (default ~/.marvis).",
|
|
593
|
+
help="Cartella vault BYOK + settings.yaml (default $MARVIS_VAULT_DIR o ~/.marvis).",
|
|
577
594
|
),
|
|
578
595
|
settings_path: Path | None = typer.Option(
|
|
579
596
|
None,
|
|
@@ -588,6 +605,10 @@ def init(
|
|
|
588
605
|
),
|
|
589
606
|
) -> None:
|
|
590
607
|
"""5-step interactive bootstrap riusando core.wizard shared lib."""
|
|
608
|
+
# When --vault-dir is omitted, honor $MARVIS_VAULT_DIR (else ~/.marvis) so
|
|
609
|
+
# init never silently writes to the real home vault under isolation.
|
|
610
|
+
if vault_dir is None:
|
|
611
|
+
vault_dir = _default_vault_dir()
|
|
591
612
|
interactive = _is_interactive() and not no_interactive
|
|
592
613
|
|
|
593
614
|
if config is not None:
|
|
@@ -733,6 +754,11 @@ from core.cli.marvis_telemetry import register as _register_telemetry # noqa: E
|
|
|
733
754
|
|
|
734
755
|
_register_telemetry(app)
|
|
735
756
|
|
|
757
|
+
# `marvis account status/link` — opt-in identity: link this install to a web account.
|
|
758
|
+
from core.cli.marvis_account import register as _register_account # noqa: E402
|
|
759
|
+
|
|
760
|
+
_register_account(app)
|
|
761
|
+
|
|
736
762
|
# `marvis doctor` — install-health self-diagnostic with actionable remediation.
|
|
737
763
|
from core.cli.marvis_doctor import register as _register_doctor # noqa: E402
|
|
738
764
|
|
|
@@ -151,9 +151,18 @@ def status_cmd(
|
|
|
151
151
|
settings_data = _settings_snapshot()
|
|
152
152
|
llm = settings_data.get("llm") or {}
|
|
153
153
|
byok = bool(_vault_state() or llm.get("provider"))
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
154
|
+
# Real EFFECTIVE state: reuse the same precedence `marvis telemetry status`
|
|
155
|
+
# uses (DO_NOT_TRACK / MARVIS_TELEMETRY env, then settings.yaml, default ON).
|
|
156
|
+
# The old inline check read only settings.yaml with a wrong default (off),
|
|
157
|
+
# so status showed "off" even when telemetry was actually ON.
|
|
158
|
+
try:
|
|
159
|
+
from core.telemetry.client import _enabled as _telemetry_enabled
|
|
160
|
+
|
|
161
|
+
telemetry = bool(_telemetry_enabled())
|
|
162
|
+
except Exception: # noqa: BLE001 — status must never crash
|
|
163
|
+
telemetry = bool(settings_data.get("telemetry", {}).get("enabled", True)) if isinstance(
|
|
164
|
+
settings_data.get("telemetry"), dict
|
|
165
|
+
) else bool(settings_data.get("telemetry", True))
|
|
157
166
|
|
|
158
167
|
result = {
|
|
159
168
|
"db_ok": db_ok,
|