execweave 0.8.9__tar.gz → 0.8.11__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 (506) hide show
  1. {execweave-0.8.9 → execweave-0.8.11}/PKG-INFO +9 -5
  2. {execweave-0.8.9 → execweave-0.8.11}/README.de.md +1 -1
  3. {execweave-0.8.9 → execweave-0.8.11}/README.fr.md +1 -1
  4. {execweave-0.8.9 → execweave-0.8.11}/README.ja.md +1 -1
  5. {execweave-0.8.9 → execweave-0.8.11}/README.ko.md +1 -1
  6. {execweave-0.8.9 → execweave-0.8.11}/README.md +8 -4
  7. {execweave-0.8.9 → execweave-0.8.11}/README.ru.md +1 -1
  8. {execweave-0.8.9 → execweave-0.8.11}/README.zh-CN.md +1 -1
  9. {execweave-0.8.9 → execweave-0.8.11}/README.zh-TW.md +1 -1
  10. {execweave-0.8.9 → execweave-0.8.11}/pyproject.toml +2 -2
  11. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/__init__.py +1 -1
  12. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/auto_specialized.py +150 -28
  13. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/collector.py +82 -22
  14. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/command.py +47 -8
  15. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/strace_backend.py +4 -1
  16. execweave-0.8.11/tests/test_cursor_ollama_session_lifecycle.py +176 -0
  17. execweave-0.8.11/tests/test_ollama_serve_runtime_integration.py +293 -0
  18. {execweave-0.8.9 → execweave-0.8.11}/tests/test_v069_dashboard_release.py +3 -3
  19. {execweave-0.8.9 → execweave-0.8.11}/.github/workflows/ci.yml +0 -0
  20. {execweave-0.8.9 → execweave-0.8.11}/.github/workflows/cleanup-workflow-history.yml +0 -0
  21. {execweave-0.8.9 → execweave-0.8.11}/.github/workflows/i18n.yml +0 -0
  22. {execweave-0.8.9 → execweave-0.8.11}/.github/workflows/package-benchmark.yml +0 -0
  23. {execweave-0.8.9 → execweave-0.8.11}/.github/workflows/package-smoke.yml +0 -0
  24. {execweave-0.8.9 → execweave-0.8.11}/.github/workflows/provider-capability-stage-integrity.yml +0 -0
  25. {execweave-0.8.9 → execweave-0.8.11}/.github/workflows/provider-dashboard-contract.yml +0 -0
  26. {execweave-0.8.9 → execweave-0.8.11}/.github/workflows/publish.yml +0 -0
  27. {execweave-0.8.9 → execweave-0.8.11}/.github/workflows/scalability.yml +0 -0
  28. {execweave-0.8.9 → execweave-0.8.11}/.github/workflows/viewer-agent-isolation.yml +0 -0
  29. {execweave-0.8.9 → execweave-0.8.11}/.github/workflows/wheel-smoke.yml +0 -0
  30. {execweave-0.8.9 → execweave-0.8.11}/.github/workflows/windows-launcher.yml +0 -0
  31. {execweave-0.8.9 → execweave-0.8.11}/.gitignore +0 -0
  32. {execweave-0.8.9 → execweave-0.8.11}/LICENSE +0 -0
  33. {execweave-0.8.9 → execweave-0.8.11}/benchmarks/phase1_overhead.py +0 -0
  34. {execweave-0.8.9 → execweave-0.8.11}/docs/antigravity-hooks.md +0 -0
  35. {execweave-0.8.9 → execweave-0.8.11}/docs/assets/codex.gif +0 -0
  36. {execweave-0.8.9 → execweave-0.8.11}/docs/benchmarks/README.md +0 -0
  37. {execweave-0.8.9 → execweave-0.8.11}/docs/benchmarks/v0.6.0-github-actions.json +0 -0
  38. {execweave-0.8.9 → execweave-0.8.11}/docs/benchmarks/v0.6.0-github-actions.svg +0 -0
  39. {execweave-0.8.9 → execweave-0.8.11}/docs/claude-code-hooks.de.md +0 -0
  40. {execweave-0.8.9 → execweave-0.8.11}/docs/claude-code-hooks.fr.md +0 -0
  41. {execweave-0.8.9 → execweave-0.8.11}/docs/claude-code-hooks.ja.md +0 -0
  42. {execweave-0.8.9 → execweave-0.8.11}/docs/claude-code-hooks.ko.md +0 -0
  43. {execweave-0.8.9 → execweave-0.8.11}/docs/claude-code-hooks.md +0 -0
  44. {execweave-0.8.9 → execweave-0.8.11}/docs/claude-code-hooks.ru.md +0 -0
  45. {execweave-0.8.9 → execweave-0.8.11}/docs/claude-code-hooks.zh-CN.md +0 -0
  46. {execweave-0.8.9 → execweave-0.8.11}/docs/claude-code-hooks.zh-TW.md +0 -0
  47. {execweave-0.8.9 → execweave-0.8.11}/docs/codex-hooks.de.md +0 -0
  48. {execweave-0.8.9 → execweave-0.8.11}/docs/codex-hooks.fr.md +0 -0
  49. {execweave-0.8.9 → execweave-0.8.11}/docs/codex-hooks.ja.md +0 -0
  50. {execweave-0.8.9 → execweave-0.8.11}/docs/codex-hooks.ko.md +0 -0
  51. {execweave-0.8.9 → execweave-0.8.11}/docs/codex-hooks.md +0 -0
  52. {execweave-0.8.9 → execweave-0.8.11}/docs/codex-hooks.ru.md +0 -0
  53. {execweave-0.8.9 → execweave-0.8.11}/docs/codex-hooks.zh-CN.md +0 -0
  54. {execweave-0.8.9 → execweave-0.8.11}/docs/codex-hooks.zh-TW.md +0 -0
  55. {execweave-0.8.9 → execweave-0.8.11}/docs/cursor-hooks.de.md +0 -0
  56. {execweave-0.8.9 → execweave-0.8.11}/docs/cursor-hooks.fr.md +0 -0
  57. {execweave-0.8.9 → execweave-0.8.11}/docs/cursor-hooks.ja.md +0 -0
  58. {execweave-0.8.9 → execweave-0.8.11}/docs/cursor-hooks.ko.md +0 -0
  59. {execweave-0.8.9 → execweave-0.8.11}/docs/cursor-hooks.md +0 -0
  60. {execweave-0.8.9 → execweave-0.8.11}/docs/cursor-hooks.ru.md +0 -0
  61. {execweave-0.8.9 → execweave-0.8.11}/docs/cursor-hooks.zh-CN.md +0 -0
  62. {execweave-0.8.9 → execweave-0.8.11}/docs/cursor-hooks.zh-TW.md +0 -0
  63. {execweave-0.8.9 → execweave-0.8.11}/docs/evidence-grades.de.md +0 -0
  64. {execweave-0.8.9 → execweave-0.8.11}/docs/evidence-grades.fr.md +0 -0
  65. {execweave-0.8.9 → execweave-0.8.11}/docs/evidence-grades.ja.md +0 -0
  66. {execweave-0.8.9 → execweave-0.8.11}/docs/evidence-grades.ko.md +0 -0
  67. {execweave-0.8.9 → execweave-0.8.11}/docs/evidence-grades.md +0 -0
  68. {execweave-0.8.9 → execweave-0.8.11}/docs/evidence-grades.ru.md +0 -0
  69. {execweave-0.8.9 → execweave-0.8.11}/docs/evidence-grades.zh-CN.md +0 -0
  70. {execweave-0.8.9 → execweave-0.8.11}/docs/evidence-grades.zh-TW.md +0 -0
  71. {execweave-0.8.9 → execweave-0.8.11}/docs/inference-gateway.de.md +0 -0
  72. {execweave-0.8.9 → execweave-0.8.11}/docs/inference-gateway.fr.md +0 -0
  73. {execweave-0.8.9 → execweave-0.8.11}/docs/inference-gateway.ja.md +0 -0
  74. {execweave-0.8.9 → execweave-0.8.11}/docs/inference-gateway.ko.md +0 -0
  75. {execweave-0.8.9 → execweave-0.8.11}/docs/inference-gateway.md +0 -0
  76. {execweave-0.8.9 → execweave-0.8.11}/docs/inference-gateway.ru.md +0 -0
  77. {execweave-0.8.9 → execweave-0.8.11}/docs/inference-gateway.zh-CN.md +0 -0
  78. {execweave-0.8.9 → execweave-0.8.11}/docs/inference-gateway.zh-TW.md +0 -0
  79. {execweave-0.8.9 → execweave-0.8.11}/docs/internal/provider-capability-matrix.md +0 -0
  80. {execweave-0.8.9 → execweave-0.8.11}/docs/live-graph.de.md +0 -0
  81. {execweave-0.8.9 → execweave-0.8.11}/docs/live-graph.fr.md +0 -0
  82. {execweave-0.8.9 → execweave-0.8.11}/docs/live-graph.ja.md +0 -0
  83. {execweave-0.8.9 → execweave-0.8.11}/docs/live-graph.ko.md +0 -0
  84. {execweave-0.8.9 → execweave-0.8.11}/docs/live-graph.md +0 -0
  85. {execweave-0.8.9 → execweave-0.8.11}/docs/live-graph.ru.md +0 -0
  86. {execweave-0.8.9 → execweave-0.8.11}/docs/live-graph.zh-CN.md +0 -0
  87. {execweave-0.8.9 → execweave-0.8.11}/docs/live-graph.zh-TW.md +0 -0
  88. {execweave-0.8.9 → execweave-0.8.11}/docs/model-runtime.de.md +0 -0
  89. {execweave-0.8.9 → execweave-0.8.11}/docs/model-runtime.fr.md +0 -0
  90. {execweave-0.8.9 → execweave-0.8.11}/docs/model-runtime.ja.md +0 -0
  91. {execweave-0.8.9 → execweave-0.8.11}/docs/model-runtime.ko.md +0 -0
  92. {execweave-0.8.9 → execweave-0.8.11}/docs/model-runtime.md +0 -0
  93. {execweave-0.8.9 → execweave-0.8.11}/docs/model-runtime.ru.md +0 -0
  94. {execweave-0.8.9 → execweave-0.8.11}/docs/model-runtime.zh-CN.md +0 -0
  95. {execweave-0.8.9 → execweave-0.8.11}/docs/model-runtime.zh-TW.md +0 -0
  96. {execweave-0.8.9 → execweave-0.8.11}/docs/opencode-plugin.de.md +0 -0
  97. {execweave-0.8.9 → execweave-0.8.11}/docs/opencode-plugin.fr.md +0 -0
  98. {execweave-0.8.9 → execweave-0.8.11}/docs/opencode-plugin.ja.md +0 -0
  99. {execweave-0.8.9 → execweave-0.8.11}/docs/opencode-plugin.ko.md +0 -0
  100. {execweave-0.8.9 → execweave-0.8.11}/docs/opencode-plugin.md +0 -0
  101. {execweave-0.8.9 → execweave-0.8.11}/docs/opencode-plugin.ru.md +0 -0
  102. {execweave-0.8.9 → execweave-0.8.11}/docs/opencode-plugin.zh-CN.md +0 -0
  103. {execweave-0.8.9 → execweave-0.8.11}/docs/opencode-plugin.zh-TW.md +0 -0
  104. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-1-runtime-collection.de.md +0 -0
  105. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-1-runtime-collection.fr.md +0 -0
  106. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-1-runtime-collection.ja.md +0 -0
  107. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-1-runtime-collection.ko.md +0 -0
  108. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-1-runtime-collection.md +0 -0
  109. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-1-runtime-collection.ru.md +0 -0
  110. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-1-runtime-collection.zh-CN.md +0 -0
  111. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-1-runtime-collection.zh-TW.md +0 -0
  112. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-2-execution-graph.de.md +0 -0
  113. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-2-execution-graph.fr.md +0 -0
  114. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-2-execution-graph.ja.md +0 -0
  115. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-2-execution-graph.ko.md +0 -0
  116. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-2-execution-graph.md +0 -0
  117. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-2-execution-graph.ru.md +0 -0
  118. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-2-execution-graph.zh-CN.md +0 -0
  119. {execweave-0.8.9 → execweave-0.8.11}/docs/phase-2-execution-graph.zh-TW.md +0 -0
  120. {execweave-0.8.9 → execweave-0.8.11}/docs/remaining-provider-audit-v0.8.7.md +0 -0
  121. {execweave-0.8.9 → execweave-0.8.11}/docs/rule-packs.de.md +0 -0
  122. {execweave-0.8.9 → execweave-0.8.11}/docs/rule-packs.fr.md +0 -0
  123. {execweave-0.8.9 → execweave-0.8.11}/docs/rule-packs.ja.md +0 -0
  124. {execweave-0.8.9 → execweave-0.8.11}/docs/rule-packs.ko.md +0 -0
  125. {execweave-0.8.9 → execweave-0.8.11}/docs/rule-packs.md +0 -0
  126. {execweave-0.8.9 → execweave-0.8.11}/docs/rule-packs.ru.md +0 -0
  127. {execweave-0.8.9 → execweave-0.8.11}/docs/rule-packs.zh-CN.md +0 -0
  128. {execweave-0.8.9 → execweave-0.8.11}/docs/rule-packs.zh-TW.md +0 -0
  129. {execweave-0.8.9 → execweave-0.8.11}/docs/run-integrity.de.md +0 -0
  130. {execweave-0.8.9 → execweave-0.8.11}/docs/run-integrity.fr.md +0 -0
  131. {execweave-0.8.9 → execweave-0.8.11}/docs/run-integrity.ja.md +0 -0
  132. {execweave-0.8.9 → execweave-0.8.11}/docs/run-integrity.ko.md +0 -0
  133. {execweave-0.8.9 → execweave-0.8.11}/docs/run-integrity.md +0 -0
  134. {execweave-0.8.9 → execweave-0.8.11}/docs/run-integrity.ru.md +0 -0
  135. {execweave-0.8.9 → execweave-0.8.11}/docs/run-integrity.zh-CN.md +0 -0
  136. {execweave-0.8.9 → execweave-0.8.11}/docs/run-integrity.zh-TW.md +0 -0
  137. {execweave-0.8.9 → execweave-0.8.11}/docs/runtime-threat-model.de.md +0 -0
  138. {execweave-0.8.9 → execweave-0.8.11}/docs/runtime-threat-model.fr.md +0 -0
  139. {execweave-0.8.9 → execweave-0.8.11}/docs/runtime-threat-model.ja.md +0 -0
  140. {execweave-0.8.9 → execweave-0.8.11}/docs/runtime-threat-model.ko.md +0 -0
  141. {execweave-0.8.9 → execweave-0.8.11}/docs/runtime-threat-model.md +0 -0
  142. {execweave-0.8.9 → execweave-0.8.11}/docs/runtime-threat-model.ru.md +0 -0
  143. {execweave-0.8.9 → execweave-0.8.11}/docs/runtime-threat-model.zh-CN.md +0 -0
  144. {execweave-0.8.9 → execweave-0.8.11}/docs/runtime-threat-model.zh-TW.md +0 -0
  145. {execweave-0.8.9 → execweave-0.8.11}/docs/security-analysis.de.md +0 -0
  146. {execweave-0.8.9 → execweave-0.8.11}/docs/security-analysis.fr.md +0 -0
  147. {execweave-0.8.9 → execweave-0.8.11}/docs/security-analysis.ja.md +0 -0
  148. {execweave-0.8.9 → execweave-0.8.11}/docs/security-analysis.ko.md +0 -0
  149. {execweave-0.8.9 → execweave-0.8.11}/docs/security-analysis.md +0 -0
  150. {execweave-0.8.9 → execweave-0.8.11}/docs/security-analysis.ru.md +0 -0
  151. {execweave-0.8.9 → execweave-0.8.11}/docs/security-analysis.zh-CN.md +0 -0
  152. {execweave-0.8.9 → execweave-0.8.11}/docs/security-analysis.zh-TW.md +0 -0
  153. {execweave-0.8.9 → execweave-0.8.11}/docs/semantic-telemetry.de.md +0 -0
  154. {execweave-0.8.9 → execweave-0.8.11}/docs/semantic-telemetry.fr.md +0 -0
  155. {execweave-0.8.9 → execweave-0.8.11}/docs/semantic-telemetry.ja.md +0 -0
  156. {execweave-0.8.9 → execweave-0.8.11}/docs/semantic-telemetry.ko.md +0 -0
  157. {execweave-0.8.9 → execweave-0.8.11}/docs/semantic-telemetry.md +0 -0
  158. {execweave-0.8.9 → execweave-0.8.11}/docs/semantic-telemetry.ru.md +0 -0
  159. {execweave-0.8.9 → execweave-0.8.11}/docs/semantic-telemetry.zh-CN.md +0 -0
  160. {execweave-0.8.9 → execweave-0.8.11}/docs/semantic-telemetry.zh-TW.md +0 -0
  161. {execweave-0.8.9 → execweave-0.8.11}/docs/v0.6.5-hardening-decisions.md +0 -0
  162. {execweave-0.8.9 → execweave-0.8.11}/docs/v0.8.3-graph-ergonomics.md +0 -0
  163. {execweave-0.8.9 → execweave-0.8.11}/scripts/audit_i18n_parity.py +0 -0
  164. {execweave-0.8.9 → execweave-0.8.11}/scripts/check_claude_hook.py +0 -0
  165. {execweave-0.8.9 → execweave-0.8.11}/scripts/check_claude_record_graph.py +0 -0
  166. {execweave-0.8.9 → execweave-0.8.11}/scripts/check_codex_hook.py +0 -0
  167. {execweave-0.8.9 → execweave-0.8.11}/scripts/check_conversation_records.py +0 -0
  168. {execweave-0.8.9 → execweave-0.8.11}/scripts/check_correlation_graph.py +0 -0
  169. {execweave-0.8.9 → execweave-0.8.11}/scripts/check_inference_gateway_cli.py +0 -0
  170. {execweave-0.8.9 → execweave-0.8.11}/scripts/check_model_runtime_cli.py +0 -0
  171. {execweave-0.8.9 → execweave-0.8.11}/scripts/check_openai_compatible_cli.py +0 -0
  172. {execweave-0.8.9 → execweave-0.8.11}/scripts/check_release_stage_integrity.py +0 -0
  173. {execweave-0.8.9 → execweave-0.8.11}/scripts/check_semantic_graph.py +0 -0
  174. {execweave-0.8.9 → execweave-0.8.11}/scripts/check_viewer_js.py +0 -0
  175. {execweave-0.8.9 → execweave-0.8.11}/scripts/check_wheel_install.py +0 -0
  176. {execweave-0.8.9 → execweave-0.8.11}/scripts/check_windows_launchers.py +0 -0
  177. {execweave-0.8.9 → execweave-0.8.11}/scripts/emit_claude_hook_smoke.py +0 -0
  178. {execweave-0.8.9 → execweave-0.8.11}/scripts/emit_codex_hook_smoke.py +0 -0
  179. {execweave-0.8.9 → execweave-0.8.11}/scripts/emit_cursor_hook_smoke.py +0 -0
  180. {execweave-0.8.9 → execweave-0.8.11}/scripts/emit_opencode_plugin_smoke.py +0 -0
  181. {execweave-0.8.9 → execweave-0.8.11}/scripts/make_semantic_smoke.py +0 -0
  182. {execweave-0.8.9 → execweave-0.8.11}/scripts/probe_provider_capability.py +0 -0
  183. {execweave-0.8.9 → execweave-0.8.11}/scripts/sync_i18n_nav.py +0 -0
  184. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/__main__.py +0 -0
  185. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/_conversation_records_core.py +0 -0
  186. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/agent_bootstrap.py +0 -0
  187. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/agent_topology.py +0 -0
  188. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/agent_trace.py +0 -0
  189. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/agy_preview_sanitize.py +0 -0
  190. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/analysis.py +0 -0
  191. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/anthropic.py +0 -0
  192. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/anthropic_cli.py +0 -0
  193. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/anthropic_full_fidelity.py +0 -0
  194. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/antigravity_adapter.py +0 -0
  195. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/antigravity_adapter_base.py +0 -0
  196. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/antigravity_full_fidelity.py +0 -0
  197. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/antigravity_full_fidelity_base.py +0 -0
  198. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/antigravity_full_fidelity_collaboration_base.py +0 -0
  199. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/antigravity_hook_cli.py +0 -0
  200. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/antigravity_record.py +0 -0
  201. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/antigravity_subagent_linkage.py +0 -0
  202. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/antigravity_trace_capability.py +0 -0
  203. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/backends.py +0 -0
  204. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/benchmark.py +0 -0
  205. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/claude_adapter.py +0 -0
  206. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/claude_child_transcript.py +0 -0
  207. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/claude_delegation.py +0 -0
  208. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/claude_full_fidelity.py +0 -0
  209. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/claude_hook_cli.py +0 -0
  210. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/claude_hook_contract.py +0 -0
  211. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/claude_model_observer.py +0 -0
  212. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/claude_record.py +0 -0
  213. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/cli.py +0 -0
  214. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/codex_adapter.py +0 -0
  215. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/codex_conversation.py +0 -0
  216. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/codex_full_fidelity.py +0 -0
  217. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/codex_hook_cli.py +0 -0
  218. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/codex_hook_lifecycle.py +0 -0
  219. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/codex_message_diagnostics.py +0 -0
  220. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/codex_message_transport_diagnostics.py +0 -0
  221. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/codex_record.py +0 -0
  222. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/codex_rollout_structures.py +0 -0
  223. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/codex_rollout_trace.py +0 -0
  224. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/codex_rollout_trace_base.py +0 -0
  225. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/content_evidence.py +0 -0
  226. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/content_store.py +0 -0
  227. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_archive.py +0 -0
  228. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_message_identity.py +0 -0
  229. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_preview.py +0 -0
  230. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_preview_antigravity.py +0 -0
  231. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_preview_claude.py +0 -0
  232. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_preview_codex.py +0 -0
  233. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_preview_common.py +0 -0
  234. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_preview_generic.py +0 -0
  235. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_preview_lines.py +0 -0
  236. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_preview_transcript.py +0 -0
  237. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_records.py +0 -0
  238. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_records_antigravity.py +0 -0
  239. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_records_codex.py +0 -0
  240. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_records_common.py +0 -0
  241. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/conversation_records_ollama.py +0 -0
  242. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/correlation.py +0 -0
  243. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/cursor_adapter.py +0 -0
  244. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/cursor_delegation.py +0 -0
  245. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/cursor_delegation_base.py +0 -0
  246. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/cursor_full_fidelity.py +0 -0
  247. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/cursor_hook_cli.py +0 -0
  248. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/cursor_hook_contract.py +0 -0
  249. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/cursor_record.py +0 -0
  250. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/dashboard_shell.py +0 -0
  251. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/entry.py +0 -0
  252. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/evidence_availability.py +0 -0
  253. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/evidence_grade.py +0 -0
  254. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/fidelity.py +0 -0
  255. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/filesystem.py +0 -0
  256. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/focus.py +0 -0
  257. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/graph.py +0 -0
  258. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/graph_ops.py +0 -0
  259. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/http_proxy.py +0 -0
  260. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/http_proxy_cli.py +0 -0
  261. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/inference_gateway.py +0 -0
  262. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/inference_gateway_cli.py +0 -0
  263. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/inference_gateway_full_fidelity.py +0 -0
  264. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/inference_identity.py +0 -0
  265. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/inference_identity_cli.py +0 -0
  266. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/integrity.py +0 -0
  267. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/integrity_cli.py +0 -0
  268. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/litellm_callback.py +0 -0
  269. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/litellm_callback_cli.py +0 -0
  270. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/live.py +0 -0
  271. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/live_core.py +0 -0
  272. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/live_view.py +0 -0
  273. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/live_view_extra_style.py +0 -0
  274. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/live_view_markup.py +0 -0
  275. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/live_view_process_layout.py +0 -0
  276. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/live_view_readability.py +0 -0
  277. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/live_view_script_a.py +0 -0
  278. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/live_view_script_b.py +0 -0
  279. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/live_view_script_c.py +0 -0
  280. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/live_view_script_d.py +0 -0
  281. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/live_view_style.py +0 -0
  282. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/model_runtime.py +0 -0
  283. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/model_runtime_cli.py +0 -0
  284. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/model_runtime_full_fidelity.py +0 -0
  285. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/openai_compatible.py +0 -0
  286. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/openai_compatible_cli.py +0 -0
  287. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/openai_compatible_full_fidelity.py +0 -0
  288. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/opencode_adapter.py +0 -0
  289. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/opencode_event_contract.py +0 -0
  290. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/opencode_full_fidelity.py +0 -0
  291. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/opencode_hook_cli.py +0 -0
  292. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/opencode_plugin_cli.py +0 -0
  293. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/opencode_record.py +0 -0
  294. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/opencode_task_linkage.py +0 -0
  295. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/overhead_benchmark.py +0 -0
  296. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/provider_capability.py +0 -0
  297. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/provider_lifecycle.py +0 -0
  298. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/provider_record.py +0 -0
  299. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/rule_pack.py +0 -0
  300. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/rule_pack_cli.py +0 -0
  301. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/scalability_benchmark.py +0 -0
  302. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/schema.py +0 -0
  303. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/scope.py +0 -0
  304. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/semantic.py +0 -0
  305. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/sink.py +0 -0
  306. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/stream_assembly.py +0 -0
  307. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/theme.py +0 -0
  308. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/top.py +0 -0
  309. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/top_cli.py +0 -0
  310. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/validate.py +0 -0
  311. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/vendor/dagre.min.js +0 -0
  312. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/view_cli.py +0 -0
  313. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer.py +0 -0
  314. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_agent_panel.py +0 -0
  315. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_agent_panel_antigravity.py +0 -0
  316. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_agent_panel_claude.py +0 -0
  317. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_agent_panel_codex.py +0 -0
  318. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_agent_panel_cursor.py +0 -0
  319. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_agent_panel_default.py +0 -0
  320. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_agent_panel_ollama.py +0 -0
  321. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_agent_panel_opencode.py +0 -0
  322. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_agent_panel_registry.py +0 -0
  323. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_content_inspector.py +0 -0
  324. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_dashboard_clean.py +0 -0
  325. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_dashboard_focus.py +0 -0
  326. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_dashboard_hardening.py +0 -0
  327. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_dashboard_hardening_v2.py +0 -0
  328. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_external_endpoints.py +0 -0
  329. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_limits.py +0 -0
  330. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_live_layout.py +0 -0
  331. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_projection.py +0 -0
  332. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/viewer_projection_base.py +0 -0
  333. {execweave-0.8.9 → execweave-0.8.11}/src/execweave/workflow.py +0 -0
  334. {execweave-0.8.9 → execweave-0.8.11}/tests/dashboard_readability_fixture.py +0 -0
  335. {execweave-0.8.9 → execweave-0.8.11}/tests/fixtures/codex_multi_agent/PROVENANCE.md +0 -0
  336. {execweave-0.8.9 → execweave-0.8.11}/tests/fixtures/codex_multi_agent/hook-payloads.json +0 -0
  337. {execweave-0.8.9 → execweave-0.8.11}/tests/fixtures/codex_multi_agent/rollout-main.jsonl +0 -0
  338. {execweave-0.8.9 → execweave-0.8.11}/tests/fixtures/hooks/README.md +0 -0
  339. {execweave-0.8.9 → execweave-0.8.11}/tests/fixtures/hooks/claude.json +0 -0
  340. {execweave-0.8.9 → execweave-0.8.11}/tests/fixtures/hooks/codex.json +0 -0
  341. {execweave-0.8.9 → execweave-0.8.11}/tests/fixtures/hooks/cursor.json +0 -0
  342. {execweave-0.8.9 → execweave-0.8.11}/tests/fixtures/hooks/manifest.json +0 -0
  343. {execweave-0.8.9 → execweave-0.8.11}/tests/fixtures/hooks/opencode.json +0 -0
  344. {execweave-0.8.9 → execweave-0.8.11}/tests/multi_agent_run_fixture.py +0 -0
  345. {execweave-0.8.9 → execweave-0.8.11}/tests/test_agent_bootstrap.py +0 -0
  346. {execweave-0.8.9 → execweave-0.8.11}/tests/test_agent_message_viewer.py +0 -0
  347. {execweave-0.8.9 → execweave-0.8.11}/tests/test_agent_node_labels.py +0 -0
  348. {execweave-0.8.9 → execweave-0.8.11}/tests/test_agent_said_panel.py +0 -0
  349. {execweave-0.8.9 → execweave-0.8.11}/tests/test_agent_topology_evidence.py +0 -0
  350. {execweave-0.8.9 → execweave-0.8.11}/tests/test_agent_trace_lifecycle.py +0 -0
  351. {execweave-0.8.9 → execweave-0.8.11}/tests/test_agent_trace_viewer_visibility.py +0 -0
  352. {execweave-0.8.9 → execweave-0.8.11}/tests/test_agy_windows_wire_acceptance.py +0 -0
  353. {execweave-0.8.9 → execweave-0.8.11}/tests/test_analysis.py +0 -0
  354. {execweave-0.8.9 → execweave-0.8.11}/tests/test_anthropic.py +0 -0
  355. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_agent_collaboration.py +0 -0
  356. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_child_panel_policy.py +0 -0
  357. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_child_transcript_tools.py +0 -0
  358. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_cursor_launch.py +0 -0
  359. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_field_run_regressions.py +0 -0
  360. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_history_replay.py +0 -0
  361. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_identity_topology.py +0 -0
  362. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_invocation_archive.py +0 -0
  363. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_lifecycle.py +0 -0
  364. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_linkage_projection.py +0 -0
  365. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_multi_conversation_isolation.py +0 -0
  366. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_official_contract.py +0 -0
  367. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_role_path_fallback.py +0 -0
  368. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_root_child_history_v2.py +0 -0
  369. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_subagent_transcript_linkage.py +0 -0
  370. {execweave-0.8.9 → execweave-0.8.11}/tests/test_antigravity_trace_capability_cli.py +0 -0
  371. {execweave-0.8.9 → execweave-0.8.11}/tests/test_auto_specialized.py +0 -0
  372. {execweave-0.8.9 → execweave-0.8.11}/tests/test_backends.py +0 -0
  373. {execweave-0.8.9 → execweave-0.8.11}/tests/test_claude_adapter.py +0 -0
  374. {execweave-0.8.9 → execweave-0.8.11}/tests/test_claude_child_transcript_tools.py +0 -0
  375. {execweave-0.8.9 → execweave-0.8.11}/tests/test_claude_delegation.py +0 -0
  376. {execweave-0.8.9 → execweave-0.8.11}/tests/test_claude_full_fidelity.py +0 -0
  377. {execweave-0.8.9 → execweave-0.8.11}/tests/test_claude_hook_contract.py +0 -0
  378. {execweave-0.8.9 → execweave-0.8.11}/tests/test_claude_hook_metadata.py +0 -0
  379. {execweave-0.8.9 → execweave-0.8.11}/tests/test_claude_hook_viewer.py +0 -0
  380. {execweave-0.8.9 → execweave-0.8.11}/tests/test_claude_model_observer.py +0 -0
  381. {execweave-0.8.9 → execweave-0.8.11}/tests/test_claude_record.py +0 -0
  382. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_adapter.py +0 -0
  383. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_archive_full_fidelity.py +0 -0
  384. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_child_panel_policy.py +0 -0
  385. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_conversation_isolation.py +0 -0
  386. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_full_fidelity.py +0 -0
  387. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_hook_lifecycle.py +0 -0
  388. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_hook_partial_capture.py +0 -0
  389. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_message_diagnostics.py +0 -0
  390. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_message_transport_diagnostics.py +0 -0
  391. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_nickname_path_fallback.py +0 -0
  392. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_plain_routed_agent_message.py +0 -0
  393. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_real_multi_agent_conversation.py +0 -0
  394. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_record.py +0 -0
  395. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_reducer_command.py +0 -0
  396. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_rollout_structures.py +0 -0
  397. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_rollout_trace.py +0 -0
  398. {execweave-0.8.9 → execweave-0.8.11}/tests/test_codex_routing_native_identity.py +0 -0
  399. {execweave-0.8.9 → execweave-0.8.11}/tests/test_collector.py +0 -0
  400. {execweave-0.8.9 → execweave-0.8.11}/tests/test_command.py +0 -0
  401. {execweave-0.8.9 → execweave-0.8.11}/tests/test_condense.py +0 -0
  402. {execweave-0.8.9 → execweave-0.8.11}/tests/test_conversation_access.py +0 -0
  403. {execweave-0.8.9 → execweave-0.8.11}/tests/test_conversation_agent_focus.py +0 -0
  404. {execweave-0.8.9 → execweave-0.8.11}/tests/test_conversation_agent_isolation.py +0 -0
  405. {execweave-0.8.9 → execweave-0.8.11}/tests/test_conversation_identity_merge.py +0 -0
  406. {execweave-0.8.9 → execweave-0.8.11}/tests/test_conversation_message_observation_dedupe.py +0 -0
  407. {execweave-0.8.9 → execweave-0.8.11}/tests/test_conversation_provider_parity.py +0 -0
  408. {execweave-0.8.9 → execweave-0.8.11}/tests/test_conversation_root_authority.py +0 -0
  409. {execweave-0.8.9 → execweave-0.8.11}/tests/test_correlation.py +0 -0
  410. {execweave-0.8.9 → execweave-0.8.11}/tests/test_correlation_canonical_path.py +0 -0
  411. {execweave-0.8.9 → execweave-0.8.11}/tests/test_correlation_checker.py +0 -0
  412. {execweave-0.8.9 → execweave-0.8.11}/tests/test_correlation_process_exe.py +0 -0
  413. {execweave-0.8.9 → execweave-0.8.11}/tests/test_cross_provider_agent_trace.py +0 -0
  414. {execweave-0.8.9 → execweave-0.8.11}/tests/test_cursor_adapter.py +0 -0
  415. {execweave-0.8.9 → execweave-0.8.11}/tests/test_cursor_delegation.py +0 -0
  416. {execweave-0.8.9 → execweave-0.8.11}/tests/test_cursor_full_fidelity.py +0 -0
  417. {execweave-0.8.9 → execweave-0.8.11}/tests/test_cursor_hook_contract.py +0 -0
  418. {execweave-0.8.9 → execweave-0.8.11}/tests/test_cursor_hook_fail_open.py +0 -0
  419. {execweave-0.8.9 → execweave-0.8.11}/tests/test_cursor_record.py +0 -0
  420. {execweave-0.8.9 → execweave-0.8.11}/tests/test_cursor_task_linkage.py +0 -0
  421. {execweave-0.8.9 → execweave-0.8.11}/tests/test_dashboard_information_architecture.py +0 -0
  422. {execweave-0.8.9 → execweave-0.8.11}/tests/test_dashboard_readability_e2e.py +0 -0
  423. {execweave-0.8.9 → execweave-0.8.11}/tests/test_dashboard_round_fold_state_e2e.py +0 -0
  424. {execweave-0.8.9 → execweave-0.8.11}/tests/test_dashboard_simplification.py +0 -0
  425. {execweave-0.8.9 → execweave-0.8.11}/tests/test_dashboard_ux_and_hook_projection.py +0 -0
  426. {execweave-0.8.9 → execweave-0.8.11}/tests/test_delegation_viewer.py +0 -0
  427. {execweave-0.8.9 → execweave-0.8.11}/tests/test_evidence_grade.py +0 -0
  428. {execweave-0.8.9 → execweave-0.8.11}/tests/test_execution_viewer.py +0 -0
  429. {execweave-0.8.9 → execweave-0.8.11}/tests/test_external_endpoints_all_providers.py +0 -0
  430. {execweave-0.8.9 → execweave-0.8.11}/tests/test_fidelity.py +0 -0
  431. {execweave-0.8.9 → execweave-0.8.11}/tests/test_filesystem_resilience.py +0 -0
  432. {execweave-0.8.9 → execweave-0.8.11}/tests/test_focus.py +0 -0
  433. {execweave-0.8.9 → execweave-0.8.11}/tests/test_fold_budget_setting.py +0 -0
  434. {execweave-0.8.9 → execweave-0.8.11}/tests/test_full_fidelity.py +0 -0
  435. {execweave-0.8.9 → execweave-0.8.11}/tests/test_graph.py +0 -0
  436. {execweave-0.8.9 → execweave-0.8.11}/tests/test_graph_clear_focus_e2e.py +0 -0
  437. {execweave-0.8.9 → execweave-0.8.11}/tests/test_graph_edge_routing_e2e.py +0 -0
  438. {execweave-0.8.9 → execweave-0.8.11}/tests/test_graph_lane_separation_e2e.py +0 -0
  439. {execweave-0.8.9 → execweave-0.8.11}/tests/test_graph_node_sizing_e2e.py +0 -0
  440. {execweave-0.8.9 → execweave-0.8.11}/tests/test_graph_ops.py +0 -0
  441. {execweave-0.8.9 → execweave-0.8.11}/tests/test_hook_fixture_corpus.py +0 -0
  442. {execweave-0.8.9 → execweave-0.8.11}/tests/test_http_proxy.py +0 -0
  443. {execweave-0.8.9 → execweave-0.8.11}/tests/test_inference_endpoint_identity.py +0 -0
  444. {execweave-0.8.9 → execweave-0.8.11}/tests/test_inference_gateway.py +0 -0
  445. {execweave-0.8.9 → execweave-0.8.11}/tests/test_inference_gateway_full_fidelity.py +0 -0
  446. {execweave-0.8.9 → execweave-0.8.11}/tests/test_inference_identity.py +0 -0
  447. {execweave-0.8.9 → execweave-0.8.11}/tests/test_integrity.py +0 -0
  448. {execweave-0.8.9 → execweave-0.8.11}/tests/test_litellm_callback.py +0 -0
  449. {execweave-0.8.9 → execweave-0.8.11}/tests/test_live.py +0 -0
  450. {execweave-0.8.9 → execweave-0.8.11}/tests/test_live_auth.py +0 -0
  451. {execweave-0.8.9 → execweave-0.8.11}/tests/test_live_dashboard.py +0 -0
  452. {execweave-0.8.9 → execweave-0.8.11}/tests/test_live_dashboard_js.py +0 -0
  453. {execweave-0.8.9 → execweave-0.8.11}/tests/test_live_delta.py +0 -0
  454. {execweave-0.8.9 → execweave-0.8.11}/tests/test_live_logs_export.py +0 -0
  455. {execweave-0.8.9 → execweave-0.8.11}/tests/test_live_theme.py +0 -0
  456. {execweave-0.8.9 → execweave-0.8.11}/tests/test_lmstudio_auto_specialized.py +0 -0
  457. {execweave-0.8.9 → execweave-0.8.11}/tests/test_local_runtime_live_capture.py +0 -0
  458. {execweave-0.8.9 → execweave-0.8.11}/tests/test_model_runtime.py +0 -0
  459. {execweave-0.8.9 → execweave-0.8.11}/tests/test_model_runtime_full_fidelity.py +0 -0
  460. {execweave-0.8.9 → execweave-0.8.11}/tests/test_ollama_panel_policy.py +0 -0
  461. {execweave-0.8.9 → execweave-0.8.11}/tests/test_openai_compatible.py +0 -0
  462. {execweave-0.8.9 → execweave-0.8.11}/tests/test_opencode_adapter.py +0 -0
  463. {execweave-0.8.9 → execweave-0.8.11}/tests/test_opencode_event_contract.py +0 -0
  464. {execweave-0.8.9 → execweave-0.8.11}/tests/test_opencode_event_lifecycle.py +0 -0
  465. {execweave-0.8.9 → execweave-0.8.11}/tests/test_opencode_full_fidelity.py +0 -0
  466. {execweave-0.8.9 → execweave-0.8.11}/tests/test_opencode_identity_unification.py +0 -0
  467. {execweave-0.8.9 → execweave-0.8.11}/tests/test_opencode_plugin.py +0 -0
  468. {execweave-0.8.9 → execweave-0.8.11}/tests/test_opencode_record.py +0 -0
  469. {execweave-0.8.9 → execweave-0.8.11}/tests/test_opencode_task_session_linkage.py +0 -0
  470. {execweave-0.8.9 → execweave-0.8.11}/tests/test_overhead_benchmark.py +0 -0
  471. {execweave-0.8.9 → execweave-0.8.11}/tests/test_per_agent_conversation_default.py +0 -0
  472. {execweave-0.8.9 → execweave-0.8.11}/tests/test_pr25_premerge_hardening_contract.py +0 -0
  473. {execweave-0.8.9 → execweave-0.8.11}/tests/test_pr25_premerge_hardening_e2e.py +0 -0
  474. {execweave-0.8.9 → execweave-0.8.11}/tests/test_process_tree_layout.py +0 -0
  475. {execweave-0.8.9 → execweave-0.8.11}/tests/test_provider_capability.py +0 -0
  476. {execweave-0.8.9 → execweave-0.8.11}/tests/test_provider_conversation_evidence.py +0 -0
  477. {execweave-0.8.9 → execweave-0.8.11}/tests/test_provider_conversation_history_integrity.py +0 -0
  478. {execweave-0.8.9 → execweave-0.8.11}/tests/test_provider_dashboard_contract.py +0 -0
  479. {execweave-0.8.9 → execweave-0.8.11}/tests/test_provider_lifecycle.py +0 -0
  480. {execweave-0.8.9 → execweave-0.8.11}/tests/test_release_stage_integrity_version_guard.py +0 -0
  481. {execweave-0.8.9 → execweave-0.8.11}/tests/test_rule_pack.py +0 -0
  482. {execweave-0.8.9 → execweave-0.8.11}/tests/test_schema.py +0 -0
  483. {execweave-0.8.9 → execweave-0.8.11}/tests/test_scope.py +0 -0
  484. {execweave-0.8.9 → execweave-0.8.11}/tests/test_semantic.py +0 -0
  485. {execweave-0.8.9 → execweave-0.8.11}/tests/test_shared_injected_context_scope.py +0 -0
  486. {execweave-0.8.9 → execweave-0.8.11}/tests/test_strace_backend.py +0 -0
  487. {execweave-0.8.9 → execweave-0.8.11}/tests/test_stream_assembly.py +0 -0
  488. {execweave-0.8.9 → execweave-0.8.11}/tests/test_threat_model.py +0 -0
  489. {execweave-0.8.9 → execweave-0.8.11}/tests/test_tool_traffic_e2e.py +0 -0
  490. {execweave-0.8.9 → execweave-0.8.11}/tests/test_top_detached.py +0 -0
  491. {execweave-0.8.9 → execweave-0.8.11}/tests/test_v063_features.py +0 -0
  492. {execweave-0.8.9 → execweave-0.8.11}/tests/test_v064_live_auto_integrations.py +0 -0
  493. {execweave-0.8.9 → execweave-0.8.11}/tests/test_v064_live_evidence.py +0 -0
  494. {execweave-0.8.9 → execweave-0.8.11}/tests/test_v079_review_e2e.py +0 -0
  495. {execweave-0.8.9 → execweave-0.8.11}/tests/test_v079_review_regressions.py +0 -0
  496. {execweave-0.8.9 → execweave-0.8.11}/tests/test_v083_release_gate_p2.py +0 -0
  497. {execweave-0.8.9 → execweave-0.8.11}/tests/test_validate.py +0 -0
  498. {execweave-0.8.9 → execweave-0.8.11}/tests/test_version.py +0 -0
  499. {execweave-0.8.9 → execweave-0.8.11}/tests/test_viewer.py +0 -0
  500. {execweave-0.8.9 → execweave-0.8.11}/tests/test_viewer_agent_isolation_e2e.py +0 -0
  501. {execweave-0.8.9 → execweave-0.8.11}/tests/test_viewer_child_authority.py +0 -0
  502. {execweave-0.8.9 → execweave-0.8.11}/tests/test_viewer_content_inspector.py +0 -0
  503. {execweave-0.8.9 → execweave-0.8.11}/tests/test_viewer_limits.py +0 -0
  504. {execweave-0.8.9 → execweave-0.8.11}/tests/test_viewer_projection.py +0 -0
  505. {execweave-0.8.9 → execweave-0.8.11}/tests/test_windows_codex_agy_display_repair.py +0 -0
  506. {execweave-0.8.9 → execweave-0.8.11}/tests/test_workflow.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: execweave
3
- Version: 0.8.9
3
+ Version: 0.8.11
4
4
  Summary: Turn AI-agent runtime behavior into a local interactive execution graph.
5
5
  Project-URL: Homepage, https://github.com/Irish-kw/ExecWeave
6
6
  Project-URL: Repository, https://github.com/Irish-kw/ExecWeave
@@ -85,7 +85,7 @@ ExecWeave is a source-available, local-first observability project that turns AI
85
85
  <img src="docs/assets/codex.gif" alt="ExecWeave animated live demo" width="100%">
86
86
  </p>
87
87
 
88
- This README documents **v0.8.9**. It includes dagre route-point rendering and post-layout port recomputation, with provider graph/history/raw contracts verified across Ubuntu, macOS, and Windows.
88
+ This README documents **v0.8.11**. This release makes managed local `ollama serve` capture fail-safe for independent loopback clients, so a later `ollama run`, SDK, or `curl` request from another terminal is recorded in the same semantic stream instead of silently falling back without conversation evidence. It also finalizes merged events, `graph.json`, and `viewer.html` when a Live run is stopped with Ctrl+C.
89
89
 
90
90
  ## Why ExecWeave
91
91
 
@@ -126,7 +126,11 @@ execweave live --open -- python my_agent.py
126
126
 
127
127
  > **Approve the hook when prompted.** On the first provider-integrated run, the Agent/IDE may ask whether ExecWeave may enable its local hook integration. Choose **Allow / Yes**. Without approval, OS-runtime telemetry can still work, but provider-level tool, model, conversation, and supplied-content visibility may be reduced or unavailable.
128
128
 
129
- Google Antigravity currently uses the `agy` CLI command; ExecWeave also accepts `antigravity` as a friendly alias and resolves it to `agy`. For Cursor, `execweave live --open -- cursor` first tries a normal PATH launcher, then falls back to the standard desktop application binary on macOS and Windows.
129
+ Google Antigravity currently uses the `agy` CLI command; ExecWeave also accepts `antigravity` as a friendly alias and resolves it to `agy`.
130
+
131
+ For Cursor on Windows, bare `cursor` follows the PATH entry the user actually has and, when it is the normal `.../resources/app/bin/cursor.cmd` shim, derives the matching `Cursor.exe` from that same installation root. This works for custom drives and arbitrary install directories; explicit launcher paths are left untouched. macOS/Windows standard desktop paths remain a fallback when the PATH shim cannot identify the desktop binary.
132
+
133
+ For a managed local Ollama server, `execweave live --open -- ollama serve` owns the public loopback endpoint and relays the real server through an internal loopback port. A later `ollama run`, Ollama SDK request, OpenAI-compatible client, or `curl` started from another terminal can therefore appear in the same ExecWeave semantic stream even though that client is not a child of the `ollama serve` process. ExecWeave prints the active public-to-internal relay mapping; if the public loopback endpoint cannot be safely reserved, the managed run now fails explicitly rather than silently losing conversation capture. Relay mode is deliberately limited to local `localhost` / `127.0.0.1` binds; external, wildcard, and IPv6 exposure is not rewritten. Stopping Live with Ctrl+C still finalizes the run artifacts before returning.
130
134
 
131
135
  Build finalized run artifacts with:
132
136
 
@@ -170,9 +174,9 @@ These are presentation-layer changes. Raw graph evidence is unchanged, and Live,
170
174
  | Claude Code | Yes | native hooks + full-fidelity supplied hook content + exact subagent results when exposed |
171
175
  | OpenAI Codex | Yes | lifecycle hooks + validated rollout transcripts + agent-local task/message/final-response routing |
172
176
  | Google Antigravity / Antigravity CLI | Yes | passive native hooks + validated conversation/subagent routing where exposed |
173
- | Cursor | Yes | native hooks + exact subagent task/summary routing when exposed |
177
+ | Cursor | Yes | native hooks + exact subagent task/summary routing when exposed; Windows bare-launch resolution follows the actual PATH installation |
174
178
  | OpenCode | Yes | project plugin + session/task routing + full-fidelity supplied plugin content |
175
- | Ollama | Yes | `execweave-model-runtime event/exchange/probe --runtime ollama` |
179
+ | Ollama | Yes | managed local `ollama serve` loopback relay + `execweave-model-runtime event/exchange/probe --runtime ollama` |
176
180
  | llama.cpp | Yes | `execweave-model-runtime event/exchange/probe --runtime llamacpp` |
177
181
  | vLLM | Yes | `execweave-model-runtime event/exchange/probe --runtime vllm` |
178
182
  | LM Studio | Only when the local process is launched under ExecWeave | `execweave-model-runtime event/exchange/probe --runtime lmstudio` |
@@ -32,7 +32,7 @@ ExecWeave ist ein source-available, local-first Observability-Projekt, das Aktiv
32
32
  <img src="docs/assets/codex.gif" alt="ExecWeave animated live demo" width="100%">
33
33
  </p>
34
34
 
35
- Dieses README dokumentiert **v0.8.9**.
35
+ Dieses README dokumentiert **v0.8.11**.
36
36
 
37
37
  ## Warum ExecWeave
38
38
 
@@ -32,7 +32,7 @@ ExecWeave est un projet d’observabilité source-available et local-first qui t
32
32
  <img src="docs/assets/codex.gif" alt="ExecWeave animated live demo" width="100%">
33
33
  </p>
34
34
 
35
- Ce README décrit **v0.8.9**.
35
+ Ce README décrit **v0.8.11**.
36
36
 
37
37
  ## Pourquoi ExecWeave
38
38
 
@@ -32,7 +32,7 @@ ExecWeave は source-available / local-first の observability プロジェク
32
32
  <img src="docs/assets/codex.gif" alt="ExecWeave animated live demo" width="100%">
33
33
  </p>
34
34
 
35
- この README は **v0.8.9** を説明します。
35
+ この README は **v0.8.11** を説明します。
36
36
 
37
37
  ## ExecWeave を使う理由
38
38
 
@@ -32,7 +32,7 @@ ExecWeave는 source-available, local-first observability 프로젝트입니다.
32
32
  <img src="docs/assets/codex.gif" alt="ExecWeave animated live demo" width="100%">
33
33
  </p>
34
34
 
35
- 이 README는 **v0.8.9**을 설명합니다.
35
+ 이 README는 **v0.8.11**을 설명합니다.
36
36
 
37
37
  ## 왜 ExecWeave인가
38
38
 
@@ -32,7 +32,7 @@ ExecWeave is a source-available, local-first observability project that turns AI
32
32
  <img src="docs/assets/codex.gif" alt="ExecWeave animated live demo" width="100%">
33
33
  </p>
34
34
 
35
- This README documents **v0.8.9**. It includes dagre route-point rendering and post-layout port recomputation, with provider graph/history/raw contracts verified across Ubuntu, macOS, and Windows.
35
+ This README documents **v0.8.11**. This release makes managed local `ollama serve` capture fail-safe for independent loopback clients, so a later `ollama run`, SDK, or `curl` request from another terminal is recorded in the same semantic stream instead of silently falling back without conversation evidence. It also finalizes merged events, `graph.json`, and `viewer.html` when a Live run is stopped with Ctrl+C.
36
36
 
37
37
  ## Why ExecWeave
38
38
 
@@ -73,7 +73,11 @@ execweave live --open -- python my_agent.py
73
73
 
74
74
  > **Approve the hook when prompted.** On the first provider-integrated run, the Agent/IDE may ask whether ExecWeave may enable its local hook integration. Choose **Allow / Yes**. Without approval, OS-runtime telemetry can still work, but provider-level tool, model, conversation, and supplied-content visibility may be reduced or unavailable.
75
75
 
76
- Google Antigravity currently uses the `agy` CLI command; ExecWeave also accepts `antigravity` as a friendly alias and resolves it to `agy`. For Cursor, `execweave live --open -- cursor` first tries a normal PATH launcher, then falls back to the standard desktop application binary on macOS and Windows.
76
+ Google Antigravity currently uses the `agy` CLI command; ExecWeave also accepts `antigravity` as a friendly alias and resolves it to `agy`.
77
+
78
+ For Cursor on Windows, bare `cursor` follows the PATH entry the user actually has and, when it is the normal `.../resources/app/bin/cursor.cmd` shim, derives the matching `Cursor.exe` from that same installation root. This works for custom drives and arbitrary install directories; explicit launcher paths are left untouched. macOS/Windows standard desktop paths remain a fallback when the PATH shim cannot identify the desktop binary.
79
+
80
+ For a managed local Ollama server, `execweave live --open -- ollama serve` owns the public loopback endpoint and relays the real server through an internal loopback port. A later `ollama run`, Ollama SDK request, OpenAI-compatible client, or `curl` started from another terminal can therefore appear in the same ExecWeave semantic stream even though that client is not a child of the `ollama serve` process. ExecWeave prints the active public-to-internal relay mapping; if the public loopback endpoint cannot be safely reserved, the managed run now fails explicitly rather than silently losing conversation capture. Relay mode is deliberately limited to local `localhost` / `127.0.0.1` binds; external, wildcard, and IPv6 exposure is not rewritten. Stopping Live with Ctrl+C still finalizes the run artifacts before returning.
77
81
 
78
82
  Build finalized run artifacts with:
79
83
 
@@ -117,9 +121,9 @@ These are presentation-layer changes. Raw graph evidence is unchanged, and Live,
117
121
  | Claude Code | Yes | native hooks + full-fidelity supplied hook content + exact subagent results when exposed |
118
122
  | OpenAI Codex | Yes | lifecycle hooks + validated rollout transcripts + agent-local task/message/final-response routing |
119
123
  | Google Antigravity / Antigravity CLI | Yes | passive native hooks + validated conversation/subagent routing where exposed |
120
- | Cursor | Yes | native hooks + exact subagent task/summary routing when exposed |
124
+ | Cursor | Yes | native hooks + exact subagent task/summary routing when exposed; Windows bare-launch resolution follows the actual PATH installation |
121
125
  | OpenCode | Yes | project plugin + session/task routing + full-fidelity supplied plugin content |
122
- | Ollama | Yes | `execweave-model-runtime event/exchange/probe --runtime ollama` |
126
+ | Ollama | Yes | managed local `ollama serve` loopback relay + `execweave-model-runtime event/exchange/probe --runtime ollama` |
123
127
  | llama.cpp | Yes | `execweave-model-runtime event/exchange/probe --runtime llamacpp` |
124
128
  | vLLM | Yes | `execweave-model-runtime event/exchange/probe --runtime vllm` |
125
129
  | LM Studio | Only when the local process is launched under ExecWeave | `execweave-model-runtime event/exchange/probe --runtime lmstudio` |
@@ -32,7 +32,7 @@ ExecWeave — source-available, local-first проект наблюдаемос
32
32
  <img src="docs/assets/codex.gif" alt="ExecWeave animated live demo" width="100%">
33
33
  </p>
34
34
 
35
- Этот README описывает **v0.8.9**.
35
+ Этот README описывает **v0.8.11**.
36
36
 
37
37
  ## Почему ExecWeave
38
38
 
@@ -32,7 +32,7 @@ ExecWeave 是一个 source-available、local-first 的可观测性项目,把 A
32
32
  <img src="docs/assets/codex.gif" alt="ExecWeave animated live demo" width="100%">
33
33
  </p>
34
34
 
35
- 本 README 对应 **v0.8.9**。
35
+ 本 README 对应 **v0.8.11**。
36
36
 
37
37
  ## 为什么是 ExecWeave
38
38
 
@@ -32,7 +32,7 @@ ExecWeave 是一個 source-available、local-first 的可觀測性專案,會
32
32
  <img src="docs/assets/codex.gif" alt="ExecWeave animated live demo" width="100%">
33
33
  </p>
34
34
 
35
- 本 README 對應 **v0.8.9**。
35
+ 本 README 對應 **v0.8.11**。
36
36
 
37
37
  ## 為什麼是 ExecWeave
38
38
 
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "execweave"
7
- # ExecWeave v0.8.9 release metadata
8
- version = "0.8.9"
7
+ # ExecWeave v0.8.11 release metadata
8
+ version = "0.8.11"
9
9
  description = "Turn AI-agent runtime behavior into a local interactive execution graph."
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.10"
@@ -1,3 +1,3 @@
1
1
  """ExecWeave runtime graph package."""
2
2
 
3
- __version__ = "0.8.9"
3
+ __version__ = "0.8.11"
@@ -2,12 +2,14 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
  import os
5
+ import socket
6
+ import sys
5
7
  import threading
6
8
  import time
7
9
  from contextlib import contextmanager
8
10
  from dataclasses import dataclass
9
11
  from pathlib import Path
10
- from typing import Iterator
12
+ from typing import Any, Iterator
11
13
  from urllib.error import HTTPError, URLError
12
14
  from urllib.parse import urlsplit, urlunsplit
13
15
  from urllib.request import Request, urlopen
@@ -22,6 +24,18 @@ from .model_runtime import (
22
24
 
23
25
  _SEMANTIC_ENV = "EXECWEAVE_SEMANTIC_SIDECAR"
24
26
  _OLLAMA_DEFAULT_ENDPOINT = "http://127.0.0.1:11434"
27
+ _OLLAMA_INFERENCE_PATHS = frozenset(
28
+ {
29
+ "/api/chat",
30
+ "/api/generate",
31
+ "/api/embed",
32
+ "/api/embeddings",
33
+ "/v1/chat/completions",
34
+ "/v1/completions",
35
+ "/v1/embeddings",
36
+ "/v1/responses",
37
+ }
38
+ )
25
39
  _PROBE_INTERVAL_SECONDS = 0.50
26
40
  _PROBE_TIMEOUT_SECONDS = 0.35
27
41
  _PROBE_STARTUP_GRACE_SECONDS = 0.10
@@ -132,6 +146,45 @@ def _ollama_endpoint_from_environment() -> str | None:
132
146
  return _local_endpoint(hostname, port)
133
147
 
134
148
 
149
+ def _ollama_serve_relay_address() -> tuple[str, int] | None:
150
+ """Return a loopback endpoint ExecWeave can safely own for ``ollama serve``."""
151
+ raw = os.environ.get("OLLAMA_HOST", "").strip()
152
+ if not raw:
153
+ return ("127.0.0.1", 11434)
154
+ candidate = raw if "://" in raw else f"http://{raw}"
155
+ try:
156
+ parsed = urlsplit(candidate)
157
+ port = parsed.port or 11434
158
+ except ValueError:
159
+ return None
160
+ if parsed.scheme != "http" or parsed.username is not None or parsed.password is not None:
161
+ return None
162
+ if parsed.path not in {"", "/"} or parsed.query or parsed.fragment:
163
+ return None
164
+ hostname = parsed.hostname
165
+ # Do not silently narrow wildcard/external/IPv6 exposure to IPv4 loopback.
166
+ if hostname not in {"127.0.0.1", "localhost"} or not (1 <= port <= 65535):
167
+ return None
168
+ return ("127.0.0.1", port)
169
+
170
+
171
+ def _allocate_loopback_port() -> int:
172
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
173
+ sock.bind(("127.0.0.1", 0))
174
+ return int(sock.getsockname()[1])
175
+
176
+
177
+ def _record_ollama_inference_exchange(config: Any, **kwargs: Any) -> None:
178
+ """Record inference exchanges while still relaying every Ollama API route."""
179
+ method = str(kwargs.get("method", "")).upper()
180
+ request_path = str(kwargs.get("request_path", ""))
181
+ if method != "POST" or urlsplit(request_path).path not in _OLLAMA_INFERENCE_PATHS:
182
+ return
183
+ from .http_proxy import record_exchange_fail_open
184
+
185
+ record_exchange_fail_open(config, **kwargs)
186
+
187
+
135
188
  def _lmstudio_post_probe_spec(command: list[str]) -> _ProbeSpec | None:
136
189
  if not _is_lmstudio_server_start(command):
137
190
  return None
@@ -248,12 +301,7 @@ def _run_ollama_probe(
248
301
 
249
302
 
250
303
  def prepare_post_command_specialized_probe(command: list[str]) -> _ProbeSpec | None:
251
- """Prepare an attribution-safe post-command probe for short-lived launch CLIs.
252
-
253
- LM Studio's `lms server start` exits after starting a persistent server. ExecWeave
254
- only prepares this probe when the user supplied an explicit local port and no
255
- compatible API is already observable at that endpoint before launch.
256
- """
304
+ """Prepare an attribution-safe post-command probe for short-lived launch CLIs."""
257
305
  spec = _lmstudio_post_probe_spec(command)
258
306
  if spec is None:
259
307
  return None
@@ -292,40 +340,119 @@ def run_post_command_specialized_probe(
292
340
  time.sleep(_POST_PROBE_RETRY_SECONDS)
293
341
 
294
342
 
295
-
296
343
  @contextmanager
297
- def auto_specialized_launch(command: list[str]) -> Iterator[dict[str, str]]:
298
- """Prepare child-only launch wiring for supported transparent local integrations."""
344
+ def auto_specialized_launch(
345
+ command: list[str],
346
+ *,
347
+ server_relay: bool = False,
348
+ ) -> Iterator[dict[str, str]]:
349
+ """Prepare child launch wiring for supported transparent local integrations.
350
+
351
+ ``server_relay`` is deliberately opt-in so direct library callers preserve the
352
+ existing contract. RuntimeCollector enables it for a real managed server run.
353
+ """
299
354
  environment = dict(os.environ)
300
355
  configured_sidecar = os.environ.get(_SEMANTIC_ENV)
301
- if not configured_sidecar or not _is_ollama_run(command):
302
- yield environment
303
- return
304
- upstream = _ollama_endpoint_from_environment()
305
- if upstream is None:
356
+ wants_run_relay = _is_ollama_run(command)
357
+ wants_serve_relay = server_relay and _is_ollama_serve(command)
358
+ if not configured_sidecar or not (wants_run_relay or wants_serve_relay):
306
359
  yield environment
307
360
  return
308
361
 
309
362
  from .http_proxy import ExecWeaveHTTPProxyServer, ProxyConfig
310
363
 
311
364
  sidecar = Path(configured_sidecar).expanduser().resolve()
365
+
366
+ if wants_run_relay:
367
+ upstream = _ollama_endpoint_from_environment()
368
+ if upstream is None:
369
+ yield environment
370
+ return
371
+ try:
372
+ server = ExecWeaveHTTPProxyServer(
373
+ ("127.0.0.1", 0),
374
+ ProxyConfig(upstream=upstream, sidecar=sidecar, mode="ollama"),
375
+ recorder=_record_ollama_inference_exchange,
376
+ )
377
+ except OSError:
378
+ yield environment
379
+ return
380
+ thread = threading.Thread(
381
+ target=server.serve_forever,
382
+ kwargs={"poll_interval": 0.05},
383
+ name="execweave-ollama-run-relay",
384
+ daemon=True,
385
+ )
386
+ thread.start()
387
+ host, port = server.server_address[:2]
388
+ environment["OLLAMA_HOST"] = f"http://{host}:{port}"
389
+ try:
390
+ yield environment
391
+ finally:
392
+ server.shutdown()
393
+ server.server_close()
394
+ thread.join(timeout=2.0)
395
+ return
396
+
397
+ listen_address = _ollama_serve_relay_address()
398
+ if listen_address is None:
399
+ yield environment
400
+ return
401
+ listen_host, listen_port = listen_address
402
+ public_endpoint = f"http://{listen_host}:{listen_port}"
312
403
  try:
313
- server = ExecWeaveHTTPProxyServer(
314
- ("127.0.0.1", 0),
315
- ProxyConfig(upstream=upstream, sidecar=sidecar, mode="ollama"),
404
+ existing = _get_json(
405
+ f"{public_endpoint}/api/ps",
406
+ timeout=_PROBE_TIMEOUT_SECONDS,
407
+ )
408
+ except _PROBE_ERRORS:
409
+ existing = None
410
+ if isinstance(existing, dict) and isinstance(existing.get("models"), list):
411
+ print(
412
+ "ExecWeave Ollama relay: existing Ollama server detected at "
413
+ f"{public_endpoint}; leaving that server unclaimed.",
414
+ file=sys.stderr,
316
415
  )
317
- except OSError:
318
416
  yield environment
319
417
  return
418
+
419
+ internal_port = _allocate_loopback_port()
420
+ upstream = f"http://127.0.0.1:{internal_port}"
421
+ server: ExecWeaveHTTPProxyServer | None = None
422
+ last_bind_error: OSError | None = None
423
+ for attempt in range(5):
424
+ try:
425
+ server = ExecWeaveHTTPProxyServer(
426
+ (listen_host, listen_port),
427
+ ProxyConfig(upstream=upstream, sidecar=sidecar, mode="ollama"),
428
+ recorder=_record_ollama_inference_exchange,
429
+ )
430
+ break
431
+ except OSError as exc:
432
+ last_bind_error = exc
433
+ if attempt < 4:
434
+ time.sleep(0.05)
435
+ if server is None:
436
+ raise RuntimeError(
437
+ "ExecWeave could not reserve the Ollama endpoint "
438
+ f"{public_endpoint} for transparent conversation capture. "
439
+ "Stop any existing Ollama server using that endpoint or set "
440
+ "OLLAMA_HOST to a free loopback port before starting "
441
+ "`execweave live -- ollama serve`."
442
+ ) from last_bind_error
320
443
  thread = threading.Thread(
321
444
  target=server.serve_forever,
322
445
  kwargs={"poll_interval": 0.05},
323
- name="execweave-ollama-run-relay",
446
+ name="execweave-ollama-serve-relay",
324
447
  daemon=True,
325
448
  )
326
449
  thread.start()
327
- host, port = server.server_address[:2]
328
- environment["OLLAMA_HOST"] = f"http://{host}:{port}"
450
+ environment["OLLAMA_HOST"] = upstream
451
+ print(
452
+ "ExecWeave Ollama relay: "
453
+ f"http://{listen_host}:{listen_port} -> {upstream}",
454
+ file=sys.stderr,
455
+ )
329
456
  try:
330
457
  yield environment
331
458
  finally:
@@ -336,12 +463,7 @@ def auto_specialized_launch(command: list[str]) -> Iterator[dict[str, str]]:
336
463
 
337
464
  @contextmanager
338
465
  def auto_specialized_probe(command: list[str]) -> Iterator[None]:
339
- """Run supported local specialized probes without affecting command execution.
340
-
341
- The probe activates only when a caller supplies ExecWeave's per-run semantic
342
- sidecar environment variable. Auto-probing is limited to known local server
343
- launch commands and loopback endpoints. All failures are fail-open.
344
- """
466
+ """Run supported local specialized probes without affecting command execution."""
345
467
  configured_sidecar = os.environ.get(_SEMANTIC_ENV)
346
468
  spec = _probe_spec(command)
347
469
  if not configured_sidecar or spec is None:
@@ -9,6 +9,7 @@ from typing import Iterable
9
9
 
10
10
  import psutil
11
11
 
12
+ from . import __version__
12
13
  from .auto_specialized import (
13
14
  auto_specialized_launch,
14
15
  auto_specialized_probe,
@@ -139,6 +140,7 @@ class RuntimeCollector:
139
140
  "command": command,
140
141
  "cwd": str(self.watch_root),
141
142
  "backend": self.backend_name,
143
+ "execweave_version": __version__,
142
144
  },
143
145
  )
144
146
  self.sink.emit(
@@ -148,7 +150,11 @@ class RuntimeCollector:
148
150
  relation="STARTED_SESSION",
149
151
  source=agent,
150
152
  target=session,
151
- attributes={"collector_pid": os.getpid(), "backend": self.backend_name},
153
+ attributes={
154
+ "collector_pid": os.getpid(),
155
+ "backend": self.backend_name,
156
+ "execweave_version": __version__,
157
+ },
152
158
  )
153
159
  )
154
160
 
@@ -166,31 +172,42 @@ class RuntimeCollector:
166
172
 
167
173
  process: subprocess.Popen[bytes] | None = None
168
174
  return_code = 1
175
+ interrupted = False
169
176
  post_command_probe = prepare_post_command_specialized_probe(command)
170
177
  try:
171
- with auto_specialized_launch(command) as launch_environment:
172
- process = subprocess.Popen(
173
- launch_command,
174
- cwd=str(self.watch_root),
175
- env=launch_environment,
176
- )
177
- root = psutil.Process(process.pid)
178
- snapshot = _safe_process_snapshot(root)
179
- if snapshot is not None:
180
- self._record_process_start(snapshot, parent=session, relation="LAUNCHED")
178
+ try:
179
+ with auto_specialized_launch(
180
+ command,
181
+ server_relay=True,
182
+ ) as launch_environment:
183
+ process = subprocess.Popen(
184
+ launch_command,
185
+ cwd=str(self.watch_root),
186
+ env=launch_environment,
187
+ )
188
+ root = psutil.Process(process.pid)
189
+ snapshot = _safe_process_snapshot(root)
190
+ if snapshot is not None:
191
+ self._record_process_start(snapshot, parent=session, relation="LAUNCHED")
192
+
193
+ with auto_specialized_probe(command):
194
+ while process.poll() is None:
195
+ self._sample_process_tree(root)
196
+ time.sleep(self.poll_interval)
181
197
 
182
- with auto_specialized_probe(command):
183
- while process.poll() is None:
184
198
  self._sample_process_tree(root)
185
- time.sleep(self.poll_interval)
186
-
187
- self._sample_process_tree(root)
188
- self._mark_disappeared_processes(set())
189
- return_code = int(process.returncode or 0)
190
- run_post_command_specialized_probe(
191
- post_command_probe,
192
- return_code=return_code,
193
- )
199
+ self._mark_disappeared_processes(set())
200
+ return_code = int(process.returncode or 0)
201
+ except KeyboardInterrupt:
202
+ interrupted = True
203
+ return_code = 130
204
+ if process is not None:
205
+ self._terminate_process_tree(process)
206
+ if not interrupted:
207
+ run_post_command_specialized_probe(
208
+ post_command_probe,
209
+ return_code=return_code,
210
+ )
194
211
  return return_code
195
212
  finally:
196
213
  if watcher is not None:
@@ -205,10 +222,53 @@ class RuntimeCollector:
205
222
  "return_code": return_code,
206
223
  "root_pid": process.pid if process is not None else None,
207
224
  "backend": self.backend_name,
225
+ "interrupted": interrupted,
226
+ "execweave_version": __version__,
208
227
  },
209
228
  )
210
229
  )
211
230
 
231
+ @staticmethod
232
+ def _terminate_process_tree(process: subprocess.Popen[bytes]) -> None:
233
+ descendants: list[psutil.Process] = []
234
+ try:
235
+ root = psutil.Process(process.pid)
236
+ descendants = root.children(recursive=True)
237
+ except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
238
+ pass
239
+
240
+ for child in reversed(descendants):
241
+ try:
242
+ child.terminate()
243
+ except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
244
+ pass
245
+
246
+ if process.poll() is None:
247
+ try:
248
+ process.terminate()
249
+ except OSError:
250
+ pass
251
+
252
+ if descendants:
253
+ _, alive = psutil.wait_procs(descendants, timeout=2.0)
254
+ for child in alive:
255
+ try:
256
+ child.kill()
257
+ except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
258
+ pass
259
+
260
+ try:
261
+ process.wait(timeout=2.0)
262
+ except subprocess.TimeoutExpired:
263
+ try:
264
+ process.kill()
265
+ except OSError:
266
+ return
267
+ try:
268
+ process.wait(timeout=2.0)
269
+ except subprocess.TimeoutExpired:
270
+ pass
271
+
212
272
  def _sample_process_tree(self, root: psutil.Process) -> None:
213
273
  processes: list[psutil.Process] = []
214
274
  try:
@@ -37,7 +37,35 @@ def _cursor_desktop_candidates() -> list[Path]:
37
37
  return []
38
38
 
39
39
 
40
- def _resolve_cursor_desktop() -> str | None:
40
+ def _prefer_cursor_desktop_launcher() -> bool:
41
+ return os.name == "nt"
42
+
43
+
44
+ def _cursor_desktop_from_launcher(launcher: str | None) -> str | None:
45
+ """Resolve Cursor.exe beside a VS Code-style PATH shim."""
46
+ if not launcher:
47
+ return None
48
+ path = Path(launcher).expanduser()
49
+ bin_dir = path.parent
50
+ app_dir = bin_dir.parent
51
+ resources_dir = app_dir.parent
52
+ install_root = resources_dir.parent
53
+ if (
54
+ bin_dir.name.lower() != "bin"
55
+ or app_dir.name.lower() != "app"
56
+ or resources_dir.name.lower() != "resources"
57
+ ):
58
+ return None
59
+ candidate = install_root / "Cursor.exe"
60
+ if candidate.is_file():
61
+ return str(candidate.resolve())
62
+ return None
63
+
64
+
65
+ def _resolve_cursor_desktop(*, path_launcher: str | None = None) -> str | None:
66
+ derived = _cursor_desktop_from_launcher(path_launcher)
67
+ if derived is not None:
68
+ return derived
41
69
  for candidate in _cursor_desktop_candidates():
42
70
  if candidate.is_file():
43
71
  return str(candidate.resolve())
@@ -54,16 +82,21 @@ def _resolve_executable(executable: str, *, path: str | None = None) -> str:
54
82
  raise FileNotFoundError(f"command executable not found: {executable!r}")
55
83
  resolved = str(candidate.resolve())
56
84
  else:
57
- resolved = shutil.which(executable, path=path)
58
- if resolved is None and executable.lower() == "cursor":
59
- resolved = _resolve_cursor_desktop()
85
+ path_launcher = shutil.which(executable, path=path)
86
+ if executable.lower() == "cursor" and _prefer_cursor_desktop_launcher():
87
+ resolved = _resolve_cursor_desktop(path_launcher=path_launcher) or path_launcher
88
+ else:
89
+ resolved = path_launcher
90
+ if resolved is None and executable.lower() == "cursor":
91
+ resolved = _resolve_cursor_desktop()
60
92
  if resolved is None and executable.lower() == "antigravity":
61
93
  resolved = shutil.which("agy", path=path)
62
94
  if resolved is None:
63
95
  detail = ""
64
96
  if executable.lower() == "cursor":
65
97
  detail = (
66
- "; ExecWeave also checked the standard Cursor desktop-app install paths"
98
+ "; ExecWeave also checked the Cursor desktop binary beside the PATH "
99
+ "launcher and the standard desktop-app install paths"
67
100
  )
68
101
  elif executable.lower() == "antigravity":
69
102
  detail = "; the current Antigravity CLI executable is 'agy'"
@@ -83,9 +116,15 @@ def resolve_launch_command(command: list[str], *, path: str | None = None) -> li
83
116
  ExecWeave launches commands without ``shell=True``. Normal executables use PATH
84
117
  lookup. On Windows, PATHEXT keeps npm-style ``.cmd``/``.bat`` launchers working.
85
118
 
86
- ``cursor`` additionally falls back to the standard macOS/Windows desktop app
87
- binaries when no CLI launcher exists on PATH. ``antigravity`` is accepted as a
88
- friendly alias for Google's current Antigravity CLI executable, ``agy``.
119
+ Bare ``cursor`` on Windows prefers the desktop application binary. ExecWeave
120
+ first derives ``Cursor.exe`` from a VS Code-style PATH shim such as
121
+ ``<install>/resources/app/bin/cursor.cmd`` and then checks standard desktop
122
+ install paths. This keeps the GUI process and provider hooks in the ExecWeave
123
+ launch environment instead of treating a short-lived CLI shim as the observed
124
+ application lifetime. Explicit launcher paths are never rewritten.
125
+
126
+ ``antigravity`` is accepted as a friendly alias for Google's current
127
+ Antigravity CLI executable, ``agy``.
89
128
 
90
129
  An explicitly supplied PowerShell ``.ps1`` file is launched through pwsh or
91
130
  Windows PowerShell because CreateProcess cannot execute a PowerShell script by
@@ -653,7 +653,10 @@ class StraceRuntimeCollector:
653
653
  ]
654
654
  return_code = 1
655
655
  try:
656
- with auto_specialized_launch(command) as launch_environment:
656
+ with auto_specialized_launch(
657
+ command,
658
+ server_relay=True,
659
+ ) as launch_environment:
657
660
  completed = subprocess.run(
658
661
  strace_command,
659
662
  cwd=str(self.watch_root),