execweave 0.8.16__tar.gz → 0.8.17__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 (592) hide show
  1. {execweave-0.8.16 → execweave-0.8.17}/PKG-INFO +1 -1
  2. {execweave-0.8.16 → execweave-0.8.17}/pyproject.toml +10 -2
  3. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/__init__.py +1 -1
  4. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/_dashboard_shell_base.py +4 -2
  5. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/auto_specialized.py +56 -3
  6. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/collector.py +3 -1
  7. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/live_core.py +10 -0
  8. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/live_view_process_layout.py +47 -91
  9. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/live_view_script_c.py +1 -1
  10. execweave-0.8.17/src/execweave/runtime_endpoint_availability.py +44 -0
  11. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/top.py +6 -0
  12. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_dashboard_focus.py +23 -5
  13. execweave-0.8.17/src/execweave/viewer_dashboard_pr70.py +261 -0
  14. execweave-0.8.17/src/execweave/viewer_gif.py +278 -0
  15. execweave-0.8.17/src/execweave/viewer_layout_geometry.py +118 -0
  16. execweave-0.8.17/src/execweave/viewer_projection_bridges.py +214 -0
  17. execweave-0.8.17/src/execweave/viewer_tool_mirror_identity.py +75 -0
  18. execweave-0.8.16/.github/workflows/ci.yml +0 -287
  19. execweave-0.8.16/.github/workflows/cleanup-workflow-history.yml +0 -98
  20. execweave-0.8.16/.github/workflows/i18n.yml +0 -35
  21. execweave-0.8.16/.github/workflows/package-benchmark.yml +0 -61
  22. execweave-0.8.16/.github/workflows/package-smoke.yml +0 -42
  23. execweave-0.8.16/.github/workflows/provider-capability-stage-integrity.yml +0 -238
  24. execweave-0.8.16/.github/workflows/provider-dashboard-contract.yml +0 -151
  25. execweave-0.8.16/.github/workflows/publish.yml +0 -87
  26. execweave-0.8.16/.github/workflows/scalability.yml +0 -54
  27. execweave-0.8.16/.github/workflows/viewer-agent-isolation.yml +0 -89
  28. execweave-0.8.16/.github/workflows/wheel-smoke.yml +0 -34
  29. execweave-0.8.16/.github/workflows/windows-launcher.yml +0 -43
  30. execweave-0.8.16/README.de.md +0 -302
  31. execweave-0.8.16/README.fr.md +0 -302
  32. execweave-0.8.16/README.ja.md +0 -302
  33. execweave-0.8.16/README.ko.md +0 -302
  34. execweave-0.8.16/README.ru.md +0 -302
  35. execweave-0.8.16/README.zh-CN.md +0 -302
  36. execweave-0.8.16/README.zh-TW.md +0 -302
  37. execweave-0.8.16/benchmarks/phase1_overhead.py +0 -5
  38. execweave-0.8.16/diagnostics/acceptance_hardening_20260906.md +0 -202
  39. execweave-0.8.16/diagnostics/audit_eight_children.py +0 -134
  40. execweave-0.8.16/diagnostics/audit_python_journey.py +0 -215
  41. execweave-0.8.16/diagnostics/audit_real_clicks.py +0 -83
  42. execweave-0.8.16/diagnostics/current_state_reaudit.md +0 -101
  43. execweave-0.8.16/diagnostics/execweave_full_audit.md +0 -468
  44. execweave-0.8.16/diagnostics/gate_status.md +0 -69
  45. execweave-0.8.16/diagnostics/gate_status_history_through_g3.md +0 -171
  46. execweave-0.8.16/diagnostics/github_pr_inventory.json +0 -402
  47. execweave-0.8.16/diagnostics/handoff_checkpoint_20260906.md +0 -98
  48. execweave-0.8.16/diagnostics/next_agent_handoff.md +0 -154
  49. execweave-0.8.16/diagnostics/pr_regression_map.md +0 -803
  50. execweave-0.8.16/docs/antigravity-hooks.md +0 -74
  51. execweave-0.8.16/docs/assets/codex.gif +0 -0
  52. execweave-0.8.16/docs/benchmarks/README.md +0 -46
  53. execweave-0.8.16/docs/benchmarks/v0.6.0-github-actions.json +0 -67
  54. execweave-0.8.16/docs/benchmarks/v0.6.0-github-actions.svg +0 -46
  55. execweave-0.8.16/docs/claude-code-hooks.de.md +0 -157
  56. execweave-0.8.16/docs/claude-code-hooks.fr.md +0 -157
  57. execweave-0.8.16/docs/claude-code-hooks.ja.md +0 -157
  58. execweave-0.8.16/docs/claude-code-hooks.ko.md +0 -157
  59. execweave-0.8.16/docs/claude-code-hooks.md +0 -157
  60. execweave-0.8.16/docs/claude-code-hooks.ru.md +0 -157
  61. execweave-0.8.16/docs/claude-code-hooks.zh-CN.md +0 -157
  62. execweave-0.8.16/docs/claude-code-hooks.zh-TW.md +0 -157
  63. execweave-0.8.16/docs/codex-hooks.de.md +0 -70
  64. execweave-0.8.16/docs/codex-hooks.fr.md +0 -70
  65. execweave-0.8.16/docs/codex-hooks.ja.md +0 -70
  66. execweave-0.8.16/docs/codex-hooks.ko.md +0 -70
  67. execweave-0.8.16/docs/codex-hooks.md +0 -70
  68. execweave-0.8.16/docs/codex-hooks.ru.md +0 -70
  69. execweave-0.8.16/docs/codex-hooks.zh-CN.md +0 -70
  70. execweave-0.8.16/docs/codex-hooks.zh-TW.md +0 -70
  71. execweave-0.8.16/docs/cursor-hooks.de.md +0 -58
  72. execweave-0.8.16/docs/cursor-hooks.fr.md +0 -58
  73. execweave-0.8.16/docs/cursor-hooks.ja.md +0 -58
  74. execweave-0.8.16/docs/cursor-hooks.ko.md +0 -58
  75. execweave-0.8.16/docs/cursor-hooks.md +0 -62
  76. execweave-0.8.16/docs/cursor-hooks.ru.md +0 -58
  77. execweave-0.8.16/docs/cursor-hooks.zh-CN.md +0 -58
  78. execweave-0.8.16/docs/cursor-hooks.zh-TW.md +0 -58
  79. execweave-0.8.16/docs/evidence-grades.de.md +0 -61
  80. execweave-0.8.16/docs/evidence-grades.fr.md +0 -61
  81. execweave-0.8.16/docs/evidence-grades.ja.md +0 -61
  82. execweave-0.8.16/docs/evidence-grades.ko.md +0 -61
  83. execweave-0.8.16/docs/evidence-grades.md +0 -61
  84. execweave-0.8.16/docs/evidence-grades.ru.md +0 -61
  85. execweave-0.8.16/docs/evidence-grades.zh-CN.md +0 -61
  86. execweave-0.8.16/docs/evidence-grades.zh-TW.md +0 -61
  87. execweave-0.8.16/docs/inference-gateway.de.md +0 -74
  88. execweave-0.8.16/docs/inference-gateway.fr.md +0 -74
  89. execweave-0.8.16/docs/inference-gateway.ja.md +0 -74
  90. execweave-0.8.16/docs/inference-gateway.ko.md +0 -74
  91. execweave-0.8.16/docs/inference-gateway.md +0 -74
  92. execweave-0.8.16/docs/inference-gateway.ru.md +0 -74
  93. execweave-0.8.16/docs/inference-gateway.zh-CN.md +0 -74
  94. execweave-0.8.16/docs/inference-gateway.zh-TW.md +0 -74
  95. execweave-0.8.16/docs/internal/provider-capability-matrix.md +0 -101
  96. execweave-0.8.16/docs/live-graph.de.md +0 -223
  97. execweave-0.8.16/docs/live-graph.fr.md +0 -223
  98. execweave-0.8.16/docs/live-graph.ja.md +0 -223
  99. execweave-0.8.16/docs/live-graph.ko.md +0 -223
  100. execweave-0.8.16/docs/live-graph.md +0 -223
  101. execweave-0.8.16/docs/live-graph.ru.md +0 -223
  102. execweave-0.8.16/docs/live-graph.zh-CN.md +0 -223
  103. execweave-0.8.16/docs/live-graph.zh-TW.md +0 -223
  104. execweave-0.8.16/docs/model-runtime.de.md +0 -61
  105. execweave-0.8.16/docs/model-runtime.fr.md +0 -61
  106. execweave-0.8.16/docs/model-runtime.ja.md +0 -61
  107. execweave-0.8.16/docs/model-runtime.ko.md +0 -61
  108. execweave-0.8.16/docs/model-runtime.md +0 -61
  109. execweave-0.8.16/docs/model-runtime.ru.md +0 -61
  110. execweave-0.8.16/docs/model-runtime.zh-CN.md +0 -61
  111. execweave-0.8.16/docs/model-runtime.zh-TW.md +0 -61
  112. execweave-0.8.16/docs/opencode-plugin.de.md +0 -54
  113. execweave-0.8.16/docs/opencode-plugin.fr.md +0 -54
  114. execweave-0.8.16/docs/opencode-plugin.ja.md +0 -54
  115. execweave-0.8.16/docs/opencode-plugin.ko.md +0 -54
  116. execweave-0.8.16/docs/opencode-plugin.md +0 -54
  117. execweave-0.8.16/docs/opencode-plugin.ru.md +0 -54
  118. execweave-0.8.16/docs/opencode-plugin.zh-CN.md +0 -54
  119. execweave-0.8.16/docs/opencode-plugin.zh-TW.md +0 -54
  120. execweave-0.8.16/docs/phase-1-runtime-collection.de.md +0 -322
  121. execweave-0.8.16/docs/phase-1-runtime-collection.fr.md +0 -322
  122. execweave-0.8.16/docs/phase-1-runtime-collection.ja.md +0 -322
  123. execweave-0.8.16/docs/phase-1-runtime-collection.ko.md +0 -322
  124. execweave-0.8.16/docs/phase-1-runtime-collection.md +0 -322
  125. execweave-0.8.16/docs/phase-1-runtime-collection.ru.md +0 -322
  126. execweave-0.8.16/docs/phase-1-runtime-collection.zh-CN.md +0 -312
  127. execweave-0.8.16/docs/phase-1-runtime-collection.zh-TW.md +0 -312
  128. execweave-0.8.16/docs/phase-2-execution-graph.de.md +0 -286
  129. execweave-0.8.16/docs/phase-2-execution-graph.fr.md +0 -286
  130. execweave-0.8.16/docs/phase-2-execution-graph.ja.md +0 -286
  131. execweave-0.8.16/docs/phase-2-execution-graph.ko.md +0 -286
  132. execweave-0.8.16/docs/phase-2-execution-graph.md +0 -286
  133. execweave-0.8.16/docs/phase-2-execution-graph.ru.md +0 -286
  134. execweave-0.8.16/docs/phase-2-execution-graph.zh-CN.md +0 -280
  135. execweave-0.8.16/docs/phase-2-execution-graph.zh-TW.md +0 -280
  136. execweave-0.8.16/docs/remaining-provider-audit-v0.8.7.md +0 -143
  137. execweave-0.8.16/docs/rule-packs.de.md +0 -77
  138. execweave-0.8.16/docs/rule-packs.fr.md +0 -77
  139. execweave-0.8.16/docs/rule-packs.ja.md +0 -77
  140. execweave-0.8.16/docs/rule-packs.ko.md +0 -77
  141. execweave-0.8.16/docs/rule-packs.md +0 -77
  142. execweave-0.8.16/docs/rule-packs.ru.md +0 -77
  143. execweave-0.8.16/docs/rule-packs.zh-CN.md +0 -77
  144. execweave-0.8.16/docs/rule-packs.zh-TW.md +0 -77
  145. execweave-0.8.16/docs/run-integrity.de.md +0 -52
  146. execweave-0.8.16/docs/run-integrity.fr.md +0 -52
  147. execweave-0.8.16/docs/run-integrity.ja.md +0 -52
  148. execweave-0.8.16/docs/run-integrity.ko.md +0 -52
  149. execweave-0.8.16/docs/run-integrity.md +0 -52
  150. execweave-0.8.16/docs/run-integrity.ru.md +0 -52
  151. execweave-0.8.16/docs/run-integrity.zh-CN.md +0 -52
  152. execweave-0.8.16/docs/run-integrity.zh-TW.md +0 -52
  153. execweave-0.8.16/docs/runtime-threat-model.de.md +0 -60
  154. execweave-0.8.16/docs/runtime-threat-model.fr.md +0 -60
  155. execweave-0.8.16/docs/runtime-threat-model.ja.md +0 -60
  156. execweave-0.8.16/docs/runtime-threat-model.ko.md +0 -60
  157. execweave-0.8.16/docs/runtime-threat-model.md +0 -60
  158. execweave-0.8.16/docs/runtime-threat-model.ru.md +0 -60
  159. execweave-0.8.16/docs/runtime-threat-model.zh-CN.md +0 -60
  160. execweave-0.8.16/docs/runtime-threat-model.zh-TW.md +0 -60
  161. execweave-0.8.16/docs/security-analysis.de.md +0 -178
  162. execweave-0.8.16/docs/security-analysis.fr.md +0 -178
  163. execweave-0.8.16/docs/security-analysis.ja.md +0 -178
  164. execweave-0.8.16/docs/security-analysis.ko.md +0 -178
  165. execweave-0.8.16/docs/security-analysis.md +0 -178
  166. execweave-0.8.16/docs/security-analysis.ru.md +0 -178
  167. execweave-0.8.16/docs/security-analysis.zh-CN.md +0 -170
  168. execweave-0.8.16/docs/security-analysis.zh-TW.md +0 -170
  169. execweave-0.8.16/docs/semantic-telemetry.de.md +0 -63
  170. execweave-0.8.16/docs/semantic-telemetry.fr.md +0 -63
  171. execweave-0.8.16/docs/semantic-telemetry.ja.md +0 -63
  172. execweave-0.8.16/docs/semantic-telemetry.ko.md +0 -63
  173. execweave-0.8.16/docs/semantic-telemetry.md +0 -63
  174. execweave-0.8.16/docs/semantic-telemetry.ru.md +0 -63
  175. execweave-0.8.16/docs/semantic-telemetry.zh-CN.md +0 -63
  176. execweave-0.8.16/docs/semantic-telemetry.zh-TW.md +0 -63
  177. execweave-0.8.16/docs/v0.6.5-hardening-decisions.md +0 -47
  178. execweave-0.8.16/docs/v0.8.3-graph-ergonomics.md +0 -180
  179. execweave-0.8.16/scripts/_check_release_stage_integrity_impl.py +0 -745
  180. execweave-0.8.16/scripts/_dashboard_acceptance_impl.py +0 -598
  181. execweave-0.8.16/scripts/_ollama_interactive_acceptance_impl.py +0 -806
  182. execweave-0.8.16/scripts/_ollama_visible_acceptance_impl.py +0 -852
  183. execweave-0.8.16/scripts/_python_native_acceptance_impl.py +0 -542
  184. execweave-0.8.16/scripts/acceptance/__init__.py +0 -1
  185. execweave-0.8.16/scripts/acceptance/browser_diagnostics.py +0 -81
  186. execweave-0.8.16/scripts/acceptance/contracts.py +0 -33
  187. execweave-0.8.16/scripts/acceptance/g5_runner.py +0 -468
  188. execweave-0.8.16/scripts/acceptance/g6_runner.py +0 -258
  189. execweave-0.8.16/scripts/acceptance/interrupt_guard.py +0 -88
  190. execweave-0.8.16/scripts/acceptance/processes.py +0 -207
  191. execweave-0.8.16/scripts/acceptance/reporting.py +0 -336
  192. execweave-0.8.16/scripts/acceptance/terminal_output.py +0 -242
  193. execweave-0.8.16/scripts/annotate_pytest_failures.py +0 -52
  194. execweave-0.8.16/scripts/audit_i18n_parity.py +0 -189
  195. execweave-0.8.16/scripts/check_claude_hook.py +0 -85
  196. execweave-0.8.16/scripts/check_claude_record_graph.py +0 -31
  197. execweave-0.8.16/scripts/check_codex_hook.py +0 -87
  198. execweave-0.8.16/scripts/check_conversation_records.py +0 -215
  199. execweave-0.8.16/scripts/check_correlation_graph.py +0 -80
  200. execweave-0.8.16/scripts/check_inference_gateway_cli.py +0 -155
  201. execweave-0.8.16/scripts/check_model_runtime_cli.py +0 -268
  202. execweave-0.8.16/scripts/check_openai_compatible_cli.py +0 -152
  203. execweave-0.8.16/scripts/check_release_stage_integrity.py +0 -79
  204. execweave-0.8.16/scripts/check_semantic_graph.py +0 -33
  205. execweave-0.8.16/scripts/check_viewer_js.py +0 -35
  206. execweave-0.8.16/scripts/check_wheel_install.py +0 -80
  207. execweave-0.8.16/scripts/check_windows_launchers.py +0 -120
  208. execweave-0.8.16/scripts/dashboard_acceptance.py +0 -49
  209. execweave-0.8.16/scripts/emit_claude_hook_smoke.py +0 -57
  210. execweave-0.8.16/scripts/emit_codex_hook_smoke.py +0 -201
  211. execweave-0.8.16/scripts/emit_cursor_hook_smoke.py +0 -67
  212. execweave-0.8.16/scripts/emit_opencode_plugin_smoke.py +0 -70
  213. execweave-0.8.16/scripts/make_semantic_smoke.py +0 -83
  214. execweave-0.8.16/scripts/measure_graph_metrics.py +0 -932
  215. execweave-0.8.16/scripts/ollama_interactive_acceptance.py +0 -88
  216. execweave-0.8.16/scripts/ollama_visible_acceptance.py +0 -33
  217. execweave-0.8.16/scripts/owned_cleanup_acceptance.py +0 -164
  218. execweave-0.8.16/scripts/probe_provider_capability.py +0 -167
  219. execweave-0.8.16/scripts/python_native_acceptance.py +0 -52
  220. execweave-0.8.16/scripts/sync_i18n_nav.py +0 -145
  221. execweave-0.8.16/src/execweave/viewer_gif.py +0 -232
  222. execweave-0.8.16/tests/dashboard_readability_fixture.py +0 -232
  223. execweave-0.8.16/tests/fixtures/codex_multi_agent/PROVENANCE.md +0 -38
  224. execweave-0.8.16/tests/fixtures/codex_multi_agent/hook-payloads.json +0 -105
  225. execweave-0.8.16/tests/fixtures/codex_multi_agent/rollout-main.jsonl +0 -77
  226. execweave-0.8.16/tests/fixtures/hooks/README.md +0 -33
  227. execweave-0.8.16/tests/fixtures/hooks/claude.json +0 -35
  228. execweave-0.8.16/tests/fixtures/hooks/codex.json +0 -40
  229. execweave-0.8.16/tests/fixtures/hooks/cursor.json +0 -51
  230. execweave-0.8.16/tests/fixtures/hooks/manifest.json +0 -49
  231. execweave-0.8.16/tests/fixtures/hooks/opencode.json +0 -30
  232. execweave-0.8.16/tests/multi_agent_run_fixture.py +0 -210
  233. execweave-0.8.16/tests/test_acceptance_browser_diagnostics_e2e.py +0 -138
  234. execweave-0.8.16/tests/test_acceptance_conpty_selection.py +0 -43
  235. execweave-0.8.16/tests/test_acceptance_interrupt_guard.py +0 -65
  236. execweave-0.8.16/tests/test_acceptance_owned_processes.py +0 -112
  237. execweave-0.8.16/tests/test_acceptance_required_capabilities.py +0 -64
  238. execweave-0.8.16/tests/test_acceptance_terminal_output.py +0 -79
  239. execweave-0.8.16/tests/test_acceptance_visible_pipe.py +0 -47
  240. execweave-0.8.16/tests/test_agent_bootstrap.py +0 -259
  241. execweave-0.8.16/tests/test_agent_message_viewer.py +0 -138
  242. execweave-0.8.16/tests/test_agent_node_labels.py +0 -165
  243. execweave-0.8.16/tests/test_agent_said_panel.py +0 -92
  244. execweave-0.8.16/tests/test_agent_topology_evidence.py +0 -439
  245. execweave-0.8.16/tests/test_agent_trace_lifecycle.py +0 -82
  246. execweave-0.8.16/tests/test_agent_trace_viewer_visibility.py +0 -72
  247. execweave-0.8.16/tests/test_agy_windows_wire_acceptance.py +0 -302
  248. execweave-0.8.16/tests/test_analysis.py +0 -178
  249. execweave-0.8.16/tests/test_anthropic.py +0 -248
  250. execweave-0.8.16/tests/test_antigravity_agent_collaboration.py +0 -161
  251. execweave-0.8.16/tests/test_antigravity_child_panel_policy.py +0 -166
  252. execweave-0.8.16/tests/test_antigravity_child_transcript_tools.py +0 -158
  253. execweave-0.8.16/tests/test_antigravity_cursor_launch.py +0 -142
  254. execweave-0.8.16/tests/test_antigravity_field_run_regressions.py +0 -280
  255. execweave-0.8.16/tests/test_antigravity_history_replay.py +0 -233
  256. execweave-0.8.16/tests/test_antigravity_identity_topology.py +0 -112
  257. execweave-0.8.16/tests/test_antigravity_invocation_archive.py +0 -237
  258. execweave-0.8.16/tests/test_antigravity_lifecycle.py +0 -54
  259. execweave-0.8.16/tests/test_antigravity_linkage_projection.py +0 -98
  260. execweave-0.8.16/tests/test_antigravity_multi_conversation_isolation.py +0 -316
  261. execweave-0.8.16/tests/test_antigravity_official_contract.py +0 -157
  262. execweave-0.8.16/tests/test_antigravity_role_path_fallback.py +0 -249
  263. execweave-0.8.16/tests/test_antigravity_root_child_history_v2.py +0 -173
  264. execweave-0.8.16/tests/test_antigravity_subagent_transcript_linkage.py +0 -398
  265. execweave-0.8.16/tests/test_antigravity_trace_capability_cli.py +0 -48
  266. execweave-0.8.16/tests/test_auto_specialized.py +0 -380
  267. execweave-0.8.16/tests/test_auto_specialized_ollama_two_phase.py +0 -230
  268. execweave-0.8.16/tests/test_backends.py +0 -21
  269. execweave-0.8.16/tests/test_claude_adapter.py +0 -284
  270. execweave-0.8.16/tests/test_claude_child_transcript_tools.py +0 -240
  271. execweave-0.8.16/tests/test_claude_delegation.py +0 -121
  272. execweave-0.8.16/tests/test_claude_full_fidelity.py +0 -163
  273. execweave-0.8.16/tests/test_claude_hook_contract.py +0 -313
  274. execweave-0.8.16/tests/test_claude_hook_metadata.py +0 -60
  275. execweave-0.8.16/tests/test_claude_hook_viewer.py +0 -101
  276. execweave-0.8.16/tests/test_claude_model_observer.py +0 -393
  277. execweave-0.8.16/tests/test_claude_record.py +0 -198
  278. execweave-0.8.16/tests/test_cleanup_finalizer_identity.py +0 -31
  279. execweave-0.8.16/tests/test_codex_adapter.py +0 -222
  280. execweave-0.8.16/tests/test_codex_archive_full_fidelity.py +0 -224
  281. execweave-0.8.16/tests/test_codex_child_panel_policy.py +0 -375
  282. execweave-0.8.16/tests/test_codex_conversation_isolation.py +0 -94
  283. execweave-0.8.16/tests/test_codex_full_fidelity.py +0 -193
  284. execweave-0.8.16/tests/test_codex_hook_global_fail_open.py +0 -99
  285. execweave-0.8.16/tests/test_codex_hook_lifecycle.py +0 -177
  286. execweave-0.8.16/tests/test_codex_hook_partial_capture.py +0 -248
  287. execweave-0.8.16/tests/test_codex_interrupt_contract.py +0 -73
  288. execweave-0.8.16/tests/test_codex_message_diagnostics.py +0 -186
  289. execweave-0.8.16/tests/test_codex_message_transport_diagnostics.py +0 -184
  290. execweave-0.8.16/tests/test_codex_nickname_path_fallback.py +0 -134
  291. execweave-0.8.16/tests/test_codex_plain_routed_agent_message.py +0 -87
  292. execweave-0.8.16/tests/test_codex_real_multi_agent_conversation.py +0 -474
  293. execweave-0.8.16/tests/test_codex_record.py +0 -187
  294. execweave-0.8.16/tests/test_codex_reducer_command.py +0 -83
  295. execweave-0.8.16/tests/test_codex_rollout_structures.py +0 -234
  296. execweave-0.8.16/tests/test_codex_rollout_trace.py +0 -393
  297. execweave-0.8.16/tests/test_codex_routing_native_identity.py +0 -44
  298. execweave-0.8.16/tests/test_collector.py +0 -43
  299. execweave-0.8.16/tests/test_command.py +0 -76
  300. execweave-0.8.16/tests/test_condense.py +0 -154
  301. execweave-0.8.16/tests/test_conversation_access.py +0 -276
  302. execweave-0.8.16/tests/test_conversation_agent_focus.py +0 -158
  303. execweave-0.8.16/tests/test_conversation_agent_isolation.py +0 -117
  304. execweave-0.8.16/tests/test_conversation_identity_merge.py +0 -491
  305. execweave-0.8.16/tests/test_conversation_message_observation_dedupe.py +0 -346
  306. execweave-0.8.16/tests/test_conversation_provider_parity.py +0 -479
  307. execweave-0.8.16/tests/test_conversation_root_authority.py +0 -40
  308. execweave-0.8.16/tests/test_correlation.py +0 -404
  309. execweave-0.8.16/tests/test_correlation_canonical_path.py +0 -76
  310. execweave-0.8.16/tests/test_correlation_checker.py +0 -75
  311. execweave-0.8.16/tests/test_correlation_process_exe.py +0 -83
  312. execweave-0.8.16/tests/test_cross_provider_agent_trace.py +0 -306
  313. execweave-0.8.16/tests/test_cursor_adapter.py +0 -162
  314. execweave-0.8.16/tests/test_cursor_delegation.py +0 -91
  315. execweave-0.8.16/tests/test_cursor_full_fidelity.py +0 -268
  316. execweave-0.8.16/tests/test_cursor_hook_contract.py +0 -127
  317. execweave-0.8.16/tests/test_cursor_hook_fail_open.py +0 -60
  318. execweave-0.8.16/tests/test_cursor_ollama_session_lifecycle.py +0 -176
  319. execweave-0.8.16/tests/test_cursor_record.py +0 -82
  320. execweave-0.8.16/tests/test_cursor_task_linkage.py +0 -96
  321. execweave-0.8.16/tests/test_d003_fast_reparent.py +0 -134
  322. execweave-0.8.16/tests/test_dagre_semantic_pipeline.py +0 -254
  323. execweave-0.8.16/tests/test_dashboard_acceptance_relative_output_e2e.py +0 -36
  324. execweave-0.8.16/tests/test_dashboard_acceptance_reporting.py +0 -60
  325. execweave-0.8.16/tests/test_dashboard_camera_scheduler_e2e.py +0 -299
  326. execweave-0.8.16/tests/test_dashboard_favicon.py +0 -8
  327. execweave-0.8.16/tests/test_dashboard_file_activity_filter.py +0 -30
  328. execweave-0.8.16/tests/test_dashboard_gif_export_e2e.py +0 -280
  329. execweave-0.8.16/tests/test_dashboard_information_architecture.py +0 -251
  330. execweave-0.8.16/tests/test_dashboard_initial_fit_readability_e2e.py +0 -107
  331. execweave-0.8.16/tests/test_dashboard_node_drag_camera_e2e.py +0 -67
  332. execweave-0.8.16/tests/test_dashboard_readability_e2e.py +0 -407
  333. execweave-0.8.16/tests/test_dashboard_round_fold_state_e2e.py +0 -258
  334. execweave-0.8.16/tests/test_dashboard_simplification.py +0 -220
  335. execweave-0.8.16/tests/test_dashboard_ux_and_hook_projection.py +0 -383
  336. execweave-0.8.16/tests/test_delegation_viewer.py +0 -209
  337. execweave-0.8.16/tests/test_evidence_grade.py +0 -72
  338. execweave-0.8.16/tests/test_execution_viewer.py +0 -112
  339. execweave-0.8.16/tests/test_external_endpoints_all_providers.py +0 -169
  340. execweave-0.8.16/tests/test_fidelity.py +0 -335
  341. execweave-0.8.16/tests/test_filesystem_resilience.py +0 -235
  342. execweave-0.8.16/tests/test_focus.py +0 -139
  343. execweave-0.8.16/tests/test_fold_budget_setting.py +0 -121
  344. execweave-0.8.16/tests/test_full_fidelity.py +0 -91
  345. execweave-0.8.16/tests/test_g5_hardening_contract.py +0 -39
  346. execweave-0.8.16/tests/test_g6_owned_parity_contract.py +0 -133
  347. execweave-0.8.16/tests/test_graph.py +0 -333
  348. execweave-0.8.16/tests/test_graph_arrange_constraints_e2e.py +0 -111
  349. execweave-0.8.16/tests/test_graph_clear_focus_e2e.py +0 -126
  350. execweave-0.8.16/tests/test_graph_edge_routing_e2e.py +0 -168
  351. execweave-0.8.16/tests/test_graph_lane_separation_e2e.py +0 -170
  352. execweave-0.8.16/tests/test_graph_node_sizing_e2e.py +0 -288
  353. execweave-0.8.16/tests/test_graph_ops.py +0 -131
  354. execweave-0.8.16/tests/test_hook_fixture_corpus.py +0 -150
  355. execweave-0.8.16/tests/test_http_proxy.py +0 -261
  356. execweave-0.8.16/tests/test_http_proxy_request_phase.py +0 -121
  357. execweave-0.8.16/tests/test_http_proxy_response_memory.py +0 -154
  358. execweave-0.8.16/tests/test_http_proxy_streaming.py +0 -116
  359. execweave-0.8.16/tests/test_i18n_readme_policy.py +0 -49
  360. execweave-0.8.16/tests/test_inference_endpoint_identity.py +0 -147
  361. execweave-0.8.16/tests/test_inference_gateway.py +0 -155
  362. execweave-0.8.16/tests/test_inference_gateway_full_fidelity.py +0 -411
  363. execweave-0.8.16/tests/test_inference_identity.py +0 -78
  364. execweave-0.8.16/tests/test_integrity.py +0 -112
  365. execweave-0.8.16/tests/test_litellm_callback.py +0 -189
  366. execweave-0.8.16/tests/test_live.py +0 -220
  367. execweave-0.8.16/tests/test_live_auth.py +0 -176
  368. execweave-0.8.16/tests/test_live_dashboard.py +0 -31
  369. execweave-0.8.16/tests/test_live_dashboard_js.py +0 -48
  370. execweave-0.8.16/tests/test_live_delta.py +0 -179
  371. execweave-0.8.16/tests/test_live_logs_export.py +0 -94
  372. execweave-0.8.16/tests/test_live_theme.py +0 -11
  373. execweave-0.8.16/tests/test_lmstudio_auto_specialized.py +0 -149
  374. execweave-0.8.16/tests/test_local_runtime_live_capture.py +0 -185
  375. execweave-0.8.16/tests/test_model_runtime.py +0 -226
  376. execweave-0.8.16/tests/test_model_runtime_full_fidelity.py +0 -218
  377. execweave-0.8.16/tests/test_ollama_interactive_acceptance.py +0 -269
  378. execweave-0.8.16/tests/test_ollama_interactive_terminal_semantics.py +0 -76
  379. execweave-0.8.16/tests/test_ollama_panel_policy.py +0 -89
  380. execweave-0.8.16/tests/test_ollama_serve_runtime_integration.py +0 -293
  381. execweave-0.8.16/tests/test_ollama_visible_acceptance.py +0 -254
  382. execweave-0.8.16/tests/test_openai_compatible.py +0 -307
  383. execweave-0.8.16/tests/test_opencode_adapter.py +0 -72
  384. execweave-0.8.16/tests/test_opencode_event_contract.py +0 -246
  385. execweave-0.8.16/tests/test_opencode_event_lifecycle.py +0 -57
  386. execweave-0.8.16/tests/test_opencode_full_fidelity.py +0 -137
  387. execweave-0.8.16/tests/test_opencode_identity_unification.py +0 -87
  388. execweave-0.8.16/tests/test_opencode_plugin.py +0 -41
  389. execweave-0.8.16/tests/test_opencode_record.py +0 -90
  390. execweave-0.8.16/tests/test_opencode_task_session_linkage.py +0 -125
  391. execweave-0.8.16/tests/test_overhead_benchmark.py +0 -84
  392. execweave-0.8.16/tests/test_per_agent_conversation_default.py +0 -157
  393. execweave-0.8.16/tests/test_pr25_premerge_hardening_contract.py +0 -52
  394. execweave-0.8.16/tests/test_pr25_premerge_hardening_e2e.py +0 -411
  395. execweave-0.8.16/tests/test_pro6_audit_regressions.py +0 -228
  396. execweave-0.8.16/tests/test_process_tree_layout.py +0 -208
  397. execweave-0.8.16/tests/test_provider_capability.py +0 -202
  398. execweave-0.8.16/tests/test_provider_conversation_evidence.py +0 -304
  399. execweave-0.8.16/tests/test_provider_conversation_history_integrity.py +0 -335
  400. execweave-0.8.16/tests/test_provider_dashboard_contract.py +0 -401
  401. execweave-0.8.16/tests/test_provider_lifecycle.py +0 -225
  402. execweave-0.8.16/tests/test_provider_neutral_viewer_semantics.py +0 -190
  403. execweave-0.8.16/tests/test_pypi_0812_regressions.py +0 -171
  404. execweave-0.8.16/tests/test_pypi_0813_cleanup.py +0 -382
  405. execweave-0.8.16/tests/test_python_native_acceptance.py +0 -107
  406. execweave-0.8.16/tests/test_relay_prompt_live_e2e.py +0 -179
  407. execweave-0.8.16/tests/test_release_stage_integrity_version_guard.py +0 -112
  408. execweave-0.8.16/tests/test_rule_pack.py +0 -153
  409. execweave-0.8.16/tests/test_schema.py +0 -18
  410. execweave-0.8.16/tests/test_scope.py +0 -54
  411. execweave-0.8.16/tests/test_semantic.py +0 -277
  412. execweave-0.8.16/tests/test_shared_injected_context_scope.py +0 -90
  413. execweave-0.8.16/tests/test_single_agent_barycenter.py +0 -261
  414. execweave-0.8.16/tests/test_strace_backend.py +0 -202
  415. execweave-0.8.16/tests/test_stream_assembly.py +0 -380
  416. execweave-0.8.16/tests/test_threat_model.py +0 -202
  417. execweave-0.8.16/tests/test_tool_traffic_e2e.py +0 -138
  418. execweave-0.8.16/tests/test_top_detached.py +0 -180
  419. execweave-0.8.16/tests/test_v063_features.py +0 -132
  420. execweave-0.8.16/tests/test_v064_live_auto_integrations.py +0 -124
  421. execweave-0.8.16/tests/test_v064_live_evidence.py +0 -250
  422. execweave-0.8.16/tests/test_v069_dashboard_release.py +0 -124
  423. execweave-0.8.16/tests/test_v079_review_e2e.py +0 -184
  424. execweave-0.8.16/tests/test_v079_review_regressions.py +0 -105
  425. execweave-0.8.16/tests/test_v083_release_gate_p2.py +0 -150
  426. execweave-0.8.16/tests/test_validate.py +0 -113
  427. execweave-0.8.16/tests/test_version.py +0 -7
  428. execweave-0.8.16/tests/test_viewer.py +0 -345
  429. execweave-0.8.16/tests/test_viewer_agent_isolation_e2e.py +0 -885
  430. execweave-0.8.16/tests/test_viewer_child_authority.py +0 -22
  431. execweave-0.8.16/tests/test_viewer_content_inspector.py +0 -248
  432. execweave-0.8.16/tests/test_viewer_limits.py +0 -115
  433. execweave-0.8.16/tests/test_viewer_projection.py +0 -412
  434. execweave-0.8.16/tests/test_visual_ux_readability.py +0 -256
  435. execweave-0.8.16/tests/test_windows_codex_agy_display_repair.py +0 -220
  436. execweave-0.8.16/tests/test_workflow.py +0 -94
  437. execweave-0.8.16/tools/verify_metrics_tool.py +0 -104
  438. {execweave-0.8.16 → execweave-0.8.17}/.gitignore +0 -0
  439. {execweave-0.8.16 → execweave-0.8.17}/LICENSE +0 -0
  440. {execweave-0.8.16 → execweave-0.8.17}/README.md +0 -0
  441. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/__main__.py +0 -0
  442. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/_conversation_records_core.py +0 -0
  443. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/_http_proxy_base.py +0 -0
  444. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/_http_proxy_bounded.py +0 -0
  445. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/_http_proxy_stage.py +0 -0
  446. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/agent_bootstrap.py +0 -0
  447. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/agent_topology.py +0 -0
  448. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/agent_trace.py +0 -0
  449. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/agy_preview_sanitize.py +0 -0
  450. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/analysis.py +0 -0
  451. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/anthropic.py +0 -0
  452. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/anthropic_cli.py +0 -0
  453. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/anthropic_full_fidelity.py +0 -0
  454. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/antigravity_adapter.py +0 -0
  455. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/antigravity_adapter_base.py +0 -0
  456. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/antigravity_full_fidelity.py +0 -0
  457. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/antigravity_full_fidelity_base.py +0 -0
  458. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/antigravity_full_fidelity_collaboration_base.py +0 -0
  459. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/antigravity_hook_cli.py +0 -0
  460. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/antigravity_record.py +0 -0
  461. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/antigravity_subagent_linkage.py +0 -0
  462. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/antigravity_trace_capability.py +0 -0
  463. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/backends.py +0 -0
  464. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/benchmark.py +0 -0
  465. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/claude_adapter.py +0 -0
  466. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/claude_child_transcript.py +0 -0
  467. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/claude_delegation.py +0 -0
  468. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/claude_full_fidelity.py +0 -0
  469. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/claude_hook_cli.py +0 -0
  470. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/claude_hook_contract.py +0 -0
  471. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/claude_model_observer.py +0 -0
  472. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/claude_record.py +0 -0
  473. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/cli.py +0 -0
  474. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/codex_adapter.py +0 -0
  475. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/codex_conversation.py +0 -0
  476. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/codex_full_fidelity.py +0 -0
  477. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/codex_hook_cli.py +0 -0
  478. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/codex_hook_entry.py +0 -0
  479. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/codex_hook_lifecycle.py +0 -0
  480. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/codex_message_diagnostics.py +0 -0
  481. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/codex_message_transport_diagnostics.py +0 -0
  482. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/codex_record.py +0 -0
  483. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/codex_rollout_structures.py +0 -0
  484. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/codex_rollout_trace.py +0 -0
  485. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/codex_rollout_trace_base.py +0 -0
  486. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/command.py +0 -0
  487. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/content_evidence.py +0 -0
  488. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/content_store.py +0 -0
  489. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_archive.py +0 -0
  490. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_message_identity.py +0 -0
  491. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_preview.py +0 -0
  492. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_preview_antigravity.py +0 -0
  493. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_preview_claude.py +0 -0
  494. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_preview_codex.py +0 -0
  495. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_preview_common.py +0 -0
  496. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_preview_generic.py +0 -0
  497. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_preview_lines.py +0 -0
  498. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_preview_transcript.py +0 -0
  499. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_records.py +0 -0
  500. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_records_antigravity.py +0 -0
  501. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_records_codex.py +0 -0
  502. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_records_common.py +0 -0
  503. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/conversation_records_ollama.py +0 -0
  504. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/correlation.py +0 -0
  505. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/cursor_adapter.py +0 -0
  506. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/cursor_delegation.py +0 -0
  507. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/cursor_delegation_base.py +0 -0
  508. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/cursor_full_fidelity.py +0 -0
  509. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/cursor_hook_cli.py +0 -0
  510. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/cursor_hook_contract.py +0 -0
  511. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/cursor_record.py +0 -0
  512. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/dashboard_shell.py +0 -0
  513. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/entry.py +0 -0
  514. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/evidence_availability.py +0 -0
  515. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/evidence_grade.py +0 -0
  516. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/fidelity.py +0 -0
  517. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/filesystem.py +0 -0
  518. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/focus.py +0 -0
  519. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/graph.py +0 -0
  520. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/graph_ops.py +0 -0
  521. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/http_proxy.py +0 -0
  522. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/http_proxy_cli.py +0 -0
  523. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/inference_gateway.py +0 -0
  524. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/inference_gateway_cli.py +0 -0
  525. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/inference_gateway_full_fidelity.py +0 -0
  526. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/inference_identity.py +0 -0
  527. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/inference_identity_cli.py +0 -0
  528. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/integrity.py +0 -0
  529. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/integrity_cli.py +0 -0
  530. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/litellm_callback.py +0 -0
  531. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/litellm_callback_cli.py +0 -0
  532. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/live.py +0 -0
  533. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/live_view.py +0 -0
  534. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/live_view_extra_style.py +0 -0
  535. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/live_view_markup.py +0 -0
  536. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/live_view_readability.py +0 -0
  537. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/live_view_script_a.py +0 -0
  538. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/live_view_script_b.py +0 -0
  539. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/live_view_script_d.py +0 -0
  540. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/live_view_style.py +0 -0
  541. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/model_runtime.py +0 -0
  542. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/model_runtime_cli.py +0 -0
  543. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/model_runtime_full_fidelity.py +0 -0
  544. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/openai_compatible.py +0 -0
  545. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/openai_compatible_cli.py +0 -0
  546. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/openai_compatible_full_fidelity.py +0 -0
  547. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/opencode_adapter.py +0 -0
  548. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/opencode_event_contract.py +0 -0
  549. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/opencode_full_fidelity.py +0 -0
  550. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/opencode_hook_cli.py +0 -0
  551. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/opencode_plugin_cli.py +0 -0
  552. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/opencode_record.py +0 -0
  553. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/opencode_task_linkage.py +0 -0
  554. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/overhead_benchmark.py +0 -0
  555. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/provider_capability.py +0 -0
  556. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/provider_lifecycle.py +0 -0
  557. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/provider_record.py +0 -0
  558. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/rule_pack.py +0 -0
  559. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/rule_pack_cli.py +0 -0
  560. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/scalability_benchmark.py +0 -0
  561. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/schema.py +0 -0
  562. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/scope.py +0 -0
  563. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/semantic.py +0 -0
  564. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/sink.py +0 -0
  565. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/strace_backend.py +0 -0
  566. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/stream_assembly.py +0 -0
  567. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/theme.py +0 -0
  568. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/top_cli.py +0 -0
  569. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/validate.py +0 -0
  570. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/vendor/dagre.min.js +0 -0
  571. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/view_cli.py +0 -0
  572. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer.py +0 -0
  573. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_agent_panel.py +0 -0
  574. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_agent_panel_antigravity.py +0 -0
  575. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_agent_panel_claude.py +0 -0
  576. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_agent_panel_codex.py +0 -0
  577. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_agent_panel_cursor.py +0 -0
  578. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_agent_panel_default.py +0 -0
  579. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_agent_panel_ollama.py +0 -0
  580. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_agent_panel_opencode.py +0 -0
  581. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_agent_panel_registry.py +0 -0
  582. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_content_inspector.py +0 -0
  583. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_dashboard_clean.py +0 -0
  584. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_dashboard_hardening.py +0 -0
  585. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_dashboard_hardening_v2.py +0 -0
  586. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_external_endpoints.py +0 -0
  587. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_limits.py +0 -0
  588. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_live_layout.py +0 -0
  589. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_projection.py +0 -0
  590. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_projection_base.py +0 -0
  591. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/viewer_semantic_projection.py +0 -0
  592. {execweave-0.8.16 → execweave-0.8.17}/src/execweave/workflow.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: execweave
3
- Version: 0.8.16
3
+ Version: 0.8.17
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
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "execweave"
7
- # ExecWeave v0.8.16 release metadata
8
- version = "0.8.16"
7
+ # ExecWeave v0.8.17 release metadata
8
+ version = "0.8.17"
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"
@@ -95,6 +95,14 @@ execweave-scalability = "execweave.scalability_benchmark:main"
95
95
  [tool.hatch.build.targets.wheel]
96
96
  packages = ["src/execweave"]
97
97
 
98
+ [tool.hatch.build.targets.sdist]
99
+ include = [
100
+ "/src/execweave",
101
+ "/pyproject.toml",
102
+ "/README.md",
103
+ "/LICENSE",
104
+ ]
105
+
98
106
  [tool.pytest.ini_options]
99
107
  testpaths = ["tests"]
100
108
  pythonpath = ["src"]
@@ -1,3 +1,3 @@
1
1
  """ExecWeave runtime graph package."""
2
2
 
3
- __version__ = "0.8.16"
3
+ __version__ = "0.8.17"
@@ -6,8 +6,9 @@ from typing import Any
6
6
  from .live_view import LIVE_HTML as _BASE_LIVE_HTML
7
7
  from .viewer_agent_panel import inject_agent_panel
8
8
  from .viewer_dashboard_clean import fold_budget_bootstrap, inject_live_dashboard_clean
9
- from .viewer_limits import resolve_viewer_limits, viewer_limits_bootstrap
10
9
  from .viewer_dashboard_focus import inject_live_dashboard_focus
10
+ from .viewer_dashboard_pr70 import inject_pr70_dashboard_repairs
11
+ from .viewer_limits import resolve_viewer_limits, viewer_limits_bootstrap
11
12
  from .viewer_live_layout import inject_live_dashboard_layout
12
13
 
13
14
 
@@ -70,6 +71,7 @@ def _build_dashboard_html() -> str:
70
71
  html = _preserve_semantic_layout_constraints(html)
71
72
  html = _preserve_semantic_arrange(html)
72
73
  html = _route_ordinary_edges_from_final_positions(html)
74
+ html = inject_pr70_dashboard_repairs(html)
73
75
  return _align_agent_panel_topology(inject_agent_panel(_guard_compact_live_snapshot(html)))
74
76
 
75
77
 
@@ -115,4 +117,4 @@ def render_static_dashboard_html(
115
117
  "<body>",
116
118
  '<body>\n<!-- unified dashboard: theme is owned by the visible #theme-toggle control -->',
117
119
  1,
118
- )
120
+ )
@@ -14,6 +14,8 @@ from urllib.error import HTTPError, URLError
14
14
  from urllib.parse import urlsplit, urlunsplit
