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.
Files changed (599) hide show
  1. {marvisx_cli-0.1.0/marvisx_cli.egg-info → marvisx_cli-0.2.0}/PKG-INFO +2 -1
  2. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/config.py +28 -2
  3. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/db.py +71 -5
  4. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/main.py +8 -2
  5. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/findings.py +6 -1
  6. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/embedding_service.py +8 -2
  7. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/insert_saga.py +53 -3
  8. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/terminal_metrics_dump.py +30 -11
  9. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/search.py +9 -14
  10. marvisx_cli-0.2.0/core/cli/marvis_account.py +132 -0
  11. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_init.py +30 -4
  12. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_runtime.py +12 -3
  13. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/telemetry/client.py +1 -1
  14. marvisx_cli-0.2.0/core/telemetry/entitlements.py +26 -0
  15. marvisx_cli-0.2.0/core/telemetry/rollup.py +281 -0
  16. marvisx_cli-0.2.0/core/telemetry/sender.py +224 -0
  17. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0/marvisx_cli.egg-info}/PKG-INFO +2 -1
  18. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/marvisx_cli.egg-info/SOURCES.txt +5 -0
  19. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/marvisx_cli.egg-info/requires.txt +1 -0
  20. marvisx_cli-0.2.0/migrations/144_notifications_pending_sync_index.sql +14 -0
  21. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/pyproject.toml +8 -1
  22. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/LICENSE +0 -0
  23. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/MANIFEST.in +0 -0
  24. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/README.md +0 -0
  25. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/__init__.py +0 -0
  26. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/agents/__init__.py +0 -0
  27. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/agents/session_health.py +0 -0
  28. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/agents/session_manager.py +0 -0
  29. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/bin/marvisx-state-hook.py +0 -0
  30. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/dependencies/__init__.py +0 -0
  31. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/dependencies/tenant.py +0 -0
  32. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/__init__.py +0 -0
  33. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/_adapter.py +0 -0
  34. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/server.py +0 -0
  35. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/__init__.py +0 -0
  36. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/brain.py +0 -0
  37. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/graph.py +0 -0
  38. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/handoffs.py +0 -0
  39. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/ingest.py +0 -0
  40. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/learnings.py +0 -0
  41. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/projects.py +0 -0
  42. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/pull_requests.py +0 -0
  43. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/safety.py +0 -0
  44. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/search.py +0 -0
  45. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/mcp/tools/tasks.py +0 -0
  46. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/middleware/__init__.py +0 -0
  47. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/middleware/tool_call_audit.py +0 -0
  48. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/__init__.py +0 -0
  49. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/auth.py +0 -0
  50. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/brain.py +0 -0
  51. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/common.py +0 -0
  52. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/costs.py +0 -0
  53. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/graph.py +0 -0
  54. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/graph_cosmo.py +0 -0
  55. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/graph_pr_impact.py +0 -0
  56. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/graph_ux.py +0 -0
  57. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/inbox.py +0 -0
  58. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/ingest_keys.py +0 -0
  59. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/kg.py +0 -0
  60. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/llm_config.py +0 -0
  61. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/monitoring.py +0 -0
  62. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/projects.py +0 -0
  63. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/search.py +0 -0
  64. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/sessions.py +0 -0
  65. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/tasks.py +0 -0
  66. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/teams.py +0 -0
  67. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/models/users.py +0 -0
  68. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/observability/__init__.py +0 -0
  69. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/observability/tracing.py +0 -0
  70. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/paths.py +0 -0
  71. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/rate_limit.py +0 -0
  72. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/rbac.py +0 -0
  73. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/__init__.py +0 -0
  74. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/_adapter.py +0 -0
  75. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/admin_pr_impact.py +0 -0
  76. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/admin_settings.py +0 -0
  77. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/agent.py +0 -0
  78. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/agent_tokens.py +0 -0
  79. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/app_settings.py +0 -0
  80. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/audit.py +0 -0
  81. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/auth.py +0 -0
  82. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/bench.py +0 -0
  83. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/brain.py +0 -0
  84. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/brain_directions.py +0 -0
  85. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/ci_checks.py +0 -0
  86. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/comments.py +0 -0
  87. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/costs.py +0 -0
  88. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/docs_coverage.py +0 -0
  89. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/docs_governance.py +0 -0
  90. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/documents.py +0 -0
  91. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/files.py +0 -0
  92. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/finder.py +0 -0
  93. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/graph.py +0 -0
  94. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/handoffs.py +0 -0
  95. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/inbox.py +0 -0
  96. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/ingest_api_keys.py +0 -0
  97. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/ingest_triage.py +0 -0
  98. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/judge.py +0 -0
  99. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/kg.py +0 -0
  100. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/learnings.py +0 -0
  101. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/llm_config.py +0 -0
  102. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/monitoring.py +0 -0
  103. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/notifications.py +0 -0
  104. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/pr_impact.py +0 -0
  105. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/projects.py +0 -0
  106. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/pull_requests.py +0 -0
  107. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/push.py +0 -0
  108. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/raci.py +0 -0
  109. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/search.py +0 -0
  110. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/sessions.py +0 -0
  111. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/settings.py +0 -0
  112. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/share_repo.py +0 -0
  113. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/status_updates.py +0 -0
  114. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/tags.py +0 -0
  115. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/tasks.py +0 -0
  116. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/teams.py +0 -0
  117. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/terminal.py +0 -0
  118. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/users.py +0 -0
  119. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/routers/webhooks.py +0 -0
  120. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/runtime_settings.py +0 -0
  121. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/security.py +0 -0
  122. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/__init__.py +0 -0
  123. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/audit.py +0 -0
  124. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/auto_approval.py +0 -0
  125. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/__init__.py +0 -0
  126. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/baseline.py +0 -0
  127. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/capabilities.py +0 -0
  128. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/cascade_rollup.py +0 -0
  129. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/compound_bridge.py +0 -0
  130. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/cycle.py +0 -0
  131. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/cycle_snapshot.py +0 -0
  132. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/digest_collector.py +0 -0
  133. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/direction.py +0 -0
  134. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/drift.py +0 -0
  135. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/drift_router.py +0 -0
  136. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/edge_metrics.py +0 -0
  137. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/events_reader.py +0 -0
  138. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/findings_reader.py +0 -0
  139. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/jobs.py +0 -0
  140. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/journal.py +0 -0
  141. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/knowledge_forms.py +0 -0
  142. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/__init__.py +0 -0
  143. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/_runner.py +0 -0
  144. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/base.py +0 -0
  145. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/cache.py +0 -0
  146. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/constants.py +0 -0
  147. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/direction_alignment.py +0 -0
  148. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/factory.py +0 -0
  149. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/finding_reasoning.py +0 -0
  150. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/finding_summary.py +0 -0
  151. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/grounding.py +0 -0
  152. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/journal_polish.py +0 -0
  153. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/local_gateway.py +0 -0
  154. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/parsers.py +0 -0
  155. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/llm/router_glue.py +0 -0
  156. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/memory_ops.py +0 -0
  157. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/models.py +0 -0
  158. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/owner_hint.py +0 -0
  159. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/recap.py +0 -0
  160. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/__init__.py +0 -0
  161. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/_signals.py +0 -0
  162. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr1_activity_without_status.py +0 -0
  163. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr2_decision_without_adr.py +0 -0
  164. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr3_stale_open_loop.py +0 -0
  165. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr4_docs_governance_drift.py +0 -0
  166. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr5_playbook_changed.py +0 -0
  167. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr6_external_update_unpropagated.py +0 -0
  168. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr7_claimed_decision_gap.py +0 -0
  169. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/rules/dr8_direction_misalignment.py +0 -0
  170. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/runs_reader.py +0 -0
  171. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/scope.py +0 -0
  172. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/sources/__init__.py +0 -0
  173. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/sources/base.py +0 -0
  174. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/sources/git_kg.py +0 -0
  175. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/sources/handoffs.py +0 -0
  176. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/sources/ingestor.py +0 -0
  177. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/sources/learnings.py +0 -0
  178. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/sources/pir_tasks.py +0 -0
  179. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/watermarks.py +0 -0
  180. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/brain/ws_emitter.py +0 -0
  181. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/cc_tasks_reader.py +0 -0
  182. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ci_service.py +0 -0
  183. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/claude_metrics.py +0 -0
  184. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/codex_metrics.py +0 -0
  185. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/conversation_reader.py +0 -0
  186. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/cost_service.py +0 -0
  187. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/crypto.py +0 -0
  188. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/docs_governance/__init__.py +0 -0
  189. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/docs_governance/confidence.py +0 -0
  190. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/docs_governance/config.py +0 -0
  191. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/docs_governance/enrichment.py +0 -0
  192. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/docs_governance/frontmatter_validator.py +0 -0
  193. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/docs_governance/hard_gates.py +0 -0
  194. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/docs_governance/triage_orchestrator.py +0 -0
  195. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/embedding_internal.py +0 -0
  196. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/event_dispatcher.py +0 -0
  197. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/events.py +0 -0
  198. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/git_ops.py +0 -0
  199. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/graph_cosmo_service.py +0 -0
  200. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/graph_ranker.py +0 -0
  201. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/graph_service.py +0 -0
  202. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox.py +0 -0
  203. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_digest.py +0 -0
  204. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_digest_deep_research.py +0 -0
  205. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_digest_jobs.py +0 -0
  206. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_gmail_sync.py +0 -0
  207. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_llm_classifier.py +0 -0
  208. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_source_identity.py +0 -0
  209. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_sources.py +0 -0
  210. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_taxonomy.py +0 -0
  211. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_tldr.py +0 -0
  212. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/inbox_triage.py +0 -0
  213. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/__init__.py +0 -0
  214. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/api_key_auth.py +0 -0
  215. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/auto_approve.py +0 -0
  216. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/classifier.py +0 -0
  217. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/confidence.py +0 -0
  218. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/dispatch.py +0 -0
  219. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/embedding_router.py +0 -0
  220. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/events.py +0 -0
  221. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/ignore_patterns.py +0 -0
  222. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/image_probe.py +0 -0
  223. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/ingress.py +0 -0
  224. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/__init__.py +0 -0
  225. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/anthropic_haiku.py +0 -0
  226. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/base.py +0 -0
  227. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/byok_provider.py +0 -0
  228. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/classification_context.py +0 -0
  229. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/config_store.py +0 -0
  230. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/factory.py +0 -0
  231. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/kg_enricher.py +0 -0
  232. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/local_gateway.py +0 -0
  233. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/local_vllm.py +0 -0
  234. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/llm/openai_nano.py +0 -0
  235. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/lock_advisory.py +0 -0
  236. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parser_router.py +0 -0
  237. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/__init__.py +0 -0
  238. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/docling_parser.py +0 -0
  239. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/docparse_gateway.py +0 -0
  240. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/docx_parser.py +0 -0
  241. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/folder_unpacker.py +0 -0
  242. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/gateway_aux.py +0 -0
  243. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/image_parser.py +0 -0
  244. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/internal_markdown.py +0 -0
  245. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/ocr_gateway.py +0 -0
  246. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/ocr_pdf_parser.py +0 -0
  247. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/pdf_types.py +0 -0
  248. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/transcript_parser.py +0 -0
  249. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/vision_gateway.py +0 -0
  250. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/xlsx_parser.py +0 -0
  251. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/parsers/zip_unpacker.py +0 -0
  252. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/preflight.py +0 -0
  253. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/retry_voyage.py +0 -0
  254. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/routing_policy.py +0 -0
  255. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/serializers/__init__.py +0 -0
  256. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/serializers/xlsx_to_markdown.py +0 -0
  257. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/skip_log.py +0 -0
  258. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/ingest/watcher.py +0 -0
  259. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/__init__.py +0 -0
  260. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/audit.py +0 -0
  261. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/hybrid_search.py +0 -0
  262. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/lens.py +0 -0
  263. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/pr_impact.py +0 -0
  264. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/queries.py +0 -0
  265. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/ranking.py +0 -0
  266. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg/rrf.py +0 -0
  267. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/kg_watcher_control.py +0 -0
  268. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/local_llm/__init__.py +0 -0
  269. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/local_llm/async_client.py +0 -0
  270. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/local_llm/client.py +0 -0
  271. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/local_llm/url_validator.py +0 -0
  272. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/metrics_collector.py +0 -0
  273. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/metrics_providers.py +0 -0
  274. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/model_registry.py +0 -0
  275. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/model_router.py +0 -0
  276. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/n8n_client.py +0 -0
  277. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/newsletter_llm_gateway.py +0 -0
  278. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/notification_service.py +0 -0
  279. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/openai_responses.py +0 -0
  280. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/opencode_metrics.py +0 -0
  281. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/opencode_sessions.py +0 -0
  282. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pii_redactor.py +0 -0
  283. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_impact_pipeline/__init__.py +0 -0
  284. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_impact_pipeline/differ.py +0 -0
  285. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_impact_pipeline/dispatcher.py +0 -0
  286. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_impact_pipeline/gc.py +0 -0
  287. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_impact_pipeline/languages.py +0 -0
  288. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_impact_pipeline/parser.py +0 -0
  289. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_impact_pipeline/writer.py +0 -0
  290. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/pr_service.py +0 -0
  291. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/project_paths.py +0 -0
  292. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/project_status_updates.py +0 -0
  293. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/providers.py +0 -0
  294. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/push_service.py +0 -0
  295. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/reminder_service.py +0 -0
  296. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/runas.py +0 -0
  297. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/salience_service.py +0 -0
  298. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/security_collector.py +0 -0
  299. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/session_catalog.py +0 -0
  300. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/session_metrics_service.py +0 -0
  301. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/session_ops.py +0 -0
  302. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/session_state.py +0 -0
  303. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/share_links.py +0 -0
  304. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/task_transitions.py +0 -0
  305. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/terminal_metrics.py +0 -0
  306. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/tmux.py +0 -0
  307. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/webhook_service.py +0 -0
  308. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/services/workspace_sync.py +0 -0
  309. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/templates/__init__.py +0 -0
  310. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/templates/markdown_share.py +0 -0
  311. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/terminal.py +0 -0
  312. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/__init__.py +0 -0
  313. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_agent_facing_auth_dependencies.py +0 -0
  314. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_audit_permissions.py +0 -0
  315. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_backfill_session_conversations.py +0 -0
  316. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_backfill_working_seconds_msg.py +0 -0
  317. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_claude_metrics.py +0 -0
  318. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_codex_metrics.py +0 -0
  319. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_finder_paths.py +0 -0
  320. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_git_ops_merge.py +0 -0
  321. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_learnings_check_search.py +0 -0
  322. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_metrics_providers.py +0 -0
  323. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_migration_087.py +0 -0
  324. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_migration_088.py +0 -0
  325. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_migration_089.py +0 -0
  326. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_openai_responses.py +0 -0
  327. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_opencode_metrics.py +0 -0
  328. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_opencode_sessions.py +0 -0
  329. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_pr_workflow_e2e.py +0 -0
  330. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_projects_handoffs.py +0 -0
  331. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_providers.py +0 -0
  332. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_safety_bridge.py +0 -0
  333. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_session_catalog.py +0 -0
  334. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_session_conversations.py +0 -0
  335. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_session_metrics_service.py +0 -0
  336. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_session_resume_paths.py +0 -0
  337. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_session_theme_mode_migration.py +0 -0
  338. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_sessions_rbac.py +0 -0
  339. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_share_edit.py +0 -0
  340. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_share_repo.py +0 -0
  341. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_terminal_session_manager.py +0 -0
  342. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_terminal_upload.py +0 -0
  343. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_tmux.py +0 -0
  344. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_workspace_sync.py +0 -0
  345. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/tests/test_ws_ticket_in_memory.py +0 -0
  346. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/__init__.py +0 -0
  347. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/_context.py +0 -0
  348. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/_errors.py +0 -0
  349. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/_roles.py +0 -0
  350. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/audit.py +0 -0
  351. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/brain.py +0 -0
  352. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/costs.py +0 -0
  353. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/graph.py +0 -0
  354. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/handoffs.py +0 -0
  355. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/ingest_triage.py +0 -0
  356. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/learnings.py +0 -0
  357. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/projects.py +0 -0
  358. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/pull_requests.py +0 -0
  359. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/use_cases/tasks.py +0 -0
  360. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/api/visibility.py +0 -0
  361. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/README.md +0 -0
  362. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/__init__.py +0 -0
  363. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/_index_source.py +0 -0
  364. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/_runtime_ctx.py +0 -0
  365. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/_transmute.py +0 -0
  366. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_doctor.py +0 -0
  367. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_feedback.py +0 -0
  368. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_governance.py +0 -0
  369. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_hooks.py +0 -0
  370. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_mcp.py +0 -0
  371. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/cli/marvis_telemetry.py +0 -0
  372. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/_drift_check.py +0 -0
  373. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/_frontmatter.py +0 -0
  374. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/_graph_writer.py +0 -0
  375. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/ast_parser.py +0 -0
  376. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/__init__.py +0 -0
  377. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/_config.sh +0 -0
  378. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/block-dangerous-bash.sh +0 -0
  379. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/block-db-direct-write.sh +0 -0
  380. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/block-push-no-task.sh +0 -0
  381. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/block-staging-to-prod.sh +0 -0
  382. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/block-subtree-push.sh +0 -0
  383. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/config.json +0 -0
  384. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/enforce-no-merge-main.sh +0 -0
  385. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/enforce-worktree.sh +0 -0
  386. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/quality-gate.sh +0 -0
  387. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/safety_bridge.py +0 -0
  388. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/install_hooks/secret-scan.sh +0 -0
  389. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/migrate_spike_node_ids.py +0 -0
  390. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/populate_artifacts.py +0 -0
  391. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/populate_cross_project.py +0 -0
  392. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/populate_inbox_nodes.py +0 -0
  393. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/populate_pr_impact.py +0 -0
  394. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/populate_project_nodes.py +0 -0
  395. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/populate_touch_counter.py +0 -0
  396. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/reparse_failed.py +0 -0
  397. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/scripts/safety_bridge.py +0 -0
  398. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/telemetry/__init__.py +0 -0
  399. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/telemetry/schema.py +0 -0
  400. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/wizard/__init__.py +0 -0
  401. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/wizard/byok_vault.py +0 -0
  402. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/wizard/defaults.py +0 -0
  403. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/wizard/state.py +0 -0
  404. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/wizard/steps.py +0 -0
  405. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/core/wizard/validation.py +0 -0
  406. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/marvisx_cli.egg-info/dependency_links.txt +0 -0
  407. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/marvisx_cli.egg-info/entry_points.txt +0 -0
  408. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/marvisx_cli.egg-info/top_level.txt +0 -0
  409. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/001_initial.sql +0 -0
  410. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/002_tasks.sql +0 -0
  411. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/003_session_management.sql +0 -0
  412. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/004_projects_comments.sql +0 -0
  413. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/005_session_intelligence.sql +0 -0
  414. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/006_settings.sql +0 -0
  415. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/007_task_scoring.sql +0 -0
  416. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/008_cost_tracking.sql +0 -0
  417. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/009_session_card_metrics.sql +0 -0
  418. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/010_monitoring.sql +0 -0
  419. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/012_agent_api.sql +0 -0
  420. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/013_session_complete.sql +0 -0
  421. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/015_pull_requests.sql +0 -0
  422. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/015_pull_requests_down.sql +0 -0
  423. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/016_users_raci.sql +0 -0
  424. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/017_task_cost_entries.sql +0 -0
  425. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/018_agents.sql +0 -0
  426. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/018_agents_down.sql +0 -0
  427. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/019_review_feedback.sql +0 -0
  428. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/020_pr_commit_sha.sql +0 -0
  429. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/021_webhook_events.sql +0 -0
  430. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/022_devx_agent_managed.sql +0 -0
  431. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/022_devx_agent_managed_down.sql +0 -0
  432. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/023_devx_p1_gate.sql +0 -0
  433. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/023_devx_p1_gate_down.sql +0 -0
  434. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/024_chat_messages.sql +0 -0
  435. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/024_pr_conversation_id.sql +0 -0
  436. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/024_task_indexes.sql +0 -0
  437. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/024_task_indexes_down.sql +0 -0
  438. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/025_audit_log.sql +0 -0
  439. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/026_agent_tokens.sql +0 -0
  440. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/027_teams_auth_phase_b.sql +0 -0
  441. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/028_learnings.sql +0 -0
  442. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/029_team_roles.sql +0 -0
  443. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/030_finder_pins.sql +0 -0
  444. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/031_pr_deploy_status.sql +0 -0
  445. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/032_task_reminders.sql +0 -0
  446. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/033_events_retry_count.sql +0 -0
  447. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/033_session_owner.sql +0 -0
  448. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/034_notifications.sql +0 -0
  449. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/035_shared_links.sql +0 -0
  450. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/036_session_index_upgrade.sql +0 -0
  451. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/037_pr_approval.sql +0 -0
  452. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/038_pr_submitted_by.sql +0 -0
  453. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/039_push_subscriptions.sql +0 -0
  454. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/040_semantic_search.sql +0 -0
  455. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/041_workspaces.sql +0 -0
  456. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/042_oidc_providers.sql +0 -0
  457. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/043_ci_checks.sql +0 -0
  458. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/044_agent_metrics.sql +0 -0
  459. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/045_documents_doc_type.sql +0 -0
  460. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/046_salience.sql +0 -0
  461. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/047_seed_missing_agents.sql +0 -0
  462. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/048_fix_agent_paths_roles.sql +0 -0
  463. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/049_agent_role_and_learnings_schema.sql +0 -0
  464. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/050_session_provider.sql +0 -0
  465. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/051_session_launch_profile.sql +0 -0
  466. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/052_session_theme_mode.sql +0 -0
  467. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/052_task_kind.sql +0 -0
  468. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/053_inbox_items.sql +0 -0
  469. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/054_inbox_triage_contract.sql +0 -0
  470. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/055_inbox_topic_treatment.sql +0 -0
  471. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/056_inbox_treatment_read_save.sql +0 -0
  472. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/057_session_theme_mode_backfill.sql +0 -0
  473. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/058_inbox_item_status_lifecycle.sql +0 -0
  474. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/059_inbox_tldr_and_source_scores.sql +0 -0
  475. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/060_newsletter.sql +0 -0
  476. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/061_inbox_redesign.sql +0 -0
  477. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/062_fix_inbox_sources_backfill.sql +0 -0
  478. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/063_task_completion_mode.sql +0 -0
  479. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/064_judge_mode_setting.sql +0 -0
  480. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/065_knowledge_graph_spike.sql +0 -0
  481. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/066_digest_ranking_inputs.sql +0 -0
  482. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/066_kg_artifact_nodes.sql +0 -0
  483. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/067_inbox_digest_selections.sql +0 -0
  484. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/067_kg_temporal.sql +0 -0
  485. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/068_inbox_digest_app_settings.sql +0 -0
  486. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/068_kg_touch_counter.sql +0 -0
  487. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/069_kg_doc_types.sql +0 -0
  488. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/070_digest_ranking_inputs_recovery.sql +0 -0
  489. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/071_inbox_digest_selections_recovery.sql +0 -0
  490. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/072_inbox_digest_app_settings_recovery.sql +0 -0
  491. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/073_kg_cross_project.sql +0 -0
  492. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/073_kg_cross_project_down.sql +0 -0
  493. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/074_kg_infra_types.sql +0 -0
  494. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/074_kg_infra_types_down.sql +0 -0
  495. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/075_kg_file_state_recovery.sql +0 -0
  496. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/075_kg_file_state_recovery_down.sql +0 -0
  497. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/076_kg_watcher_state.sql +0 -0
  498. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/076_kg_watcher_state_down.sql +0 -0
  499. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/077_kg_doc_types_extend.sql +0 -0
  500. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/077_kg_doc_types_extend_down.sql +0 -0
  501. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/078_kg_fts5.sql +0 -0
  502. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/078_kg_fts5_down.sql +0 -0
  503. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/079_kg_missing_indexes.sql +0 -0
  504. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/079_kg_missing_indexes_down.sql +0 -0
  505. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/080_kg_fts5_extended.sql +0 -0
  506. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/080_kg_fts5_extended_down.sql +0 -0
  507. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/081_kg_lens_indexes.sql +0 -0
  508. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/081_kg_lens_indexes_down.sql +0 -0
  509. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/082_kg_pins.sql +0 -0
  510. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/082_kg_pins_down.sql +0 -0
  511. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/083_kg_graph_nodes_degree.sql +0 -0
  512. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/083_kg_graph_nodes_degree_down.sql +0 -0
  513. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/084_drop_legacy_scheduler_tables.sql +0 -0
  514. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/084_drop_legacy_scheduler_tables_down.sql +0 -0
  515. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/085_kg_edge_resolves_to.sql +0 -0
  516. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/085_kg_edge_resolves_to_down.sql +0 -0
  517. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/086_project_status_updates_feed.sql +0 -0
  518. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/086_project_status_updates_feed_down.sql +0 -0
  519. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/087_session_metrics_dual.sql +0 -0
  520. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/087_session_metrics_dual_down.sql +0 -0
  521. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/088_rename_context_pct_legacy.sql +0 -0
  522. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/088_rename_context_pct_legacy_down.sql +0 -0
  523. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/089_session_metrics_equivalent_cost.sql +0 -0
  524. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/089_session_metrics_equivalent_cost_down.sql +0 -0
  525. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/090_kg_inbox_node_type.sql +0 -0
  526. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/090_kg_inbox_node_type_down.sql +0 -0
  527. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/091_kg_inbox_node_type_check.sql +0 -0
  528. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/091_kg_inbox_node_type_check_down.sql +0 -0
  529. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/092_sessions_activity_state_ts.sql +0 -0
  530. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/092_sessions_activity_state_ts_down.sql +0 -0
  531. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/093_sessions_activity_state_column.sql +0 -0
  532. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/093_sessions_activity_state_column_down.sql +0 -0
  533. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/094_ingest_pending.sql +0 -0
  534. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/094_ingest_pending_down.sql +0 -0
  535. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/095_kg_intent_first.sql +0 -0
  536. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/095_kg_intent_first_down.sql +0 -0
  537. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/096_kg_xlsx_artifact_prefix.sql +0 -0
  538. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/096_kg_xlsx_artifact_prefix_down.sql +0 -0
  539. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/097_ingest_change_history.sql +0 -0
  540. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/097_ingest_change_history_down.sql +0 -0
  541. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/098_kg_node_type_business.sql +0 -0
  542. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/098_kg_node_type_business_down.sql +0 -0
  543. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/099_kg_edges_restore_weight.sql +0 -0
  544. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/099_kg_edges_restore_weight_down.sql +0 -0
  545. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/100_kg_enriched_at.sql +0 -0
  546. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/100_kg_enriched_at_down.sql +0 -0
  547. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/101_local_llm_shadow_comparisons.sql +0 -0
  548. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/101_local_llm_shadow_comparisons_down.sql +0 -0
  549. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/102_promote_llm_costs.sql +0 -0
  550. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/102_promote_llm_costs_down.sql +0 -0
  551. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/103_ingest_skipped_log.sql +0 -0
  552. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/103_ingest_skipped_log_down.sql +0 -0
  553. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/120_docs_governance.sql +0 -0
  554. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/120_docs_governance_down.sql +0 -0
  555. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/121_notification_event_fk_cleanup.sql +0 -0
  556. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/121_notification_event_fk_cleanup_down.sql +0 -0
  557. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/122_docs_drift_history.sql +0 -0
  558. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/122_docs_drift_history_down.sql +0 -0
  559. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/123_ingest_parser_waiting_status.sql +0 -0
  560. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/123_ingest_parser_waiting_status_down.sql +0 -0
  561. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/124_heypocket_recordings.sql +0 -0
  562. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/124_heypocket_recordings_down.sql +0 -0
  563. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/125_kg_node_type_record.sql +0 -0
  564. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/125_kg_node_type_record_down.sql +0 -0
  565. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/126_ingest_terminal_upload_source_kind.sql +0 -0
  566. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/126_ingest_terminal_upload_source_kind_down.sql +0 -0
  567. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/127_brain_v1_substrate.sql +0 -0
  568. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/127_brain_v1_substrate_down.sql +0 -0
  569. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/128_brain_drift_signals.sql +0 -0
  570. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/128_brain_drift_signals_down.sql +0 -0
  571. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/129_brain_memory_operations.sql +0 -0
  572. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/129_brain_memory_operations_down.sql +0 -0
  573. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/130_brain_findings.sql +0 -0
  574. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/130_brain_findings_down.sql +0 -0
  575. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/132_kg_pr_modifies.sql +0 -0
  576. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/132_kg_pr_modifies_down.sql +0 -0
  577. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/133_brain_v1_2_direction_schema.sql +0 -0
  578. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/133_brain_v1_2_direction_schema_down.sql +0 -0
  579. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/134_brain_journal_narrative_polished.sql +0 -0
  580. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/134_brain_journal_narrative_polished_down.sql +0 -0
  581. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/135_kg_edges_provider.sql +0 -0
  582. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/136_documents_fts.sql +0 -0
  583. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/137_promote_llm_costs.sql +0 -0
  584. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/137_promote_llm_costs_down.sql +0 -0
  585. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/138_ingest_api_keys.sql +0 -0
  586. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/138_ingest_api_keys_down.sql +0 -0
  587. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/139_ingest_pending_ingress.sql +0 -0
  588. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/139_ingest_pending_ingress_down.sql +0 -0
  589. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/140_ingest_idempotency_quota.sql +0 -0
  590. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/140_ingest_idempotency_quota_down.sql +0 -0
  591. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/141_ingest_pending_metadata.sql +0 -0
  592. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/141_ingest_pending_metadata_down.sql +0 -0
  593. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/142_llm_function_config.sql +0 -0
  594. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/142_llm_function_config_down.sql +0 -0
  595. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/143_kg_code_embeddings.sql +0 -0
  596. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/143_kg_code_embeddings_down.sql +0 -0
  597. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/migrations/__init__.py +0 -0
  598. {marvisx_cli-0.1.0 → marvisx_cli-0.2.0}/projects/_template/project.yaml +0 -0
  599. {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.1.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 = "/data/pir/lib/vec0"
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
- return holder
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
- vec_path = Path(settings.vec0_path)
502
- vec_so = vec_path.with_suffix(".so") if not vec_path.suffix else vec_path
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(?)", [str(vec_path)])
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 != 'pending'
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 = f"fnd_{uuid.uuid4().hex[:24]}"
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
- vec_path = str(Path(vec0_path))
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(?)", [vec_path])
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 (PROJECTS_ROOT / slug).resolve()
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(PROJECTS_ROOT)),
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(PROJECTS_ROOT)}")
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
- try:
179
- probe = await sample_internet_probe(collector)
180
- await append_terminal_metrics_record(
181
- {
182
- "kind": "internet_probe",
183
- "probe": probe,
184
- },
185
- output_dir=output_dir,
186
- )
187
- except Exception:
188
- logger.warning("terminal metrics internet probe failed", exc_info=True)
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 pathlib import Path
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
- vec_path = Path(settings.vec0_path)
238
- vec_so = vec_path.with_suffix(".so") if not vec_path.suffix else vec_path
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(?)", [str(vec_path)])
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 pathlib import Path
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
- vec_path = Path(settings.vec0_path)
287
- vec_so = vec_path.with_suffix(".so") if not vec_path.suffix else vec_path
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(?)", [str(vec_path)])
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.1.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
- DEFAULT_VAULT_DIR,
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
- telemetry = bool(settings_data.get("telemetry", {}).get("enabled", False)) if isinstance(
155
- settings_data.get("telemetry"), dict
156
- ) else bool(settings_data.get("telemetry", False))
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,
@@ -220,7 +220,7 @@ def _install_id() -> str:
220
220
 
221
221
  def _marvis_version() -> str:
222
222
  """The CLI version (kept in lockstep with ``marvis version``)."""
223
- return "0.1.0"
223
+ return "0.2.0"
224
224
 
225
225
 
226
226
  def _os_name() -> str: