execweave 0.8.9__tar.gz → 0.8.10__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 (505) hide show
  1. {execweave-0.8.9 → execweave-0.8.10}/PKG-INFO +9 -5
  2. {execweave-0.8.9 → execweave-0.8.10}/README.de.md +1 -1
  3. {execweave-0.8.9 → execweave-0.8.10}/README.fr.md +1 -1
  4. {execweave-0.8.9 → execweave-0.8.10}/README.ja.md +1 -1
  5. {execweave-0.8.9 → execweave-0.8.10}/README.ko.md +1 -1
  6. {execweave-0.8.9 → execweave-0.8.10}/README.md +8 -4
  7. {execweave-0.8.9 → execweave-0.8.10}/README.ru.md +1 -1
  8. {execweave-0.8.9 → execweave-0.8.10}/README.zh-CN.md +1 -1
  9. {execweave-0.8.9 → execweave-0.8.10}/README.zh-TW.md +1 -1
  10. {execweave-0.8.9 → execweave-0.8.10}/pyproject.toml +2 -2
  11. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/__init__.py +1 -1
  12. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/auto_specialized.py +112 -25
  13. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/collector.py +1 -1
  14. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/command.py +47 -8
  15. execweave-0.8.10/tests/test_cursor_ollama_session_lifecycle.py +176 -0
  16. {execweave-0.8.9 → execweave-0.8.10}/tests/test_v069_dashboard_release.py +3 -3
  17. {execweave-0.8.9 → execweave-0.8.10}/.github/workflows/ci.yml +0 -0
  18. {execweave-0.8.9 → execweave-0.8.10}/.github/workflows/cleanup-workflow-history.yml +0 -0
  19. {execweave-0.8.9 → execweave-0.8.10}/.github/workflows/i18n.yml +0 -0
  20. {execweave-0.8.9 → execweave-0.8.10}/.github/workflows/package-benchmark.yml +0 -0
  21. {execweave-0.8.9 → execweave-0.8.10}/.github/workflows/package-smoke.yml +0 -0
  22. {execweave-0.8.9 → execweave-0.8.10}/.github/workflows/provider-capability-stage-integrity.yml +0 -0
  23. {execweave-0.8.9 → execweave-0.8.10}/.github/workflows/provider-dashboard-contract.yml +0 -0
  24. {execweave-0.8.9 → execweave-0.8.10}/.github/workflows/publish.yml +0 -0
  25. {execweave-0.8.9 → execweave-0.8.10}/.github/workflows/scalability.yml +0 -0
  26. {execweave-0.8.9 → execweave-0.8.10}/.github/workflows/viewer-agent-isolation.yml +0 -0
  27. {execweave-0.8.9 → execweave-0.8.10}/.github/workflows/wheel-smoke.yml +0 -0
  28. {execweave-0.8.9 → execweave-0.8.10}/.github/workflows/windows-launcher.yml +0 -0
  29. {execweave-0.8.9 → execweave-0.8.10}/.gitignore +0 -0
  30. {execweave-0.8.9 → execweave-0.8.10}/LICENSE +0 -0
  31. {execweave-0.8.9 → execweave-0.8.10}/benchmarks/phase1_overhead.py +0 -0
  32. {execweave-0.8.9 → execweave-0.8.10}/docs/antigravity-hooks.md +0 -0
  33. {execweave-0.8.9 → execweave-0.8.10}/docs/assets/codex.gif +0 -0
  34. {execweave-0.8.9 → execweave-0.8.10}/docs/benchmarks/README.md +0 -0
  35. {execweave-0.8.9 → execweave-0.8.10}/docs/benchmarks/v0.6.0-github-actions.json +0 -0
  36. {execweave-0.8.9 → execweave-0.8.10}/docs/benchmarks/v0.6.0-github-actions.svg +0 -0
  37. {execweave-0.8.9 → execweave-0.8.10}/docs/claude-code-hooks.de.md +0 -0
  38. {execweave-0.8.9 → execweave-0.8.10}/docs/claude-code-hooks.fr.md +0 -0
  39. {execweave-0.8.9 → execweave-0.8.10}/docs/claude-code-hooks.ja.md +0 -0
  40. {execweave-0.8.9 → execweave-0.8.10}/docs/claude-code-hooks.ko.md +0 -0
  41. {execweave-0.8.9 → execweave-0.8.10}/docs/claude-code-hooks.md +0 -0
  42. {execweave-0.8.9 → execweave-0.8.10}/docs/claude-code-hooks.ru.md +0 -0
  43. {execweave-0.8.9 → execweave-0.8.10}/docs/claude-code-hooks.zh-CN.md +0 -0
  44. {execweave-0.8.9 → execweave-0.8.10}/docs/claude-code-hooks.zh-TW.md +0 -0
  45. {execweave-0.8.9 → execweave-0.8.10}/docs/codex-hooks.de.md +0 -0
  46. {execweave-0.8.9 → execweave-0.8.10}/docs/codex-hooks.fr.md +0 -0
  47. {execweave-0.8.9 → execweave-0.8.10}/docs/codex-hooks.ja.md +0 -0
  48. {execweave-0.8.9 → execweave-0.8.10}/docs/codex-hooks.ko.md +0 -0
  49. {execweave-0.8.9 → execweave-0.8.10}/docs/codex-hooks.md +0 -0
  50. {execweave-0.8.9 → execweave-0.8.10}/docs/codex-hooks.ru.md +0 -0
  51. {execweave-0.8.9 → execweave-0.8.10}/docs/codex-hooks.zh-CN.md +0 -0
  52. {execweave-0.8.9 → execweave-0.8.10}/docs/codex-hooks.zh-TW.md +0 -0
  53. {execweave-0.8.9 → execweave-0.8.10}/docs/cursor-hooks.de.md +0 -0
  54. {execweave-0.8.9 → execweave-0.8.10}/docs/cursor-hooks.fr.md +0 -0
  55. {execweave-0.8.9 → execweave-0.8.10}/docs/cursor-hooks.ja.md +0 -0
  56. {execweave-0.8.9 → execweave-0.8.10}/docs/cursor-hooks.ko.md +0 -0
  57. {execweave-0.8.9 → execweave-0.8.10}/docs/cursor-hooks.md +0 -0
  58. {execweave-0.8.9 → execweave-0.8.10}/docs/cursor-hooks.ru.md +0 -0
  59. {execweave-0.8.9 → execweave-0.8.10}/docs/cursor-hooks.zh-CN.md +0 -0
  60. {execweave-0.8.9 → execweave-0.8.10}/docs/cursor-hooks.zh-TW.md +0 -0
  61. {execweave-0.8.9 → execweave-0.8.10}/docs/evidence-grades.de.md +0 -0
  62. {execweave-0.8.9 → execweave-0.8.10}/docs/evidence-grades.fr.md +0 -0
  63. {execweave-0.8.9 → execweave-0.8.10}/docs/evidence-grades.ja.md +0 -0
  64. {execweave-0.8.9 → execweave-0.8.10}/docs/evidence-grades.ko.md +0 -0
  65. {execweave-0.8.9 → execweave-0.8.10}/docs/evidence-grades.md +0 -0
  66. {execweave-0.8.9 → execweave-0.8.10}/docs/evidence-grades.ru.md +0 -0
  67. {execweave-0.8.9 → execweave-0.8.10}/docs/evidence-grades.zh-CN.md +0 -0
  68. {execweave-0.8.9 → execweave-0.8.10}/docs/evidence-grades.zh-TW.md +0 -0
  69. {execweave-0.8.9 → execweave-0.8.10}/docs/inference-gateway.de.md +0 -0
  70. {execweave-0.8.9 → execweave-0.8.10}/docs/inference-gateway.fr.md +0 -0
  71. {execweave-0.8.9 → execweave-0.8.10}/docs/inference-gateway.ja.md +0 -0
  72. {execweave-0.8.9 → execweave-0.8.10}/docs/inference-gateway.ko.md +0 -0
  73. {execweave-0.8.9 → execweave-0.8.10}/docs/inference-gateway.md +0 -0
  74. {execweave-0.8.9 → execweave-0.8.10}/docs/inference-gateway.ru.md +0 -0
  75. {execweave-0.8.9 → execweave-0.8.10}/docs/inference-gateway.zh-CN.md +0 -0
  76. {execweave-0.8.9 → execweave-0.8.10}/docs/inference-gateway.zh-TW.md +0 -0
  77. {execweave-0.8.9 → execweave-0.8.10}/docs/internal/provider-capability-matrix.md +0 -0
  78. {execweave-0.8.9 → execweave-0.8.10}/docs/live-graph.de.md +0 -0
  79. {execweave-0.8.9 → execweave-0.8.10}/docs/live-graph.fr.md +0 -0
  80. {execweave-0.8.9 → execweave-0.8.10}/docs/live-graph.ja.md +0 -0
  81. {execweave-0.8.9 → execweave-0.8.10}/docs/live-graph.ko.md +0 -0
  82. {execweave-0.8.9 → execweave-0.8.10}/docs/live-graph.md +0 -0
  83. {execweave-0.8.9 → execweave-0.8.10}/docs/live-graph.ru.md +0 -0
  84. {execweave-0.8.9 → execweave-0.8.10}/docs/live-graph.zh-CN.md +0 -0
  85. {execweave-0.8.9 → execweave-0.8.10}/docs/live-graph.zh-TW.md +0 -0
  86. {execweave-0.8.9 → execweave-0.8.10}/docs/model-runtime.de.md +0 -0
  87. {execweave-0.8.9 → execweave-0.8.10}/docs/model-runtime.fr.md +0 -0
  88. {execweave-0.8.9 → execweave-0.8.10}/docs/model-runtime.ja.md +0 -0
  89. {execweave-0.8.9 → execweave-0.8.10}/docs/model-runtime.ko.md +0 -0
  90. {execweave-0.8.9 → execweave-0.8.10}/docs/model-runtime.md +0 -0
  91. {execweave-0.8.9 → execweave-0.8.10}/docs/model-runtime.ru.md +0 -0
  92. {execweave-0.8.9 → execweave-0.8.10}/docs/model-runtime.zh-CN.md +0 -0
  93. {execweave-0.8.9 → execweave-0.8.10}/docs/model-runtime.zh-TW.md +0 -0
  94. {execweave-0.8.9 → execweave-0.8.10}/docs/opencode-plugin.de.md +0 -0
  95. {execweave-0.8.9 → execweave-0.8.10}/docs/opencode-plugin.fr.md +0 -0
  96. {execweave-0.8.9 → execweave-0.8.10}/docs/opencode-plugin.ja.md +0 -0
  97. {execweave-0.8.9 → execweave-0.8.10}/docs/opencode-plugin.ko.md +0 -0
  98. {execweave-0.8.9 → execweave-0.8.10}/docs/opencode-plugin.md +0 -0
  99. {execweave-0.8.9 → execweave-0.8.10}/docs/opencode-plugin.ru.md +0 -0
  100. {execweave-0.8.9 → execweave-0.8.10}/docs/opencode-plugin.zh-CN.md +0 -0
  101. {execweave-0.8.9 → execweave-0.8.10}/docs/opencode-plugin.zh-TW.md +0 -0
  102. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-1-runtime-collection.de.md +0 -0
  103. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-1-runtime-collection.fr.md +0 -0
  104. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-1-runtime-collection.ja.md +0 -0
  105. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-1-runtime-collection.ko.md +0 -0
  106. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-1-runtime-collection.md +0 -0
  107. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-1-runtime-collection.ru.md +0 -0
  108. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-1-runtime-collection.zh-CN.md +0 -0
  109. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-1-runtime-collection.zh-TW.md +0 -0
  110. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-2-execution-graph.de.md +0 -0
  111. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-2-execution-graph.fr.md +0 -0
  112. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-2-execution-graph.ja.md +0 -0
  113. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-2-execution-graph.ko.md +0 -0
  114. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-2-execution-graph.md +0 -0
  115. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-2-execution-graph.ru.md +0 -0
  116. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-2-execution-graph.zh-CN.md +0 -0
  117. {execweave-0.8.9 → execweave-0.8.10}/docs/phase-2-execution-graph.zh-TW.md +0 -0
  118. {execweave-0.8.9 → execweave-0.8.10}/docs/remaining-provider-audit-v0.8.7.md +0 -0
  119. {execweave-0.8.9 → execweave-0.8.10}/docs/rule-packs.de.md +0 -0
  120. {execweave-0.8.9 → execweave-0.8.10}/docs/rule-packs.fr.md +0 -0
  121. {execweave-0.8.9 → execweave-0.8.10}/docs/rule-packs.ja.md +0 -0
  122. {execweave-0.8.9 → execweave-0.8.10}/docs/rule-packs.ko.md +0 -0
  123. {execweave-0.8.9 → execweave-0.8.10}/docs/rule-packs.md +0 -0
  124. {execweave-0.8.9 → execweave-0.8.10}/docs/rule-packs.ru.md +0 -0
  125. {execweave-0.8.9 → execweave-0.8.10}/docs/rule-packs.zh-CN.md +0 -0
  126. {execweave-0.8.9 → execweave-0.8.10}/docs/rule-packs.zh-TW.md +0 -0
  127. {execweave-0.8.9 → execweave-0.8.10}/docs/run-integrity.de.md +0 -0
  128. {execweave-0.8.9 → execweave-0.8.10}/docs/run-integrity.fr.md +0 -0
  129. {execweave-0.8.9 → execweave-0.8.10}/docs/run-integrity.ja.md +0 -0
  130. {execweave-0.8.9 → execweave-0.8.10}/docs/run-integrity.ko.md +0 -0
  131. {execweave-0.8.9 → execweave-0.8.10}/docs/run-integrity.md +0 -0
  132. {execweave-0.8.9 → execweave-0.8.10}/docs/run-integrity.ru.md +0 -0
  133. {execweave-0.8.9 → execweave-0.8.10}/docs/run-integrity.zh-CN.md +0 -0
  134. {execweave-0.8.9 → execweave-0.8.10}/docs/run-integrity.zh-TW.md +0 -0
  135. {execweave-0.8.9 → execweave-0.8.10}/docs/runtime-threat-model.de.md +0 -0
  136. {execweave-0.8.9 → execweave-0.8.10}/docs/runtime-threat-model.fr.md +0 -0
  137. {execweave-0.8.9 → execweave-0.8.10}/docs/runtime-threat-model.ja.md +0 -0
  138. {execweave-0.8.9 → execweave-0.8.10}/docs/runtime-threat-model.ko.md +0 -0
  139. {execweave-0.8.9 → execweave-0.8.10}/docs/runtime-threat-model.md +0 -0
  140. {execweave-0.8.9 → execweave-0.8.10}/docs/runtime-threat-model.ru.md +0 -0
  141. {execweave-0.8.9 → execweave-0.8.10}/docs/runtime-threat-model.zh-CN.md +0 -0
  142. {execweave-0.8.9 → execweave-0.8.10}/docs/runtime-threat-model.zh-TW.md +0 -0
  143. {execweave-0.8.9 → execweave-0.8.10}/docs/security-analysis.de.md +0 -0
  144. {execweave-0.8.9 → execweave-0.8.10}/docs/security-analysis.fr.md +0 -0
  145. {execweave-0.8.9 → execweave-0.8.10}/docs/security-analysis.ja.md +0 -0
  146. {execweave-0.8.9 → execweave-0.8.10}/docs/security-analysis.ko.md +0 -0
  147. {execweave-0.8.9 → execweave-0.8.10}/docs/security-analysis.md +0 -0
  148. {execweave-0.8.9 → execweave-0.8.10}/docs/security-analysis.ru.md +0 -0
  149. {execweave-0.8.9 → execweave-0.8.10}/docs/security-analysis.zh-CN.md +0 -0
  150. {execweave-0.8.9 → execweave-0.8.10}/docs/security-analysis.zh-TW.md +0 -0
  151. {execweave-0.8.9 → execweave-0.8.10}/docs/semantic-telemetry.de.md +0 -0
  152. {execweave-0.8.9 → execweave-0.8.10}/docs/semantic-telemetry.fr.md +0 -0
  153. {execweave-0.8.9 → execweave-0.8.10}/docs/semantic-telemetry.ja.md +0 -0
  154. {execweave-0.8.9 → execweave-0.8.10}/docs/semantic-telemetry.ko.md +0 -0
  155. {execweave-0.8.9 → execweave-0.8.10}/docs/semantic-telemetry.md +0 -0
  156. {execweave-0.8.9 → execweave-0.8.10}/docs/semantic-telemetry.ru.md +0 -0
  157. {execweave-0.8.9 → execweave-0.8.10}/docs/semantic-telemetry.zh-CN.md +0 -0
  158. {execweave-0.8.9 → execweave-0.8.10}/docs/semantic-telemetry.zh-TW.md +0 -0
  159. {execweave-0.8.9 → execweave-0.8.10}/docs/v0.6.5-hardening-decisions.md +0 -0
  160. {execweave-0.8.9 → execweave-0.8.10}/docs/v0.8.3-graph-ergonomics.md +0 -0
  161. {execweave-0.8.9 → execweave-0.8.10}/scripts/audit_i18n_parity.py +0 -0
  162. {execweave-0.8.9 → execweave-0.8.10}/scripts/check_claude_hook.py +0 -0
  163. {execweave-0.8.9 → execweave-0.8.10}/scripts/check_claude_record_graph.py +0 -0
  164. {execweave-0.8.9 → execweave-0.8.10}/scripts/check_codex_hook.py +0 -0
  165. {execweave-0.8.9 → execweave-0.8.10}/scripts/check_conversation_records.py +0 -0
  166. {execweave-0.8.9 → execweave-0.8.10}/scripts/check_correlation_graph.py +0 -0
  167. {execweave-0.8.9 → execweave-0.8.10}/scripts/check_inference_gateway_cli.py +0 -0
  168. {execweave-0.8.9 → execweave-0.8.10}/scripts/check_model_runtime_cli.py +0 -0
  169. {execweave-0.8.9 → execweave-0.8.10}/scripts/check_openai_compatible_cli.py +0 -0
  170. {execweave-0.8.9 → execweave-0.8.10}/scripts/check_release_stage_integrity.py +0 -0
  171. {execweave-0.8.9 → execweave-0.8.10}/scripts/check_semantic_graph.py +0 -0
  172. {execweave-0.8.9 → execweave-0.8.10}/scripts/check_viewer_js.py +0 -0
  173. {execweave-0.8.9 → execweave-0.8.10}/scripts/check_wheel_install.py +0 -0
  174. {execweave-0.8.9 → execweave-0.8.10}/scripts/check_windows_launchers.py +0 -0
  175. {execweave-0.8.9 → execweave-0.8.10}/scripts/emit_claude_hook_smoke.py +0 -0
  176. {execweave-0.8.9 → execweave-0.8.10}/scripts/emit_codex_hook_smoke.py +0 -0
  177. {execweave-0.8.9 → execweave-0.8.10}/scripts/emit_cursor_hook_smoke.py +0 -0
  178. {execweave-0.8.9 → execweave-0.8.10}/scripts/emit_opencode_plugin_smoke.py +0 -0
  179. {execweave-0.8.9 → execweave-0.8.10}/scripts/make_semantic_smoke.py +0 -0
  180. {execweave-0.8.9 → execweave-0.8.10}/scripts/probe_provider_capability.py +0 -0
  181. {execweave-0.8.9 → execweave-0.8.10}/scripts/sync_i18n_nav.py +0 -0
  182. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/__main__.py +0 -0
  183. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/_conversation_records_core.py +0 -0
  184. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/agent_bootstrap.py +0 -0
  185. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/agent_topology.py +0 -0
  186. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/agent_trace.py +0 -0
  187. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/agy_preview_sanitize.py +0 -0
  188. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/analysis.py +0 -0
  189. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/anthropic.py +0 -0
  190. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/anthropic_cli.py +0 -0
  191. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/anthropic_full_fidelity.py +0 -0
  192. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/antigravity_adapter.py +0 -0
  193. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/antigravity_adapter_base.py +0 -0
  194. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/antigravity_full_fidelity.py +0 -0
  195. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/antigravity_full_fidelity_base.py +0 -0
  196. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/antigravity_full_fidelity_collaboration_base.py +0 -0
  197. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/antigravity_hook_cli.py +0 -0
  198. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/antigravity_record.py +0 -0
  199. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/antigravity_subagent_linkage.py +0 -0
  200. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/antigravity_trace_capability.py +0 -0
  201. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/backends.py +0 -0
  202. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/benchmark.py +0 -0
  203. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/claude_adapter.py +0 -0
  204. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/claude_child_transcript.py +0 -0
  205. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/claude_delegation.py +0 -0
  206. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/claude_full_fidelity.py +0 -0
  207. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/claude_hook_cli.py +0 -0
  208. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/claude_hook_contract.py +0 -0
  209. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/claude_model_observer.py +0 -0
  210. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/claude_record.py +0 -0
  211. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/cli.py +0 -0
  212. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/codex_adapter.py +0 -0
  213. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/codex_conversation.py +0 -0
  214. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/codex_full_fidelity.py +0 -0
  215. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/codex_hook_cli.py +0 -0
  216. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/codex_hook_lifecycle.py +0 -0
  217. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/codex_message_diagnostics.py +0 -0
  218. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/codex_message_transport_diagnostics.py +0 -0
  219. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/codex_record.py +0 -0
  220. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/codex_rollout_structures.py +0 -0
  221. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/codex_rollout_trace.py +0 -0
  222. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/codex_rollout_trace_base.py +0 -0
  223. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/content_evidence.py +0 -0
  224. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/content_store.py +0 -0
  225. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_archive.py +0 -0
  226. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_message_identity.py +0 -0
  227. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_preview.py +0 -0
  228. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_preview_antigravity.py +0 -0
  229. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_preview_claude.py +0 -0
  230. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_preview_codex.py +0 -0
  231. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_preview_common.py +0 -0
  232. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_preview_generic.py +0 -0
  233. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_preview_lines.py +0 -0
  234. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_preview_transcript.py +0 -0
  235. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_records.py +0 -0
  236. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_records_antigravity.py +0 -0
  237. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_records_codex.py +0 -0
  238. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_records_common.py +0 -0
  239. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/conversation_records_ollama.py +0 -0
  240. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/correlation.py +0 -0
  241. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/cursor_adapter.py +0 -0
  242. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/cursor_delegation.py +0 -0
  243. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/cursor_delegation_base.py +0 -0
  244. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/cursor_full_fidelity.py +0 -0
  245. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/cursor_hook_cli.py +0 -0
  246. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/cursor_hook_contract.py +0 -0
  247. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/cursor_record.py +0 -0
  248. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/dashboard_shell.py +0 -0
  249. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/entry.py +0 -0
  250. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/evidence_availability.py +0 -0
  251. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/evidence_grade.py +0 -0
  252. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/fidelity.py +0 -0
  253. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/filesystem.py +0 -0
  254. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/focus.py +0 -0
  255. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/graph.py +0 -0
  256. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/graph_ops.py +0 -0
  257. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/http_proxy.py +0 -0
  258. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/http_proxy_cli.py +0 -0
  259. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/inference_gateway.py +0 -0
  260. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/inference_gateway_cli.py +0 -0
  261. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/inference_gateway_full_fidelity.py +0 -0
  262. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/inference_identity.py +0 -0
  263. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/inference_identity_cli.py +0 -0
  264. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/integrity.py +0 -0
  265. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/integrity_cli.py +0 -0
  266. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/litellm_callback.py +0 -0
  267. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/litellm_callback_cli.py +0 -0
  268. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/live.py +0 -0
  269. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/live_core.py +0 -0
  270. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/live_view.py +0 -0
  271. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/live_view_extra_style.py +0 -0
  272. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/live_view_markup.py +0 -0
  273. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/live_view_process_layout.py +0 -0
  274. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/live_view_readability.py +0 -0
  275. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/live_view_script_a.py +0 -0
  276. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/live_view_script_b.py +0 -0
  277. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/live_view_script_c.py +0 -0
  278. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/live_view_script_d.py +0 -0
  279. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/live_view_style.py +0 -0
  280. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/model_runtime.py +0 -0
  281. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/model_runtime_cli.py +0 -0
  282. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/model_runtime_full_fidelity.py +0 -0
  283. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/openai_compatible.py +0 -0
  284. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/openai_compatible_cli.py +0 -0
  285. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/openai_compatible_full_fidelity.py +0 -0
  286. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/opencode_adapter.py +0 -0
  287. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/opencode_event_contract.py +0 -0
  288. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/opencode_full_fidelity.py +0 -0
  289. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/opencode_hook_cli.py +0 -0
  290. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/opencode_plugin_cli.py +0 -0
  291. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/opencode_record.py +0 -0
  292. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/opencode_task_linkage.py +0 -0
  293. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/overhead_benchmark.py +0 -0
  294. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/provider_capability.py +0 -0
  295. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/provider_lifecycle.py +0 -0
  296. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/provider_record.py +0 -0
  297. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/rule_pack.py +0 -0
  298. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/rule_pack_cli.py +0 -0
  299. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/scalability_benchmark.py +0 -0
  300. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/schema.py +0 -0
  301. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/scope.py +0 -0
  302. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/semantic.py +0 -0
  303. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/sink.py +0 -0
  304. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/strace_backend.py +0 -0
  305. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/stream_assembly.py +0 -0
  306. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/theme.py +0 -0
  307. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/top.py +0 -0
  308. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/top_cli.py +0 -0
  309. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/validate.py +0 -0
  310. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/vendor/dagre.min.js +0 -0
  311. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/view_cli.py +0 -0
  312. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer.py +0 -0
  313. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_agent_panel.py +0 -0
  314. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_agent_panel_antigravity.py +0 -0
  315. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_agent_panel_claude.py +0 -0
  316. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_agent_panel_codex.py +0 -0
  317. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_agent_panel_cursor.py +0 -0
  318. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_agent_panel_default.py +0 -0
  319. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_agent_panel_ollama.py +0 -0
  320. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_agent_panel_opencode.py +0 -0
  321. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_agent_panel_registry.py +0 -0
  322. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_content_inspector.py +0 -0
  323. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_dashboard_clean.py +0 -0
  324. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_dashboard_focus.py +0 -0
  325. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_dashboard_hardening.py +0 -0
  326. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_dashboard_hardening_v2.py +0 -0
  327. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_external_endpoints.py +0 -0
  328. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_limits.py +0 -0
  329. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_live_layout.py +0 -0
  330. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_projection.py +0 -0
  331. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/viewer_projection_base.py +0 -0
  332. {execweave-0.8.9 → execweave-0.8.10}/src/execweave/workflow.py +0 -0
  333. {execweave-0.8.9 → execweave-0.8.10}/tests/dashboard_readability_fixture.py +0 -0
  334. {execweave-0.8.9 → execweave-0.8.10}/tests/fixtures/codex_multi_agent/PROVENANCE.md +0 -0
  335. {execweave-0.8.9 → execweave-0.8.10}/tests/fixtures/codex_multi_agent/hook-payloads.json +0 -0
  336. {execweave-0.8.9 → execweave-0.8.10}/tests/fixtures/codex_multi_agent/rollout-main.jsonl +0 -0
  337. {execweave-0.8.9 → execweave-0.8.10}/tests/fixtures/hooks/README.md +0 -0
  338. {execweave-0.8.9 → execweave-0.8.10}/tests/fixtures/hooks/claude.json +0 -0
  339. {execweave-0.8.9 → execweave-0.8.10}/tests/fixtures/hooks/codex.json +0 -0
  340. {execweave-0.8.9 → execweave-0.8.10}/tests/fixtures/hooks/cursor.json +0 -0
  341. {execweave-0.8.9 → execweave-0.8.10}/tests/fixtures/hooks/manifest.json +0 -0
  342. {execweave-0.8.9 → execweave-0.8.10}/tests/fixtures/hooks/opencode.json +0 -0
  343. {execweave-0.8.9 → execweave-0.8.10}/tests/multi_agent_run_fixture.py +0 -0
  344. {execweave-0.8.9 → execweave-0.8.10}/tests/test_agent_bootstrap.py +0 -0
  345. {execweave-0.8.9 → execweave-0.8.10}/tests/test_agent_message_viewer.py +0 -0
  346. {execweave-0.8.9 → execweave-0.8.10}/tests/test_agent_node_labels.py +0 -0
  347. {execweave-0.8.9 → execweave-0.8.10}/tests/test_agent_said_panel.py +0 -0
  348. {execweave-0.8.9 → execweave-0.8.10}/tests/test_agent_topology_evidence.py +0 -0
  349. {execweave-0.8.9 → execweave-0.8.10}/tests/test_agent_trace_lifecycle.py +0 -0
  350. {execweave-0.8.9 → execweave-0.8.10}/tests/test_agent_trace_viewer_visibility.py +0 -0
  351. {execweave-0.8.9 → execweave-0.8.10}/tests/test_agy_windows_wire_acceptance.py +0 -0
  352. {execweave-0.8.9 → execweave-0.8.10}/tests/test_analysis.py +0 -0
  353. {execweave-0.8.9 → execweave-0.8.10}/tests/test_anthropic.py +0 -0
  354. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_agent_collaboration.py +0 -0
  355. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_child_panel_policy.py +0 -0
  356. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_child_transcript_tools.py +0 -0
  357. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_cursor_launch.py +0 -0
  358. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_field_run_regressions.py +0 -0
  359. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_history_replay.py +0 -0
  360. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_identity_topology.py +0 -0
  361. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_invocation_archive.py +0 -0
  362. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_lifecycle.py +0 -0
  363. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_linkage_projection.py +0 -0
  364. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_multi_conversation_isolation.py +0 -0
  365. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_official_contract.py +0 -0
  366. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_role_path_fallback.py +0 -0
  367. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_root_child_history_v2.py +0 -0
  368. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_subagent_transcript_linkage.py +0 -0
  369. {execweave-0.8.9 → execweave-0.8.10}/tests/test_antigravity_trace_capability_cli.py +0 -0
  370. {execweave-0.8.9 → execweave-0.8.10}/tests/test_auto_specialized.py +0 -0
  371. {execweave-0.8.9 → execweave-0.8.10}/tests/test_backends.py +0 -0
  372. {execweave-0.8.9 → execweave-0.8.10}/tests/test_claude_adapter.py +0 -0
  373. {execweave-0.8.9 → execweave-0.8.10}/tests/test_claude_child_transcript_tools.py +0 -0
  374. {execweave-0.8.9 → execweave-0.8.10}/tests/test_claude_delegation.py +0 -0
  375. {execweave-0.8.9 → execweave-0.8.10}/tests/test_claude_full_fidelity.py +0 -0
  376. {execweave-0.8.9 → execweave-0.8.10}/tests/test_claude_hook_contract.py +0 -0
  377. {execweave-0.8.9 → execweave-0.8.10}/tests/test_claude_hook_metadata.py +0 -0
  378. {execweave-0.8.9 → execweave-0.8.10}/tests/test_claude_hook_viewer.py +0 -0
  379. {execweave-0.8.9 → execweave-0.8.10}/tests/test_claude_model_observer.py +0 -0
  380. {execweave-0.8.9 → execweave-0.8.10}/tests/test_claude_record.py +0 -0
  381. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_adapter.py +0 -0
  382. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_archive_full_fidelity.py +0 -0
  383. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_child_panel_policy.py +0 -0
  384. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_conversation_isolation.py +0 -0
  385. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_full_fidelity.py +0 -0
  386. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_hook_lifecycle.py +0 -0
  387. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_hook_partial_capture.py +0 -0
  388. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_message_diagnostics.py +0 -0
  389. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_message_transport_diagnostics.py +0 -0
  390. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_nickname_path_fallback.py +0 -0
  391. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_plain_routed_agent_message.py +0 -0
  392. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_real_multi_agent_conversation.py +0 -0
  393. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_record.py +0 -0
  394. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_reducer_command.py +0 -0
  395. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_rollout_structures.py +0 -0
  396. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_rollout_trace.py +0 -0
  397. {execweave-0.8.9 → execweave-0.8.10}/tests/test_codex_routing_native_identity.py +0 -0
  398. {execweave-0.8.9 → execweave-0.8.10}/tests/test_collector.py +0 -0
  399. {execweave-0.8.9 → execweave-0.8.10}/tests/test_command.py +0 -0
  400. {execweave-0.8.9 → execweave-0.8.10}/tests/test_condense.py +0 -0
  401. {execweave-0.8.9 → execweave-0.8.10}/tests/test_conversation_access.py +0 -0
  402. {execweave-0.8.9 → execweave-0.8.10}/tests/test_conversation_agent_focus.py +0 -0
  403. {execweave-0.8.9 → execweave-0.8.10}/tests/test_conversation_agent_isolation.py +0 -0
  404. {execweave-0.8.9 → execweave-0.8.10}/tests/test_conversation_identity_merge.py +0 -0
  405. {execweave-0.8.9 → execweave-0.8.10}/tests/test_conversation_message_observation_dedupe.py +0 -0
  406. {execweave-0.8.9 → execweave-0.8.10}/tests/test_conversation_provider_parity.py +0 -0
  407. {execweave-0.8.9 → execweave-0.8.10}/tests/test_conversation_root_authority.py +0 -0
  408. {execweave-0.8.9 → execweave-0.8.10}/tests/test_correlation.py +0 -0
  409. {execweave-0.8.9 → execweave-0.8.10}/tests/test_correlation_canonical_path.py +0 -0
  410. {execweave-0.8.9 → execweave-0.8.10}/tests/test_correlation_checker.py +0 -0
  411. {execweave-0.8.9 → execweave-0.8.10}/tests/test_correlation_process_exe.py +0 -0
  412. {execweave-0.8.9 → execweave-0.8.10}/tests/test_cross_provider_agent_trace.py +0 -0
  413. {execweave-0.8.9 → execweave-0.8.10}/tests/test_cursor_adapter.py +0 -0
  414. {execweave-0.8.9 → execweave-0.8.10}/tests/test_cursor_delegation.py +0 -0
  415. {execweave-0.8.9 → execweave-0.8.10}/tests/test_cursor_full_fidelity.py +0 -0
  416. {execweave-0.8.9 → execweave-0.8.10}/tests/test_cursor_hook_contract.py +0 -0
  417. {execweave-0.8.9 → execweave-0.8.10}/tests/test_cursor_hook_fail_open.py +0 -0
  418. {execweave-0.8.9 → execweave-0.8.10}/tests/test_cursor_record.py +0 -0
  419. {execweave-0.8.9 → execweave-0.8.10}/tests/test_cursor_task_linkage.py +0 -0
  420. {execweave-0.8.9 → execweave-0.8.10}/tests/test_dashboard_information_architecture.py +0 -0
  421. {execweave-0.8.9 → execweave-0.8.10}/tests/test_dashboard_readability_e2e.py +0 -0
  422. {execweave-0.8.9 → execweave-0.8.10}/tests/test_dashboard_round_fold_state_e2e.py +0 -0
  423. {execweave-0.8.9 → execweave-0.8.10}/tests/test_dashboard_simplification.py +0 -0
  424. {execweave-0.8.9 → execweave-0.8.10}/tests/test_dashboard_ux_and_hook_projection.py +0 -0
  425. {execweave-0.8.9 → execweave-0.8.10}/tests/test_delegation_viewer.py +0 -0
  426. {execweave-0.8.9 → execweave-0.8.10}/tests/test_evidence_grade.py +0 -0
  427. {execweave-0.8.9 → execweave-0.8.10}/tests/test_execution_viewer.py +0 -0
  428. {execweave-0.8.9 → execweave-0.8.10}/tests/test_external_endpoints_all_providers.py +0 -0
  429. {execweave-0.8.9 → execweave-0.8.10}/tests/test_fidelity.py +0 -0
  430. {execweave-0.8.9 → execweave-0.8.10}/tests/test_filesystem_resilience.py +0 -0
  431. {execweave-0.8.9 → execweave-0.8.10}/tests/test_focus.py +0 -0
  432. {execweave-0.8.9 → execweave-0.8.10}/tests/test_fold_budget_setting.py +0 -0
  433. {execweave-0.8.9 → execweave-0.8.10}/tests/test_full_fidelity.py +0 -0
  434. {execweave-0.8.9 → execweave-0.8.10}/tests/test_graph.py +0 -0
  435. {execweave-0.8.9 → execweave-0.8.10}/tests/test_graph_clear_focus_e2e.py +0 -0
  436. {execweave-0.8.9 → execweave-0.8.10}/tests/test_graph_edge_routing_e2e.py +0 -0
  437. {execweave-0.8.9 → execweave-0.8.10}/tests/test_graph_lane_separation_e2e.py +0 -0
  438. {execweave-0.8.9 → execweave-0.8.10}/tests/test_graph_node_sizing_e2e.py +0 -0
  439. {execweave-0.8.9 → execweave-0.8.10}/tests/test_graph_ops.py +0 -0
  440. {execweave-0.8.9 → execweave-0.8.10}/tests/test_hook_fixture_corpus.py +0 -0
  441. {execweave-0.8.9 → execweave-0.8.10}/tests/test_http_proxy.py +0 -0
  442. {execweave-0.8.9 → execweave-0.8.10}/tests/test_inference_endpoint_identity.py +0 -0
  443. {execweave-0.8.9 → execweave-0.8.10}/tests/test_inference_gateway.py +0 -0
  444. {execweave-0.8.9 → execweave-0.8.10}/tests/test_inference_gateway_full_fidelity.py +0 -0
  445. {execweave-0.8.9 → execweave-0.8.10}/tests/test_inference_identity.py +0 -0
  446. {execweave-0.8.9 → execweave-0.8.10}/tests/test_integrity.py +0 -0
  447. {execweave-0.8.9 → execweave-0.8.10}/tests/test_litellm_callback.py +0 -0
  448. {execweave-0.8.9 → execweave-0.8.10}/tests/test_live.py +0 -0
  449. {execweave-0.8.9 → execweave-0.8.10}/tests/test_live_auth.py +0 -0
  450. {execweave-0.8.9 → execweave-0.8.10}/tests/test_live_dashboard.py +0 -0
  451. {execweave-0.8.9 → execweave-0.8.10}/tests/test_live_dashboard_js.py +0 -0
  452. {execweave-0.8.9 → execweave-0.8.10}/tests/test_live_delta.py +0 -0
  453. {execweave-0.8.9 → execweave-0.8.10}/tests/test_live_logs_export.py +0 -0
  454. {execweave-0.8.9 → execweave-0.8.10}/tests/test_live_theme.py +0 -0
  455. {execweave-0.8.9 → execweave-0.8.10}/tests/test_lmstudio_auto_specialized.py +0 -0
  456. {execweave-0.8.9 → execweave-0.8.10}/tests/test_local_runtime_live_capture.py +0 -0
  457. {execweave-0.8.9 → execweave-0.8.10}/tests/test_model_runtime.py +0 -0
  458. {execweave-0.8.9 → execweave-0.8.10}/tests/test_model_runtime_full_fidelity.py +0 -0
  459. {execweave-0.8.9 → execweave-0.8.10}/tests/test_ollama_panel_policy.py +0 -0
  460. {execweave-0.8.9 → execweave-0.8.10}/tests/test_openai_compatible.py +0 -0
  461. {execweave-0.8.9 → execweave-0.8.10}/tests/test_opencode_adapter.py +0 -0
  462. {execweave-0.8.9 → execweave-0.8.10}/tests/test_opencode_event_contract.py +0 -0
  463. {execweave-0.8.9 → execweave-0.8.10}/tests/test_opencode_event_lifecycle.py +0 -0
  464. {execweave-0.8.9 → execweave-0.8.10}/tests/test_opencode_full_fidelity.py +0 -0
  465. {execweave-0.8.9 → execweave-0.8.10}/tests/test_opencode_identity_unification.py +0 -0
  466. {execweave-0.8.9 → execweave-0.8.10}/tests/test_opencode_plugin.py +0 -0
  467. {execweave-0.8.9 → execweave-0.8.10}/tests/test_opencode_record.py +0 -0
  468. {execweave-0.8.9 → execweave-0.8.10}/tests/test_opencode_task_session_linkage.py +0 -0
  469. {execweave-0.8.9 → execweave-0.8.10}/tests/test_overhead_benchmark.py +0 -0
  470. {execweave-0.8.9 → execweave-0.8.10}/tests/test_per_agent_conversation_default.py +0 -0
  471. {execweave-0.8.9 → execweave-0.8.10}/tests/test_pr25_premerge_hardening_contract.py +0 -0
  472. {execweave-0.8.9 → execweave-0.8.10}/tests/test_pr25_premerge_hardening_e2e.py +0 -0
  473. {execweave-0.8.9 → execweave-0.8.10}/tests/test_process_tree_layout.py +0 -0
  474. {execweave-0.8.9 → execweave-0.8.10}/tests/test_provider_capability.py +0 -0
  475. {execweave-0.8.9 → execweave-0.8.10}/tests/test_provider_conversation_evidence.py +0 -0
  476. {execweave-0.8.9 → execweave-0.8.10}/tests/test_provider_conversation_history_integrity.py +0 -0
  477. {execweave-0.8.9 → execweave-0.8.10}/tests/test_provider_dashboard_contract.py +0 -0
  478. {execweave-0.8.9 → execweave-0.8.10}/tests/test_provider_lifecycle.py +0 -0
  479. {execweave-0.8.9 → execweave-0.8.10}/tests/test_release_stage_integrity_version_guard.py +0 -0
  480. {execweave-0.8.9 → execweave-0.8.10}/tests/test_rule_pack.py +0 -0
  481. {execweave-0.8.9 → execweave-0.8.10}/tests/test_schema.py +0 -0
  482. {execweave-0.8.9 → execweave-0.8.10}/tests/test_scope.py +0 -0
  483. {execweave-0.8.9 → execweave-0.8.10}/tests/test_semantic.py +0 -0
  484. {execweave-0.8.9 → execweave-0.8.10}/tests/test_shared_injected_context_scope.py +0 -0
  485. {execweave-0.8.9 → execweave-0.8.10}/tests/test_strace_backend.py +0 -0
  486. {execweave-0.8.9 → execweave-0.8.10}/tests/test_stream_assembly.py +0 -0
  487. {execweave-0.8.9 → execweave-0.8.10}/tests/test_threat_model.py +0 -0
  488. {execweave-0.8.9 → execweave-0.8.10}/tests/test_tool_traffic_e2e.py +0 -0
  489. {execweave-0.8.9 → execweave-0.8.10}/tests/test_top_detached.py +0 -0
  490. {execweave-0.8.9 → execweave-0.8.10}/tests/test_v063_features.py +0 -0
  491. {execweave-0.8.9 → execweave-0.8.10}/tests/test_v064_live_auto_integrations.py +0 -0
  492. {execweave-0.8.9 → execweave-0.8.10}/tests/test_v064_live_evidence.py +0 -0
  493. {execweave-0.8.9 → execweave-0.8.10}/tests/test_v079_review_e2e.py +0 -0
  494. {execweave-0.8.9 → execweave-0.8.10}/tests/test_v079_review_regressions.py +0 -0
  495. {execweave-0.8.9 → execweave-0.8.10}/tests/test_v083_release_gate_p2.py +0 -0
  496. {execweave-0.8.9 → execweave-0.8.10}/tests/test_validate.py +0 -0
  497. {execweave-0.8.9 → execweave-0.8.10}/tests/test_version.py +0 -0
  498. {execweave-0.8.9 → execweave-0.8.10}/tests/test_viewer.py +0 -0
  499. {execweave-0.8.9 → execweave-0.8.10}/tests/test_viewer_agent_isolation_e2e.py +0 -0
  500. {execweave-0.8.9 → execweave-0.8.10}/tests/test_viewer_child_authority.py +0 -0
  501. {execweave-0.8.9 → execweave-0.8.10}/tests/test_viewer_content_inspector.py +0 -0
  502. {execweave-0.8.9 → execweave-0.8.10}/tests/test_viewer_limits.py +0 -0
  503. {execweave-0.8.9 → execweave-0.8.10}/tests/test_viewer_projection.py +0 -0
  504. {execweave-0.8.9 → execweave-0.8.10}/tests/test_windows_codex_agy_display_repair.py +0 -0
  505. {execweave-0.8.9 → execweave-0.8.10}/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.10
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.10**. This release fixes Windows Cursor launch resolution for arbitrary install roots and lets an ExecWeave-managed local `ollama serve` capture later loopback inference clients into the same semantic stream and dashboard.
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. Relay mode is deliberately limited to local `localhost` / `127.0.0.1` binds; external, wildcard, and IPv6 exposure is not rewritten.
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.10**.
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.10**.
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.10** を説明します。
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.10**을 설명합니다.
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.10**. This release fixes Windows Cursor launch resolution for arbitrary install roots and lets an ExecWeave-managed local `ollama serve` capture later loopback inference clients into the same semantic stream and dashboard.
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. Relay mode is deliberately limited to local `localhost` / `127.0.0.1` binds; external, wildcard, and IPv6 exposure is not rewritten.
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.10**.
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.10**。
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.10**。
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.10 release metadata
8
+ version = "0.8.10"
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.10"
@@ -2,12 +2,13 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
  import os
5
+ import socket
5
6
  import threading
6
7
  import time
7
8
  from contextlib import contextmanager
8
9
  from dataclasses import dataclass
9
10
  from pathlib import Path
10
- from typing import Iterator
11
+ from typing import Any, Iterator
11
12
  from urllib.error import HTTPError, URLError
12
13
  from urllib.parse import urlsplit, urlunsplit
13
14
  from urllib.request import Request, urlopen
@@ -22,6 +23,18 @@ from .model_runtime import (
22
23
 
23
24
  _SEMANTIC_ENV = "EXECWEAVE_SEMANTIC_SIDECAR"
24
25
  _OLLAMA_DEFAULT_ENDPOINT = "http://127.0.0.1:11434"
26
+ _OLLAMA_INFERENCE_PATHS = frozenset(
27
+ {
28
+ "/api/chat",
29
+ "/api/generate",
30
+ "/api/embed",
31
+ "/api/embeddings",
32
+ "/v1/chat/completions",
33
+ "/v1/completions",
34
+ "/v1/embeddings",
35
+ "/v1/responses",
36
+ }
37
+ )
25
38
  _PROBE_INTERVAL_SECONDS = 0.50
26
39
  _PROBE_TIMEOUT_SECONDS = 0.35
27
40
  _PROBE_STARTUP_GRACE_SECONDS = 0.10
@@ -132,6 +145,45 @@ def _ollama_endpoint_from_environment() -> str | None:
132
145
  return _local_endpoint(hostname, port)
133
146
 
134
147
 
148
+ def _ollama_serve_relay_address() -> tuple[str, int] | None:
149
+ """Return a loopback endpoint ExecWeave can safely own for ``ollama serve``."""
150
+ raw = os.environ.get("OLLAMA_HOST", "").strip()
151
+ if not raw:
152
+ return ("127.0.0.1", 11434)
153
+ candidate = raw if "://" in raw else f"http://{raw}"
154
+ try:
155
+ parsed = urlsplit(candidate)
156
+ port = parsed.port or 11434
157
+ except ValueError:
158
+ return None
159
+ if parsed.scheme != "http" or parsed.username is not None or parsed.password is not None:
160
+ return None
161
+ if parsed.path not in {"", "/"} or parsed.query or parsed.fragment:
162
+ return None
163
+ hostname = parsed.hostname
164
+ # Do not silently narrow wildcard/external/IPv6 exposure to IPv4 loopback.
165
+ if hostname not in {"127.0.0.1", "localhost"} or not (1 <= port <= 65535):
166
+ return None
167
+ return ("127.0.0.1", port)
168
+
169
+
170
+ def _allocate_loopback_port() -> int:
171
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
172
+ sock.bind(("127.0.0.1", 0))
173
+ return int(sock.getsockname()[1])
174
+
175
+
176
+ def _record_ollama_inference_exchange(config: Any, **kwargs: Any) -> None:
177
+ """Record inference exchanges while still relaying every Ollama API route."""
178
+ method = str(kwargs.get("method", "")).upper()
179
+ request_path = str(kwargs.get("request_path", ""))
180
+ if method != "POST" or urlsplit(request_path).path not in _OLLAMA_INFERENCE_PATHS:
181
+ return
182
+ from .http_proxy import record_exchange_fail_open
183
+
184
+ record_exchange_fail_open(config, **kwargs)
185
+
186
+
135
187
  def _lmstudio_post_probe_spec(command: list[str]) -> _ProbeSpec | None:
136
188
  if not _is_lmstudio_server_start(command):
137
189
  return None
@@ -248,12 +300,7 @@ def _run_ollama_probe(
248
300
 
249
301
 
250
302
  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
- """
303
+ """Prepare an attribution-safe post-command probe for short-lived launch CLIs."""
257
304
  spec = _lmstudio_post_probe_spec(command)
258
305
  if spec is None:
259
306
  return None
@@ -292,40 +339,85 @@ def run_post_command_specialized_probe(
292
339
  time.sleep(_POST_PROBE_RETRY_SECONDS)
293
340
 
294
341
 
295
-
296
342
  @contextmanager
297
- def auto_specialized_launch(command: list[str]) -> Iterator[dict[str, str]]:
298
- """Prepare child-only launch wiring for supported transparent local integrations."""
343
+ def auto_specialized_launch(
344
+ command: list[str],
345
+ *,
346
+ server_relay: bool = False,
347
+ ) -> Iterator[dict[str, str]]:
348
+ """Prepare child launch wiring for supported transparent local integrations.
349
+
350
+ ``server_relay`` is deliberately opt-in so direct library callers preserve the
351
+ existing contract. RuntimeCollector enables it for a real managed server run.
352
+ """
299
353
  environment = dict(os.environ)
300
354
  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:
355
+ wants_run_relay = _is_ollama_run(command)
356
+ wants_serve_relay = server_relay and _is_ollama_serve(command)
357
+ if not configured_sidecar or not (wants_run_relay or wants_serve_relay):
306
358
  yield environment
307
359
  return
308
360
 
309
361
  from .http_proxy import ExecWeaveHTTPProxyServer, ProxyConfig
310
362
 
311
363
  sidecar = Path(configured_sidecar).expanduser().resolve()
364
+
365
+ if wants_run_relay:
366
+ upstream = _ollama_endpoint_from_environment()
367
+ if upstream is None:
368
+ yield environment
369
+ return
370
+ try:
371
+ server = ExecWeaveHTTPProxyServer(
372
+ ("127.0.0.1", 0),
373
+ ProxyConfig(upstream=upstream, sidecar=sidecar, mode="ollama"),
374
+ recorder=_record_ollama_inference_exchange,
375
+ )
376
+ except OSError:
377
+ yield environment
378
+ return
379
+ thread = threading.Thread(
380
+ target=server.serve_forever,
381
+ kwargs={"poll_interval": 0.05},
382
+ name="execweave-ollama-run-relay",
383
+ daemon=True,
384
+ )
385
+ thread.start()
386
+ host, port = server.server_address[:2]
387
+ environment["OLLAMA_HOST"] = f"http://{host}:{port}"
388
+ try:
389
+ yield environment
390
+ finally:
391
+ server.shutdown()
392
+ server.server_close()
393
+ thread.join(timeout=2.0)
394
+ return
395
+
396
+ listen_address = _ollama_serve_relay_address()
397
+ if listen_address is None:
398
+ yield environment
399
+ return
400
+ listen_host, listen_port = listen_address
401
+ internal_port = _allocate_loopback_port()
402
+ upstream = f"http://127.0.0.1:{internal_port}"
312
403
  try:
313
404
  server = ExecWeaveHTTPProxyServer(
314
- ("127.0.0.1", 0),
405
+ (listen_host, listen_port),
315
406
  ProxyConfig(upstream=upstream, sidecar=sidecar, mode="ollama"),
407
+ recorder=_record_ollama_inference_exchange,
316
408
  )
317
409
  except OSError:
410
+ # Fail open: preserve the child command's normal bind/error behavior.
318
411
  yield environment
319
412
  return
320
413
  thread = threading.Thread(
321
414
  target=server.serve_forever,
322
415
  kwargs={"poll_interval": 0.05},
323
- name="execweave-ollama-run-relay",
416
+ name="execweave-ollama-serve-relay",
324
417
  daemon=True,
325
418
  )
326
419
  thread.start()
327
- host, port = server.server_address[:2]
328
- environment["OLLAMA_HOST"] = f"http://{host}:{port}"
420
+ environment["OLLAMA_HOST"] = upstream
329
421
  try:
330
422
  yield environment
331
423
  finally:
@@ -336,12 +428,7 @@ def auto_specialized_launch(command: list[str]) -> Iterator[dict[str, str]]:
336
428
 
337
429
  @contextmanager
338
430
  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
- """
431
+ """Run supported local specialized probes without affecting command execution."""
345
432
  configured_sidecar = os.environ.get(_SEMANTIC_ENV)
346
433
  spec = _probe_spec(command)
347
434
  if not configured_sidecar or spec is None:
@@ -168,7 +168,7 @@ class RuntimeCollector:
168
168
  return_code = 1
169
169
  post_command_probe = prepare_post_command_specialized_probe(command)
170
170
  try:
171
- with auto_specialized_launch(command) as launch_environment:
171
+ with auto_specialized_launch(command, server_relay=True) as launch_environment:
172
172
  process = subprocess.Popen(
173
173
  launch_command,
174
174
  cwd=str(self.watch_root),
@@ -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
@@ -0,0 +1,176 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import socket
5
+ import threading
6
+ from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
7
+ from pathlib import Path
8
+ from urllib.request import Request, urlopen
9
+
10
+ import pytest
11
+
12
+ import execweave.command as command_module
13
+ from execweave.auto_specialized import auto_specialized_launch
14
+ from execweave.command import resolve_launch_command
15
+
16
+
17
+ def _free_loopback_port() -> int:
18
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
19
+ sock.bind(("127.0.0.1", 0))
20
+ return int(sock.getsockname()[1])
21
+
22
+
23
+ @pytest.mark.parametrize(
24
+ "install_parts",
25
+ [
26
+ ("custom-cursor",),
27
+ ("Apps With Spaces", "Cursor Portable"),
28
+ ("任意位置", "Cursor"),
29
+ ],
30
+ )
31
+ def test_windows_cursor_policy_prefers_desktop_from_same_install(
32
+ monkeypatch: pytest.MonkeyPatch,
33
+ tmp_path: Path,
34
+ install_parts: tuple[str, ...],
35
+ ) -> None:
36
+ # The install root is deliberately arbitrary. The resolver must derive the
37
+ # desktop binary from the PATH shim's relative package layout, never from a
38
+ # drive letter, username, or fixed install directory.
39
+ install = tmp_path.joinpath(*install_parts)
40
+ bin_dir = install / "resources" / "app" / "bin"
41
+ bin_dir.mkdir(parents=True)
42
+ shim = bin_dir / "cursor.cmd"
43
+ shim.write_text("@echo off\r\n", encoding="utf-8")
44
+ desktop = install / "Cursor.exe"
45
+ desktop.write_bytes(b"MZ")
46
+ desktop.chmod(0o755)
47
+
48
+ monkeypatch.setattr(
49
+ command_module.shutil,
50
+ "which",
51
+ lambda executable, path=None: str(shim) if executable == "cursor" else None,
52
+ )
53
+ monkeypatch.setattr(command_module, "_cursor_desktop_candidates", lambda: [])
54
+ monkeypatch.setattr(command_module, "_prefer_cursor_desktop_launcher", lambda: True)
55
+
56
+ assert resolve_launch_command(["cursor"]) == [str(desktop.resolve())]
57
+
58
+
59
+ def test_explicit_cursor_launcher_path_is_not_rewritten(tmp_path: Path) -> None:
60
+ install = tmp_path / "custom-cursor"
61
+ bin_dir = install / "resources" / "app" / "bin"
62
+ bin_dir.mkdir(parents=True)
63
+ shim = bin_dir / "cursor.cmd"
64
+ shim.write_text("#!/bin/sh\nexit 0\n", encoding="utf-8")
65
+ shim.chmod(0o755)
66
+ desktop = install / "Cursor.exe"
67
+ desktop.write_bytes(b"MZ")
68
+
69
+ assert resolve_launch_command([str(shim), "--version"])[0] == str(shim.resolve())
70
+
71
+
72
+ class _IndependentOllamaHandler(BaseHTTPRequestHandler):
73
+ def log_message(self, format: str, *args: object) -> None:
74
+ return
75
+
76
+ def do_POST(self) -> None:
77
+ if self.path != "/api/chat":
78
+ self.send_response(404)
79
+ self.end_headers()
80
+ return
81
+ length = int(self.headers.get("Content-Length", "0"))
82
+ request = json.loads(self.rfile.read(length).decode("utf-8"))
83
+ payload = {
84
+ "model": request.get("model", "tiny"),
85
+ "message": {"role": "assistant", "content": "serve relay answer"},
86
+ "done": True,
87
+ }
88
+ body = json.dumps(payload).encode("utf-8")
89
+ self.send_response(200)
90
+ self.send_header("Content-Type", "application/json")
91
+ self.send_header("Content-Length", str(len(body)))
92
+ self.end_headers()
93
+ self.wfile.write(body)
94
+
95
+
96
+ def test_ollama_serve_relay_captures_client_outside_process_tree(
97
+ monkeypatch: pytest.MonkeyPatch,
98
+ tmp_path: Path,
99
+ ) -> None:
100
+ public_port = _free_loopback_port()
101
+ public_endpoint = f"http://127.0.0.1:{public_port}"
102
+ sidecar = tmp_path / "events.semantic.jsonl"
103
+ monkeypatch.setenv("EXECWEAVE_SEMANTIC_SIDECAR", str(sidecar))
104
+ monkeypatch.setenv("OLLAMA_HOST", public_endpoint)
105
+
106
+ upstream: ThreadingHTTPServer | None = None
107
+ thread: threading.Thread | None = None
108
+ try:
109
+ with auto_specialized_launch(
110
+ ["ollama", "serve"],
111
+ server_relay=True,
112
+ ) as environment:
113
+ assert environment["OLLAMA_HOST"] != public_endpoint
114
+ upstream_port = int(environment["OLLAMA_HOST"].rsplit(":", 1)[1])
115
+ upstream = ThreadingHTTPServer(
116
+ ("127.0.0.1", upstream_port),
117
+ _IndependentOllamaHandler,
118
+ )
119
+ thread = threading.Thread(target=upstream.serve_forever, daemon=True)
120
+ thread.start()
121
+
122
+ # This request deliberately uses the original/public endpoint rather
123
+ # than the child environment returned above. It models `ollama run`,
124
+ # an SDK, or curl started from another terminal after `ollama serve`.
125
+ request = Request(
126
+ public_endpoint + "/api/chat",
127
+ data=json.dumps(
128
+ {
129
+ "model": "tiny",
130
+ "messages": [{"role": "user", "content": "outside client"}],
131
+ }
132
+ ).encode("utf-8"),
133
+ headers={"Content-Type": "application/json"},
134
+ method="POST",
135
+ )
136
+ with urlopen(request, timeout=5) as response:
137
+ result = json.loads(response.read().decode("utf-8"))
138
+ assert result["message"]["content"] == "serve relay answer"
139
+
140
+ rows = [
141
+ json.loads(line)
142
+ for line in sidecar.read_text(encoding="utf-8").splitlines()
143
+ if line.strip()
144
+ ]
145
+ kinds = {
146
+ (row.get("target", {}).get("attributes") or {}).get("content_kind")
147
+ for row in rows
148
+ if isinstance(row, dict)
149
+ }
150
+ assert "model_runtime.ollama.request_messages" in kinds
151
+ assert "model_runtime.ollama.assistant_messages" in kinds
152
+ assert any(
153
+ row.get("attributes", {}).get("transport_relay_observed") is True
154
+ for row in rows
155
+ if isinstance(row, dict)
156
+ )
157
+ finally:
158
+ if upstream is not None:
159
+ upstream.shutdown()
160
+ upstream.server_close()
161
+ if thread is not None:
162
+ thread.join(timeout=2)
163
+
164
+
165
+ def test_ollama_serve_relay_does_not_change_remote_bind(
166
+ monkeypatch: pytest.MonkeyPatch,
167
+ tmp_path: Path,
168
+ ) -> None:
169
+ monkeypatch.setenv("EXECWEAVE_SEMANTIC_SIDECAR", str(tmp_path / "semantic.jsonl"))
170
+ monkeypatch.setenv("OLLAMA_HOST", "http://192.0.2.10:11434")
171
+
172
+ with auto_specialized_launch(
173
+ ["ollama", "serve"],
174
+ server_relay=True,
175
+ ) as environment:
176
+ assert environment["OLLAMA_HOST"] == "http://192.0.2.10:11434"
@@ -103,10 +103,10 @@ def test_release_version_and_noncommercial_license_metadata_are_078() -> None:
103
103
  stage-integrity node-ID floor refuses renames; the assertions below are the
104
104
  current release.
105
105
  """
106
- assert __version__ == "0.8.9"
106
+ assert __version__ == "0.8.10"
107
107
  pyproject = Path("pyproject.toml").read_text(encoding="utf-8")
108
- assert 'version = "0.8.9"' in pyproject
109
- assert "ExecWeave v0.8.9 release metadata" in pyproject
108
+ assert 'version = "0.8.10"' in pyproject
109
+ assert "ExecWeave v0.8.10 release metadata" in pyproject
110
110
  assert "License :: Other/Proprietary License" in pyproject
111
111
  assert "License :: OSI Approved :: MIT License" not in pyproject
112
112