15
15
  from urllib.request import Request, urlopen
16
16
 
17
+ from .runtime_endpoint_availability import windows_exclusive_endpoint_available
18
+
17
19
  from .model_runtime import (
18
20
  append_model_runtime_records,
19
21
  llamacpp_models_to_events,
@@ -214,6 +216,49 @@ def _probe_spec(command: list[str]) -> _ProbeSpec | None:
214
216
  return None
215
217
 
216
218
 
219
+ @dataclass(frozen=True)
220
+ class _LiveProbeAdmission:
221
+ # Prepared before the child (and any managed relay) is launched. A grace
222
+ # period is a scheduling aid, never evidence of endpoint ownership.
223
+ spec: _ProbeSpec | None
224
+
225
+
226
+ def prepare_live_specialized_probe(command: list[str]) -> _LiveProbeAdmission:
227
+ """Do not attach an already listening or uncertain endpoint to a new run.
228
+
229
+ A refused connection establishes absence at this pre-launch boundary. A
230
+ Windows connect timeout requires independent exclusive-bind proof for every
231
+ resolved loopback address; a timeout alone never authorizes a probe. Other
232
+ unknown/denied states abstain. This affects automatic catalog polling only,
233
+ not command execution or explicit request/response capture.
234
+ """
235
+ if not os.environ.get(_SEMANTIC_ENV):
236
+ return _LiveProbeAdmission(None)
237
+ spec = _probe_spec(command)
238
+ if spec is None:
239
+ return _LiveProbeAdmission(None)
240
+ address = urlsplit(spec.endpoint)
241
+ try:
242
+ with socket.create_connection(
243
+ (str(address.hostname), int(address.port or 80)),
244
+ timeout=_PROBE_TIMEOUT_SECONDS,
245
+ ):
246
+ pass
247
+ except ConnectionRefusedError:
248
+ return _LiveProbeAdmission(spec)
249
+ except TimeoutError:
250
+ if windows_exclusive_endpoint_available(str(address.hostname), int(address.port or 80)):
251
+ return _LiveProbeAdmission(spec)
252
+ except OSError:
253
+ pass
254
+ print(
255
+ f"ExecWeave {spec.runtime} probe: endpoint {spec.endpoint} was not "
256
+ "proven unused before launch; automatic catalog evidence is disabled.",
257
+ file=sys.stderr,
258
+ )
259
+ return _LiveProbeAdmission(None)
260
+
261
+
217
262
  def _get_json(url: str, *, timeout: float) -> dict[str, object]:
218
263
  request = Request(url, headers={"Accept": "application/json"})
219
264
  with urlopen(request, timeout=timeout) as response:
@@ -462,10 +507,18 @@ def auto_specialized_launch(
462
507
 
463
508
 
464
509
  @contextmanager
465
- def auto_specialized_probe(command: list[str]) -> Iterator[None]:
466
- """Run supported local specialized probes without affecting command execution."""
510
+ def auto_specialized_probe(
511
+ command: list[str],
512
+ *,
513
+ admission: _LiveProbeAdmission | None = None,
514
+ ) -> Iterator[None]:
515
+ """Poll a prepared launch, or an explicitly requested library observation.
516
+
517
+ RuntimeCollector always supplies pre-launch admission. A direct library
518
+ caller without admission retains the explicit endpoint-observation API.
519
+ """
467
520
  configured_sidecar = os.environ.get(_SEMANTIC_ENV)
468
- spec = _probe_spec(command)
521
+ spec = admission.spec if admission is not None else _probe_spec(command)
469
522
  if not configured_sidecar or spec is None:
470
523
  yield
471
524
  return
@@ -16,6 +16,7 @@ from .auto_specialized import (
16
16
  auto_specialized_launch,
17
17
  auto_specialized_probe,
18
18
  prepare_post_command_specialized_probe,
19
+ prepare_live_specialized_probe,
19
20
  run_post_command_specialized_probe,
20
21
  )
21
22
  from .command import resolve_launch_command
@@ -209,6 +210,7 @@ class RuntimeCollector:
209
210
  collector_error_type: str | None = None
210
211
  workload_terminated_due_to_collector_error = False
211
212
  subreaper_previous: bool | None = None
213
+ live_probe_admission = prepare_live_specialized_probe(command)
212
214
  post_command_probe = prepare_post_command_specialized_probe(command)
213
215
  try:
214
216
  if watcher is not None:
@@ -235,7 +237,7 @@ class RuntimeCollector:
235
237
  if snapshot is not None:
236
238
  self._record_process_start(snapshot, parent=session, relation="LAUNCHED")
237
239
 
238
- with auto_specialized_probe(command):
240
+ with auto_specialized_probe(command, admission=live_probe_admission):
239
241
  while process.poll() is None:
240
242
  self._sample_process_tree(root)
241
243
  time.sleep(self.poll_interval)
@@ -549,6 +549,11 @@ class _LiveState:
549
549
  else _inject_final_theme(render_graph_html(final_graph))
550
550
  )
551
551
  with self._lock:
552
+ # The last browser poll may precede the collector's final batch.
553
+ # Drain complete runtime/semantic records for raw-log and evidence
554
+ # counters before publishing FINISHED. The canonical graph below,
555
+ # not the provisional accumulator, remains the graph authority.
556
+ self._refresh_incremental_locked()
552
557
  self._final_graph = final_graph
553
558
  self._final_html = rendered_final
554
559
  self._finished = True
@@ -563,6 +568,11 @@ class _LiveState:
563
568
  "edges_added": [],
564
569
  "edges_updated": [],
565
570
  "terminal": True,
571
+ # A counts-only terminal delta loses unpolled nodes/edges and
572
+ # canonical identity/metadata changes. Reconcile in this same
573
+ # sequence-visible response, before the client stops polling.
574
+ # Use the normal projection and payload budget, as on reconnect.
575
+ "final_graph": self._snapshot_from_accumulator_locked(),
566
576
  }
567
577
  if not _within_live_payload_budget(node_count, edge_count):
568
578
  terminal["live_payload_compact"] = True
@@ -254,16 +254,17 @@ function execweaveLayoutDirectedGraph(topo){
254
254
  }
255
255
  try{
256
256
  const graph=new engine.graphlib.Graph();
257
- graph.setGraph({rankdir:'LR',nodesep:EXECWEAVE_DAG_GAP,ranksep:48,marginx:16,marginy:16,edgesep:16});
257
+ graph.setGraph({rankdir:'LR',nodesep:EXECWEAVE_DAG_GAP,ranksep:48,marginx:0,marginy:16,edgesep:16});
258
258
  graph.setDefaultEdgeLabel(()=>({}));
259
259
  const ids=[];
260
- for(const id of topo.spec.keys()){
260
+ for(const id of [...topo.spec.keys()].sort()){
261
261
  if(!nodeById.has(id))continue;
262
262
  graph.setNode(id,{width:execweaveWidthOf(id),height:execweaveHeightOf(id)});
263
263
  ids.push(id);
264
264
  }
265
265
  const seen=new Set();
266
- for(const edge of edgeById.values()){
266
+ for(const edge of [...edgeById.values()].sort((a,b)=>edgeId(a).localeCompare(edgeId(b)))){
267
+ if(typeof execweaveIsStopped==='function'&&execweaveIsStopped(edge))continue;
267
268
  if(!topo.spec.has(edge.source)||!topo.spec.has(edge.target)||edge.source===edge.target)continue;
268
269
  const key=execweaveEdgeKey(edge.source,edge.target);
269
270
  if(seen.has(key))continue;
@@ -301,74 +302,24 @@ function execweaveRestoreSemanticLayoutConstraints(topo,preferred,dagrePlacement
301
302
  const nodes=[...nodeById.values()],edges=[...edgeById.values()];
302
303
  const componentOf=execweaveComponents(nodes,edges);
303
304
 
304
- // X constraint: Semantic lanes define bounding constraints.
305
- // Dynamically propagate corridor lower bounds across semantic ranks so Dagre
306
- // horizontal positions are retained within their architectural corridors.
307
- const laneRank = {
308
- runtime: 0,
309
- root: 1,
310
- agent: 2,
311
- model: 3,
312
- tool: 4,
313
- file: 5,
314
- endpoint: 6,
315
- other: 6
316
- };
317
-
318
- // Group non-process nodes by semantic rank
319
- const nodesByRank = new Map();
320
- for (const [id, before] of preferred) {
321
- const node = nodeById.get(id);
322
- if (!node) continue;
323
- const type = String(node.type || '').toLowerCase();
324
- if (type === 'process' || type === 'session' || type === 'runtime') continue;
325
- const lane = topo.spec.get(id)?.lane || before.lane || 'other';
326
- const rank = laneRank[lane] ?? 3;
327
- if (!nodesByRank.has(rank)) nodesByRank.set(rank, []);
328
- nodesByRank.get(rank).push(id);
329
- }
330
-
331
- // Handle process-like nodes first (pinned to process-tree coordinates)
332
- let maxProcessRight = 0;
333
- for (const [id, before] of preferred) {
334
- const after = topo.spec.get(id), node = nodeById.get(id);
335
- if (!after || !node) continue;
336
- const type = String(node.type || '').toLowerCase();
337
- if (type === 'process' || type === 'session' || type === 'runtime') {
338
- if (Number.isFinite(before.x)) after.x = before.x;
339
- const pw = topo.width?.get(id) || (typeof execweaveWidthOf === 'function' ? execweaveWidthOf(id) : 160);
340
- const px = Number.isFinite(after.x) ? after.x : 0;
341
- maxProcessRight = Math.max(maxProcessRight, px + pw);
342
- }
343
- }
344
-
345
- // Propagate corridor lower bounds across ranks:
346
- // rank 1 (root) < rank 2 (agent) < rank 3 (model) < rank 4 (tool) < rank 5 (file) < rank 6 (endpoint)
347
- let minAllowedX = maxProcessRight;
348
- for (let r = 1; r <= 6; r++) {
349
- const ids = nodesByRank.get(r) || [];
350
- if (!ids.length) continue;
351
- let rankMaxX = minAllowedX;
352
- for (const id of ids) {
353
- const after = topo.spec.get(id);
354
- const before = preferred.get(id);
355
- const dagreX = dagrePlacement.get(id)?.x;
356
- const laneX = topo.laneX && Number.isFinite(topo.laneX[after?.lane]) ? topo.laneX[after.lane] : before?.x;
357
- if (!after) continue;
358
-
359
- const isBundledTarget = edges.some(e => e.target === id && topo.bundleByEdge?.get(edgeId(e))?.size > 1);
360
- const candidateX = isBundledTarget && Number.isFinite(laneX) ? laneX : dagreX;
361
-
362
- if (Number.isFinite(candidateX) && candidateX >= minAllowedX) {
363
- after.x = candidateX;
364
- } else if (Number.isFinite(before?.x) && before.x >= minAllowedX) {
365
- after.x = before.x;
366
- } else {
367
- after.x = minAllowedX;
368
- }
369
- rankMaxX = Math.max(rankMaxX, after.x);
370
- }
371
- minAllowedX = rankMaxX + 1;
305
+ // Constrain X to measured semantic corridors. Dagre supplies ordering and route
306
+ // control points; process-tree depth is retained within the runtime corridor.
307
+ // All render paths consume these final coordinates, including Arrange.
308
+ let floor=-Infinity;
309
+ for(const [id,before] of preferred){
310
+ const after=topo.spec.get(id),node=nodeById.get(id);
311
+ if(!after||!node||!isProcess(node))continue;
312
+ after.x=before.x;
313
+ floor=Math.max(floor,after.x+(topo.width?.get(id)||EXECWEAVE_NODE_W)+PROCESS_COL_GAP);
314
+ }
315
+ for(const lane of ['root','agent','model','tool','file','endpoint','other']){
316
+ const ids=[...topo.spec.keys()].filter(id=>topo.spec.get(id)?.lane===lane&&!isProcess(nodeById.get(id)));
317
+ if(!ids.length)continue;
318
+ const laneX=Number.isFinite(topo.laneX?.[lane])?topo.laneX[lane]:Math.min(...ids.map(id=>preferred.get(id).x));
319
+ const x=Math.max(laneX,Number.isFinite(floor)?floor:laneX);
320
+ let right=x;
321
+ for(const id of ids){const after=topo.spec.get(id);after.x=x;right=Math.max(right,x+(topo.width?.get(id)||EXECWEAVE_NODE_W))}
322
+ floor=right+PROCESS_COL_GAP;
372
323
  }
373
324
 
374
325
  // Y constraint: Dagre coordinates optimize positions within semantic lane/component bounds
@@ -462,9 +413,15 @@ function execweaveRestoreSemanticLayoutConstraints(topo,preferred,dagrePlacement
462
413
  return{value,members,minX,maxX,minY,maxY,w:maxX-minX,h:maxY-minY};
463
414
  }).filter(box=>Number.isFinite(box.minX));
464
415
 
416
+ // Use an aspect-balanced shelf width for disconnected components instead of
417
+ // forcing every component wider than half a short spine onto its own row.
418
+ // Component shapes/ordering stay intact; this is packing, not raw graph repair.
419
+ const columns=Math.max(1,Math.ceil(Math.sqrt(compBoxes.length)));
420
+ const widest=compBoxes.reduce((width,box)=>Math.max(width,box.w),0);
421
+ const packingWidth=Math.max(spineWidth,columns*widest+(columns-1)*bandGap);
465
422
  let cursorX=spineLeft,cursorY=spineFloor+bandGap,rowHeight=0;
466
423
  for(const box of compBoxes){
467
- if(cursorX>spineLeft&&cursorX+box.w>spineLeft+spineWidth){
424
+ if(cursorX>spineLeft&&cursorX+box.w>spineLeft+packingWidth){
468
425
  cursorX=spineLeft;cursorY+=rowHeight+bandGap;rowHeight=0;
469
426
  }
470
427
  const shiftX=cursorX-box.minX,shiftY=cursorY-box.minY;
@@ -565,7 +522,13 @@ function execweaveRouteFromPoints(edge,points){
565
522
  return{d,labelX:labelPoint.x,labelY:labelPoint.y-8,kind:execweaveIsSpawn(edge)?'spawn':(forward?'forward':'reverse'),bundle:null};
566
523
  }
567
524
  const execweaveBuildTopologyBase=execweaveBuildTopology;
568
- execweaveBuildTopology=function(){return execweaveApplyDirectedGraph(execweaveLayoutRelated(execweaveLayoutProcessTree(execweaveBuildTopologyBase())))};
525
+ execweaveBuildTopology=function(){
526
+ // Width/height and lane helpers must see THIS build, never the previous graph.
527
+ const topo=execweaveBuildTopologyBase(),prior=execweaveTopology;
528
+ execweaveTopology=topo;
529
+ try{return execweaveApplyDirectedGraph(execweaveLayoutRelated(execweaveLayoutProcessTree(topo)))}
530
+ finally{execweaveTopology=prior}
531
+ };
569
532
  if(typeof window!=='undefined'){
570
533
  window.execweaveLayoutDirectedGraph=execweaveLayoutDirectedGraph;
571
534
  window.execweaveSeparateOverlappingNodes=execweaveSeparateOverlappingNodes;
@@ -653,13 +616,7 @@ function execweaveWriteDirectedPositions(topo){
653
616
  const next=new Map();
654
617
  for(const id of nodeById.keys()){
655
618
  const spec=topo.spec.get(id);
656
- const packed=topo.secondaryPackedIds?.has(id);
657
- const laneX=(topo.laneX&&spec?.lane&&Number.isFinite(topo.laneX[spec.lane]))?topo.laneX[spec.lane]:spec?.x;
658
- // Connected semantic lanes retain their established X contract. Only
659
- // disconnected components use the final 2D packing X; forcing those back
660
- // to the lane origin would stack every orphan node on the same rectangle.
661
- const initialX=packed?spec?.x:laneX;
662
- next.set(id,spec?{x:initialX,y:spec.y}:execweaveDesiredPosition(id));
619
+ next.set(id,spec?{x:spec.x,y:spec.y}:execweaveDesiredPosition(id));
663
620
  }
664
621
  positions=next;layerRows=new Map();
665
622
  for(const [id,p] of positions){
@@ -673,20 +630,19 @@ function execweaveWriteDirectedPositions(topo){
673
630
  for(const edge of edgeById.values())updateEdgeElement(edge);
674
631
  svg.classList.toggle('execweave-crowded',!!topo.crowded);
675
632
  }
676
- const execweaveFullLayoutBase=fullLayout;
677
- fullLayout=function(){
678
- const prior=positions;
679
- const incoming=[...nodeById.keys()].some(id=>!prior.has(id));
680
- if(prior.size&&!incoming){execweaveFullLayoutBase();return}
633
+ function execweaveInstallFinalLayout(priorY){
681
634
  execweaveTopology=execweaveBuildTopology();
682
635
  execweaveWriteDirectedPositions(execweaveTopology);
636
+ if(priorY.size&&typeof execweaveRestorePriorYUnlessWorse==='function'){
637
+ execweaveRestorePriorYUnlessWorse(priorY,execweaveTopology);
638
+ window.__execweavePr70.paint();
639
+ }
640
+ }
641
+ fullLayout=function(){
642
+ execweaveInstallFinalLayout(new Map([...positions].map(([id,p])=>[id,p.y])));
683
643
  };
684
- const execweavePlaceAddedBase=placeAddedNodes;
685
- placeAddedNodes=function(ids){
686
- const incoming=(ids||[]).filter(id=>nodeById.has(id)&&!positions.has(id));
687
- if(!incoming.length){execweavePlaceAddedBase(ids);return}
688
- execweaveTopology=execweaveBuildTopology();
689
- execweaveWriteDirectedPositions(execweaveTopology);
644
+ placeAddedNodes=function(_ids){
645
+ execweaveInstallFinalLayout(new Map([...positions].map(([id,p])=>[id,p.y])));
690
646
  };
691
647
  })();
692
648
  """.strip()
@@ -12,7 +12,7 @@ function updateJumpLatest(){jumpLatest.hidden=!latestNodeId||latestInsideSafeZon
12
12
  function userTookCamera(){if(cameraMode!=='manual')setCameraMode('manual',{apply:false})}
13
13
  function zoomBy(factor){userTookCamera();const box=svg.getBoundingClientRect(),mx=box.width/2,my=box.height/2,old=transform.scale,nextScale=Math.min(4,Math.max(.07,old*factor)),gx=(mx-transform.x)/old,gy=(my-transform.y)/old;animateTo({x:mx-gx*nextScale,y:my-gy*nextScale,scale:nextScale},140)}
14
14
  function applySearch(){const q=search.value.trim().toLowerCase(),matched=new Set();document.querySelectorAll('.node').forEach(el=>{const ok=!q||el.dataset.search.includes(q);el.classList.toggle('dim',!ok);if(ok)matched.add(el.dataset.id)});document.querySelectorAll('.edge').forEach(el=>{const keep=!q||matched.has(el.dataset.source)||matched.has(el.dataset.target)||el.dataset.relation.includes(q);el.classList.toggle('dim',!keep)})}
15
- async function poll(){try{const response=await fetch(`/live.json?after=${liveSequence}`,{cache:'no-store'});if(!response.ok)throw new Error(String(response.status));const data=await response.json();if(data.kind==='snapshot'){liveSequence=Number(data.sequence)||0;setSnapshot(data.graph||{});}else if(data.kind==='delta'){if(Number(data.base_sequence)!==liveSequence){liveSequence=-1;setStatus('RESYNCING','resyncing');setTimeout(poll,0);return}for(const update of data.updates||[]){if(Number(update.sequence)!==liveSequence+1){liveSequence=-1;setStatus('RESYNCING','resyncing');setTimeout(poll,0);return}applyDelta(update);liveSequence=Number(update.sequence)}if(!(data.updates||[]).length)liveSequence=Number(data.sequence)||liveSequence;}else if(data.kind==='noop'){liveSequence=Number(data.sequence)||liveSequence;updateStats(data);}window.__execweaveDashboard?.onPayload?.(data);updateEvidence(data);const finished=!!data.live_finished;setStatus(finished?'FINISHED':(protectedMode?'PROTECTED':'LIVE'),finished?'finished':protectedMode?'reconnecting':'');if(finished){window.__execweaveDashboard?.onFinished?.();return}}catch(_){setStatus('RECONNECTING','reconnecting')}setTimeout(poll,500)}
15
+ async function poll(){try{const response=await fetch(`/live.json?after=${liveSequence}`,{cache:'no-store'});if(!response.ok)throw new Error(String(response.status));const data=await response.json();if(data.kind==='snapshot'){liveSequence=Number(data.sequence)||0;setSnapshot(data.graph||{});}else if(data.kind==='delta'){if(Number(data.base_sequence)!==liveSequence){liveSequence=-1;setStatus('RESYNCING','resyncing');setTimeout(poll,0);return}for(const update of data.updates||[]){if(Number(update.sequence)!==liveSequence+1){liveSequence=-1;setStatus('RESYNCING','resyncing');setTimeout(poll,0);return}if(update.terminal&&update.final_graph)setSnapshot(update.final_graph);else applyDelta(update);liveSequence=Number(update.sequence)}if(!(data.updates||[]).length)liveSequence=Number(data.sequence)||liveSequence;}else if(data.kind==='noop'){liveSequence=Number(data.sequence)||liveSequence;updateStats(data);}window.__execweaveDashboard?.onPayload?.(data);updateEvidence(data);const finished=!!data.live_finished;setStatus(finished?'FINISHED':(protectedMode?'PROTECTED':'LIVE'),finished?'finished':protectedMode?'reconnecting':'');if(finished){window.__execweaveDashboard?.onFinished?.();return}}catch(_){setStatus('RECONNECTING','reconnecting')}setTimeout(poll,500)}
16
16
  svg.onpointerdown=e=>{if(e.target.closest?.('.node'))return;userTookCamera();stopAnimation();pan={x:e.clientX,y:e.clientY,tx:transform.x,ty:transform.y,travelled:false};svg.classList.add('panning');svg.setPointerCapture(e.pointerId)};svg.onpointermove=e=>{if(!pan)return;if(Math.abs(e.clientX-pan.x)>3||Math.abs(e.clientY-pan.y)>3)pan.travelled=true;transform.x=pan.tx+e.clientX-pan.x;transform.y=pan.ty+e.clientY-pan.y;applyTransform();updateJumpLatest()};svg.onpointerup=e=>{const dragged=!!pan?.travelled;pan=null;svg.classList.remove('panning');try{svg.releasePointerCapture(e.pointerId)}catch(_){}if(!dragged&&!e.target.closest?.('.node'))window.__execweaveClearFocus?.()};svg.addEventListener('wheel',e=>{e.preventDefault();userTookCamera();stopAnimation();const rect=svg.getBoundingClientRect(),mx=e.clientX-rect.left,my=e.clientY-rect.top,old=transform.scale,next=Math.min(4,Math.max(.07,old*Math.exp(-e.deltaY*.0012))),gx=(mx-transform.x)/old,gy=(my-transform.y)/old;transform.scale=next;transform.x=mx-gx*next;transform.y=my-gy*next;applyTransform();updateJumpLatest()},{passive:false});
17
17
  function focusRawLogEvent(event){const target=event?.target?.id,source=event?.source?.id;if(target&&nodeById.has(target)){selectNode(target,{syncLog:false});focusNode(target);return}if(source&&nodeById.has(source)){selectNode(source,{syncLog:false});focusNode(source)}}
18
18
  // Focus is only exitable if something offers the exit. The control appears with the
@@ -0,0 +1,44 @@
1
+ """Conservative Winsock fallback for a timed-out pre-launch loopback connect."""
2
+ from __future__ import annotations
3
+
4
+ import ipaddress
5
+ import socket
6
+ import sys
7
+ from contextlib import ExitStack
8
+
9
+
10
+ def windows_exclusive_endpoint_available(host: str, port: int) -> bool:
11
+ """Require exclusive binds, not a timeout, as evidence of unused addresses.
12
+
13
+ A short Windows connect can time out before an unused port reports refusal.
14
+ SO_EXCLUSIVEADDRUSE prevents taking over an existing bind. Every resolved
15
+ loopback address must be exclusively bindable at the same instant; sockets
16
+ are closed before the real relay/child starts. No listener is created and no
17
+ SO_REUSEADDR is enabled. This proves availability only at the launch boundary,
18
+ not ownership of an unrelated service started later.
19
+ """
20
+ exclusive = getattr(socket, 'SO_EXCLUSIVEADDRUSE', None)
21
+ if sys.platform != 'win32' or exclusive is None or not 0 < port <= 65535:
22
+ return False
23
+ try:
24
+ addresses = socket.getaddrinfo(host, port, type=socket.SOCK_STREAM,
25
+ proto=socket.IPPROTO_TCP)
26
+ seen = set()
27
+ with ExitStack() as stack:
28
+ for family, kind, protocol, _, address in addresses:
29
+ if family not in (socket.AF_INET, socket.AF_INET6):
30
+ return False
31
+ if not ipaddress.ip_address(address[0]).is_loopback:
32
+ return False
33
+ key = (family, address)
34
+ if key in seen:
35
+ continue
36
+ seen.add(key)
37
+ reservation = stack.enter_context(socket.socket(family, kind, protocol))
38
+ reservation.setsockopt(socket.SOL_SOCKET, exclusive, 1)
39
+ if family == socket.AF_INET6:
40
+ reservation.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)
41
+ reservation.bind(address)
42
+ return bool(seen)
43
+ except (OSError, ValueError):
44
+ return False
@@ -69,6 +69,12 @@ class TerminalState:
69
69
 
70
70
  def apply_update(self, update: dict[str, object]) -> None:
71
71
  self.sequence = int(update.get("sequence", self.sequence) or self.sequence)
72
+ final_graph = update.get("final_graph")
73
+ if update.get("terminal") and isinstance(final_graph, dict):
74
+ # The web client and Top must consume the same authoritative final
75
+ # entities, including canonical identity replacement, before stopping.
76
+ self.apply_snapshot(final_graph, self.sequence)
77
+ return
72
78
  self.event_count = int(update.get("event_count", self.event_count) or 0)
73
79
  self.node_count = int(update.get("node_count", self.node_count) or 0)
74
80
  self.edge_count = int(update.get("edge_count", self.edge_count) or 0)
@@ -56,9 +56,22 @@ execweaveDashboardGraph=function(data){
56
56
  }
57
57
  const ollamaRoots=prepared.filter(node=>node?.type==='agent'&&['agent:Ollama','agent:ollama'].includes(String(node.id||'')));
58
58
  const ollamaRuntimes=prepared.filter(node=>node?.type==='model_runtime'&&String(node?.attributes?.provider||'').toLowerCase()==='ollama');
59
- if(ollamaRoots.length===1&&ollamaRuntimes.length===1){
60
- const root=ollamaRoots[0],runtime=ollamaRuntimes[0];presentationAlias.set(runtime.id,root.id);
61
- prepared=prepared.filter(node=>node.id!==runtime.id).map(node=>node.id===root.id?{...node,name:'/root'}:node);
59
+ const runtimeContextSupport=new Map();
60
+ // Same provider/cardinality does not establish runtime ownership. Compress a
61
+ // context only when an explicit, unambiguous agent->runtime observation exists.
62
+ // Otherwise retain the runtime and its original catalog edges, including old
63
+ // failed-launch artifacts that contain observations of a pre-existing server.
64
+ for(const runtime of ollamaRuntimes){
65
+ const incoming=(projected.edges||[]).filter(e=>e?.target===runtime.id&&prepared.some(n=>n.id===e.source&&n.type==='agent'));
66
+ const owners=[...new Set(incoming.map(e=>e.source))];
67
+ const root=owners.length===1?ollamaRoots.find(n=>n.id===owners[0]):null;
68
+ const support=incoming.filter(e=>e.relation==='OBSERVED_MODEL_RUNTIME');
69
+ const conflict=(a,b)=>['provider','run_id','session_id','conversation_id','provider_session_id','agent_path'].some(k=>
70
+ a?.[k]&&b?.[k]&&String(a[k])!==String(b[k]));
71
+ const identities=[runtime.attributes||{},root?.attributes||{},...incoming.map(e=>e.attributes||{})];
72
+ if(!root||!support.length||identities.some((a,i)=>identities.slice(0,i).some(b=>conflict(a,b))))continue;
73
+ presentationAlias.set(runtime.id,root.id);runtimeContextSupport.set(runtime.id,support);
74
+ prepared=prepared.filter(node=>node.id!==runtime.id);
62
75
  }
63
76
  const normalized=value=>String(value||'').trim().replaceAll('\\\\','/').replace(/\/+$/,'').toLowerCase();
64
77
  const canonicalKey=node=>{
@@ -85,10 +98,15 @@ execweaveDashboardGraph=function(data){
85
98
  const remapped=[];for(const edge of(projected.edges||[])){
86
99
  if(!edge)continue;const source=canonicalId.get(edge.source)||edge.source,target=canonicalId.get(edge.target)||edge.target;
87
100
  if(!ids.has(source)||!ids.has(target)||source===target)continue;
88
- remapped.push(source===edge.source&&target===edge.target?edge:{...edge,source,target,viewer_canonicalized:true,viewer_original_source:edge.source,viewer_original_target:edge.target});
101
+ const support=runtimeContextSupport.get(edge.source);
102
+ if(support){
103
+ remapped.push({...edge,source,target,viewer_only:true,inferred:true,causal:false,
104
+ viewer_runtime_context:true,viewer_original_source:edge.source,viewer_original_target:edge.target,
105
+ viewer_supporting_edges:[...support,edge]});
106
+ }else remapped.push(source===edge.source&&target===edge.target?edge:{...edge,source,target,viewer_canonicalized:true,viewer_original_source:edge.source,viewer_original_target:edge.target});
89
107
  }
90
108
  const edgeGroups=new Map();
91
- for(const edge of remapped){const key=`${edge.source}\u0000${edge.relation||''}\u0000${edge.target}`,existing=edgeGroups.get(key);if(!existing){edgeGroups.set(key,{...edge,viewer_edge_occurrence_count:1,viewer_edge_occurrence_ids:[edge.id]});continue}existing.viewer_edge_occurrence_count+=1;existing.viewer_edge_occurrence_ids.push(edge.id);existing.count=Number(existing.count||1)+Number(edge.count||1);if(Number.isInteger(edge.first_sequence))existing.first_sequence=Number.isInteger(existing.first_sequence)?Math.min(existing.first_sequence,edge.first_sequence):edge.first_sequence;if(Number.isInteger(edge.last_sequence))existing.last_sequence=Number.isInteger(existing.last_sequence)?Math.max(existing.last_sequence,edge.last_sequence):edge.last_sequence;existing.first_seen=earlier(existing.first_seen,edge.first_seen);existing.last_seen=later(existing.last_seen,edge.last_seen)}
109
+ for(const edge of remapped){const key=`${edge.source}\u0000${edge.relation||''}\u0000${edge.target}${edge.viewer_runtime_context?'\u0000'+edge.viewer_original_source:''}`,existing=edgeGroups.get(key);if(!existing){edgeGroups.set(key,{...edge,viewer_edge_occurrence_count:1,viewer_edge_occurrence_ids:[edge.id]});continue}existing.viewer_edge_occurrence_count+=1;existing.viewer_edge_occurrence_ids.push(edge.id);existing.count=Number(existing.count||1)+Number(edge.count||1);if(Number.isInteger(edge.first_sequence))existing.first_sequence=Number.isInteger(existing.first_sequence)?Math.min(existing.first_sequence,edge.first_sequence):edge.first_sequence;if(Number.isInteger(edge.last_sequence))existing.last_sequence=Number.isInteger(existing.last_sequence)?Math.max(existing.last_sequence,edge.last_sequence):edge.last_sequence;existing.first_seen=earlier(existing.first_seen,edge.first_seen);existing.last_seen=later(existing.last_seen,edge.last_seen)}
92
110
  const edges=[...edgeGroups.values()];
93
111
  return{...projected,nodes,edges,node_count:nodes.length,edge_count:edges.length,dashboard_projection:{...(projected.dashboard_projection||{}),hidden_context_node_count:before.length-prepared.length,merged_context_node_count:mergedContextNodeCount,hidden_orphan_file_node_count:0}};
94
112
  };