execweave 0.8.14__tar.gz → 0.8.16__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.
- {execweave-0.8.14 → execweave-0.8.16}/.github/workflows/provider-capability-stage-integrity.yml +27 -0
- {execweave-0.8.14 → execweave-0.8.16}/PKG-INFO +12 -1
- {execweave-0.8.14 → execweave-0.8.16}/README.md +9 -0
- {execweave-0.8.14 → execweave-0.8.16}/pyproject.toml +4 -2
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/__init__.py +1 -1
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/collector.py +82 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/live_view.py +0 -27
- execweave-0.8.16/src/execweave/live_view_script_d.py +40 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/live_view_style.py +2 -1
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_dashboard_clean.py +37 -13
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_dashboard_hardening_v2.py +1 -22
- execweave-0.8.16/src/execweave/viewer_gif.py +232 -0
- execweave-0.8.16/tests/test_d003_fast_reparent.py +134 -0
- execweave-0.8.16/tests/test_dashboard_file_activity_filter.py +30 -0
- execweave-0.8.16/tests/test_dashboard_gif_export_e2e.py +280 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_live_logs_export.py +3 -2
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_pr25_premerge_hardening_contract.py +3 -8
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_threat_model.py +2 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_v069_dashboard_release.py +32 -53
- execweave-0.8.14/src/execweave/live_view_script_d.py +0 -47
- execweave-0.8.14/tests/test_dashboard_gif_export_e2e.py +0 -108
- {execweave-0.8.14 → execweave-0.8.16}/.github/workflows/ci.yml +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/.github/workflows/cleanup-workflow-history.yml +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/.github/workflows/i18n.yml +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/.github/workflows/package-benchmark.yml +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/.github/workflows/package-smoke.yml +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/.github/workflows/provider-dashboard-contract.yml +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/.github/workflows/publish.yml +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/.github/workflows/scalability.yml +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/.github/workflows/viewer-agent-isolation.yml +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/.github/workflows/wheel-smoke.yml +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/.github/workflows/windows-launcher.yml +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/.gitignore +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/LICENSE +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/README.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/README.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/README.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/README.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/README.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/README.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/README.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/benchmarks/phase1_overhead.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/diagnostics/acceptance_hardening_20260906.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/diagnostics/audit_eight_children.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/diagnostics/audit_python_journey.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/diagnostics/audit_real_clicks.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/diagnostics/current_state_reaudit.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/diagnostics/execweave_full_audit.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/diagnostics/gate_status.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/diagnostics/gate_status_history_through_g3.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/diagnostics/github_pr_inventory.json +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/diagnostics/handoff_checkpoint_20260906.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/diagnostics/next_agent_handoff.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/diagnostics/pr_regression_map.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/antigravity-hooks.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/assets/codex.gif +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/benchmarks/README.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/benchmarks/v0.6.0-github-actions.json +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/benchmarks/v0.6.0-github-actions.svg +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/claude-code-hooks.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/claude-code-hooks.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/claude-code-hooks.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/claude-code-hooks.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/claude-code-hooks.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/claude-code-hooks.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/claude-code-hooks.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/claude-code-hooks.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/codex-hooks.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/codex-hooks.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/codex-hooks.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/codex-hooks.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/codex-hooks.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/codex-hooks.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/codex-hooks.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/codex-hooks.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/cursor-hooks.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/cursor-hooks.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/cursor-hooks.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/cursor-hooks.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/cursor-hooks.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/cursor-hooks.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/cursor-hooks.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/cursor-hooks.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/evidence-grades.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/evidence-grades.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/evidence-grades.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/evidence-grades.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/evidence-grades.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/evidence-grades.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/evidence-grades.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/evidence-grades.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/inference-gateway.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/inference-gateway.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/inference-gateway.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/inference-gateway.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/inference-gateway.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/inference-gateway.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/inference-gateway.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/inference-gateway.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/internal/provider-capability-matrix.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/live-graph.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/live-graph.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/live-graph.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/live-graph.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/live-graph.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/live-graph.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/live-graph.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/live-graph.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/model-runtime.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/model-runtime.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/model-runtime.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/model-runtime.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/model-runtime.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/model-runtime.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/model-runtime.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/model-runtime.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/opencode-plugin.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/opencode-plugin.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/opencode-plugin.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/opencode-plugin.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/opencode-plugin.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/opencode-plugin.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/opencode-plugin.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/opencode-plugin.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-1-runtime-collection.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-1-runtime-collection.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-1-runtime-collection.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-1-runtime-collection.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-1-runtime-collection.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-1-runtime-collection.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-1-runtime-collection.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-1-runtime-collection.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-2-execution-graph.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-2-execution-graph.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-2-execution-graph.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-2-execution-graph.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-2-execution-graph.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-2-execution-graph.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-2-execution-graph.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/phase-2-execution-graph.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/remaining-provider-audit-v0.8.7.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/rule-packs.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/rule-packs.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/rule-packs.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/rule-packs.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/rule-packs.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/rule-packs.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/rule-packs.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/rule-packs.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/run-integrity.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/run-integrity.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/run-integrity.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/run-integrity.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/run-integrity.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/run-integrity.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/run-integrity.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/run-integrity.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/runtime-threat-model.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/runtime-threat-model.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/runtime-threat-model.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/runtime-threat-model.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/runtime-threat-model.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/runtime-threat-model.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/runtime-threat-model.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/runtime-threat-model.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/security-analysis.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/security-analysis.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/security-analysis.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/security-analysis.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/security-analysis.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/security-analysis.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/security-analysis.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/security-analysis.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/semantic-telemetry.de.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/semantic-telemetry.fr.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/semantic-telemetry.ja.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/semantic-telemetry.ko.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/semantic-telemetry.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/semantic-telemetry.ru.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/semantic-telemetry.zh-CN.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/semantic-telemetry.zh-TW.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/v0.6.5-hardening-decisions.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/docs/v0.8.3-graph-ergonomics.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/_check_release_stage_integrity_impl.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/_dashboard_acceptance_impl.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/_ollama_interactive_acceptance_impl.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/_ollama_visible_acceptance_impl.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/_python_native_acceptance_impl.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/acceptance/__init__.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/acceptance/browser_diagnostics.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/acceptance/contracts.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/acceptance/g5_runner.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/acceptance/g6_runner.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/acceptance/interrupt_guard.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/acceptance/processes.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/acceptance/reporting.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/acceptance/terminal_output.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/annotate_pytest_failures.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/audit_i18n_parity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/check_claude_hook.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/check_claude_record_graph.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/check_codex_hook.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/check_conversation_records.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/check_correlation_graph.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/check_inference_gateway_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/check_model_runtime_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/check_openai_compatible_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/check_release_stage_integrity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/check_semantic_graph.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/check_viewer_js.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/check_wheel_install.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/check_windows_launchers.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/dashboard_acceptance.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/emit_claude_hook_smoke.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/emit_codex_hook_smoke.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/emit_cursor_hook_smoke.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/emit_opencode_plugin_smoke.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/make_semantic_smoke.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/measure_graph_metrics.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/ollama_interactive_acceptance.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/ollama_visible_acceptance.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/owned_cleanup_acceptance.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/probe_provider_capability.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/python_native_acceptance.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/scripts/sync_i18n_nav.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/__main__.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/_conversation_records_core.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/_dashboard_shell_base.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/_http_proxy_base.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/_http_proxy_bounded.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/_http_proxy_stage.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/agent_bootstrap.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/agent_topology.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/agent_trace.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/agy_preview_sanitize.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/analysis.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/anthropic.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/anthropic_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/anthropic_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/antigravity_adapter.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/antigravity_adapter_base.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/antigravity_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/antigravity_full_fidelity_base.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/antigravity_full_fidelity_collaboration_base.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/antigravity_hook_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/antigravity_record.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/antigravity_subagent_linkage.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/antigravity_trace_capability.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/auto_specialized.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/backends.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/benchmark.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/claude_adapter.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/claude_child_transcript.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/claude_delegation.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/claude_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/claude_hook_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/claude_hook_contract.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/claude_model_observer.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/claude_record.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/codex_adapter.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/codex_conversation.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/codex_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/codex_hook_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/codex_hook_entry.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/codex_hook_lifecycle.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/codex_message_diagnostics.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/codex_message_transport_diagnostics.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/codex_record.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/codex_rollout_structures.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/codex_rollout_trace.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/codex_rollout_trace_base.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/command.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/content_evidence.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/content_store.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_archive.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_message_identity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_preview.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_preview_antigravity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_preview_claude.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_preview_codex.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_preview_common.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_preview_generic.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_preview_lines.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_preview_transcript.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_records.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_records_antigravity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_records_codex.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_records_common.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/conversation_records_ollama.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/correlation.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/cursor_adapter.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/cursor_delegation.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/cursor_delegation_base.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/cursor_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/cursor_hook_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/cursor_hook_contract.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/cursor_record.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/dashboard_shell.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/entry.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/evidence_availability.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/evidence_grade.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/filesystem.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/focus.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/graph.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/graph_ops.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/http_proxy.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/http_proxy_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/inference_gateway.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/inference_gateway_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/inference_gateway_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/inference_identity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/inference_identity_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/integrity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/integrity_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/litellm_callback.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/litellm_callback_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/live.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/live_core.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/live_view_extra_style.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/live_view_markup.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/live_view_process_layout.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/live_view_readability.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/live_view_script_a.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/live_view_script_b.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/live_view_script_c.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/model_runtime.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/model_runtime_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/model_runtime_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/openai_compatible.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/openai_compatible_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/openai_compatible_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/opencode_adapter.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/opencode_event_contract.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/opencode_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/opencode_hook_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/opencode_plugin_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/opencode_record.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/opencode_task_linkage.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/overhead_benchmark.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/provider_capability.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/provider_lifecycle.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/provider_record.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/rule_pack.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/rule_pack_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/scalability_benchmark.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/schema.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/scope.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/semantic.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/sink.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/strace_backend.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/stream_assembly.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/theme.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/top.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/top_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/validate.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/vendor/dagre.min.js +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/view_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_agent_panel.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_agent_panel_antigravity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_agent_panel_claude.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_agent_panel_codex.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_agent_panel_cursor.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_agent_panel_default.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_agent_panel_ollama.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_agent_panel_opencode.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_agent_panel_registry.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_content_inspector.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_dashboard_focus.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_dashboard_hardening.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_external_endpoints.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_limits.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_live_layout.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_projection.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_projection_base.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/viewer_semantic_projection.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/src/execweave/workflow.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/dashboard_readability_fixture.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/fixtures/codex_multi_agent/PROVENANCE.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/fixtures/codex_multi_agent/hook-payloads.json +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/fixtures/codex_multi_agent/rollout-main.jsonl +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/fixtures/hooks/README.md +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/fixtures/hooks/claude.json +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/fixtures/hooks/codex.json +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/fixtures/hooks/cursor.json +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/fixtures/hooks/manifest.json +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/fixtures/hooks/opencode.json +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/multi_agent_run_fixture.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_acceptance_browser_diagnostics_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_acceptance_conpty_selection.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_acceptance_interrupt_guard.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_acceptance_owned_processes.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_acceptance_required_capabilities.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_acceptance_terminal_output.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_acceptance_visible_pipe.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_agent_bootstrap.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_agent_message_viewer.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_agent_node_labels.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_agent_said_panel.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_agent_topology_evidence.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_agent_trace_lifecycle.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_agent_trace_viewer_visibility.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_agy_windows_wire_acceptance.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_analysis.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_anthropic.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_agent_collaboration.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_child_panel_policy.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_child_transcript_tools.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_cursor_launch.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_field_run_regressions.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_history_replay.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_identity_topology.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_invocation_archive.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_lifecycle.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_linkage_projection.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_multi_conversation_isolation.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_official_contract.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_role_path_fallback.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_root_child_history_v2.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_subagent_transcript_linkage.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_antigravity_trace_capability_cli.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_auto_specialized.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_auto_specialized_ollama_two_phase.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_backends.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_claude_adapter.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_claude_child_transcript_tools.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_claude_delegation.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_claude_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_claude_hook_contract.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_claude_hook_metadata.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_claude_hook_viewer.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_claude_model_observer.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_claude_record.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_cleanup_finalizer_identity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_adapter.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_archive_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_child_panel_policy.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_conversation_isolation.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_hook_global_fail_open.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_hook_lifecycle.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_hook_partial_capture.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_interrupt_contract.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_message_diagnostics.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_message_transport_diagnostics.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_nickname_path_fallback.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_plain_routed_agent_message.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_real_multi_agent_conversation.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_record.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_reducer_command.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_rollout_structures.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_rollout_trace.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_codex_routing_native_identity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_collector.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_command.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_condense.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_conversation_access.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_conversation_agent_focus.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_conversation_agent_isolation.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_conversation_identity_merge.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_conversation_message_observation_dedupe.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_conversation_provider_parity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_conversation_root_authority.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_correlation.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_correlation_canonical_path.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_correlation_checker.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_correlation_process_exe.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_cross_provider_agent_trace.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_cursor_adapter.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_cursor_delegation.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_cursor_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_cursor_hook_contract.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_cursor_hook_fail_open.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_cursor_ollama_session_lifecycle.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_cursor_record.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_cursor_task_linkage.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_dagre_semantic_pipeline.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_dashboard_acceptance_relative_output_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_dashboard_acceptance_reporting.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_dashboard_camera_scheduler_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_dashboard_favicon.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_dashboard_information_architecture.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_dashboard_initial_fit_readability_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_dashboard_node_drag_camera_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_dashboard_readability_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_dashboard_round_fold_state_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_dashboard_simplification.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_dashboard_ux_and_hook_projection.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_delegation_viewer.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_evidence_grade.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_execution_viewer.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_external_endpoints_all_providers.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_filesystem_resilience.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_focus.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_fold_budget_setting.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_g5_hardening_contract.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_g6_owned_parity_contract.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_graph.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_graph_arrange_constraints_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_graph_clear_focus_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_graph_edge_routing_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_graph_lane_separation_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_graph_node_sizing_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_graph_ops.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_hook_fixture_corpus.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_http_proxy.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_http_proxy_request_phase.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_http_proxy_response_memory.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_http_proxy_streaming.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_i18n_readme_policy.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_inference_endpoint_identity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_inference_gateway.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_inference_gateway_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_inference_identity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_integrity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_litellm_callback.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_live.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_live_auth.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_live_dashboard.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_live_dashboard_js.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_live_delta.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_live_theme.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_lmstudio_auto_specialized.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_local_runtime_live_capture.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_model_runtime.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_model_runtime_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_ollama_interactive_acceptance.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_ollama_interactive_terminal_semantics.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_ollama_panel_policy.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_ollama_serve_runtime_integration.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_ollama_visible_acceptance.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_openai_compatible.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_opencode_adapter.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_opencode_event_contract.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_opencode_event_lifecycle.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_opencode_full_fidelity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_opencode_identity_unification.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_opencode_plugin.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_opencode_record.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_opencode_task_session_linkage.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_overhead_benchmark.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_per_agent_conversation_default.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_pr25_premerge_hardening_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_pro6_audit_regressions.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_process_tree_layout.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_provider_capability.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_provider_conversation_evidence.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_provider_conversation_history_integrity.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_provider_dashboard_contract.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_provider_lifecycle.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_provider_neutral_viewer_semantics.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_pypi_0812_regressions.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_pypi_0813_cleanup.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_python_native_acceptance.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_relay_prompt_live_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_release_stage_integrity_version_guard.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_rule_pack.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_schema.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_scope.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_semantic.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_shared_injected_context_scope.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_single_agent_barycenter.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_strace_backend.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_stream_assembly.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_tool_traffic_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_top_detached.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_v063_features.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_v064_live_auto_integrations.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_v064_live_evidence.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_v079_review_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_v079_review_regressions.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_v083_release_gate_p2.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_validate.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_version.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_viewer.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_viewer_agent_isolation_e2e.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_viewer_child_authority.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_viewer_content_inspector.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_viewer_limits.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_viewer_projection.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_visual_ux_readability.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_windows_codex_agy_display_repair.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tests/test_workflow.py +0 -0
- {execweave-0.8.14 → execweave-0.8.16}/tools/verify_metrics_tool.py +0 -0
{execweave-0.8.14 → execweave-0.8.16}/.github/workflows/provider-capability-stage-integrity.yml
RENAMED
|
@@ -78,6 +78,33 @@ jobs:
|
|
|
78
78
|
&& -n "$model_runtime_identity_changed" ]]; then
|
|
79
79
|
args+=(--allow-test-change "tests/test_model_runtime.py=AUD-002 only: the historical llama.cpp request ID assertion now includes the sanitized endpoint scope; the test node ID and runtime privacy contract are unchanged")
|
|
80
80
|
fi
|
|
81
|
+
threat_model_changed=""
|
|
82
|
+
if git diff --name-only "$BASELINE_REF...HEAD" \
|
|
83
|
+
| grep -qx 'tests/test_threat_model.py'; then
|
|
84
|
+
threat_model_changed=yes
|
|
85
|
+
fi
|
|
86
|
+
if [[ "$HEAD_REF" == "fix/0815-threat-model-pid-collision" \
|
|
87
|
+
&& -n "$threat_model_changed" ]]; then
|
|
88
|
+
args+=(--allow-test-change "tests/test_threat_model.py=0.8.15 RC follow-up makes the existing outliving-child assertion hermetic against ambient host PID collisions; the historical test node ID and product expectation are unchanged")
|
|
89
|
+
fi
|
|
90
|
+
if [[ "$HEAD_REF" == "fix/gif-dashboard-parity" ]]; then
|
|
91
|
+
while IFS= read -r path; do
|
|
92
|
+
case "$path" in
|
|
93
|
+
tests/test_dashboard_gif_export_e2e.py)
|
|
94
|
+
args+=(--allow-test-change "$path=GIF export now records the real displayed SVG timeline instead of reconstructing animation from the final graph; the historical repeatable-download test node ID is retained and new screenshot-to-decoded-frame parity regressions are added")
|
|
95
|
+
;;
|
|
96
|
+
tests/test_live_logs_export.py)
|
|
97
|
+
args+=(--allow-test-change "$path=the GIF contract now requires captureGifFrame and forbids the retired sortedGifSteps reconstruction path; historical test node IDs remain unchanged")
|
|
98
|
+
;;
|
|
99
|
+
tests/test_pr25_premerge_hardening_contract.py)
|
|
100
|
+
args+=(--allow-test-change "$path=GIF export now freezes measured SVG geometry directly, so the historical hardening assertion must reject the old separate drawGifFrame renderer while retaining the same test node ID")
|
|
101
|
+
;;
|
|
102
|
+
tests/test_v069_dashboard_release.py)
|
|
103
|
+
args+=(--allow-test-change "$path=the GIF encoder changed from the historical fixed-code replay implementation to the recorded-SVG encoder and is now validated through an independent GIF decoder; release/version assertions and historical test node IDs remain intact")
|
|
104
|
+
;;
|
|
105
|
+
esac
|
|
106
|
+
done < <(git diff --name-only "$BASELINE_REF...HEAD" -- tests)
|
|
107
|
+
fi
|
|
81
108
|
if [[ "$HEAD_REF" == "fix/provider-isolation" ]]; then
|
|
82
109
|
while IFS= read -r path; do
|
|
83
110
|
case "$path" in
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: execweave
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.16
|
|
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
|
|
@@ -42,10 +42,12 @@ Requires-Python: >=3.10
|
|
|
42
42
|
Requires-Dist: psutil>=5.9
|
|
43
43
|
Requires-Dist: watchdog>=4.0
|
|
44
44
|
Provides-Extra: dev
|
|
45
|
+
Requires-Dist: pillow>=10.0; extra == 'dev'
|
|
45
46
|
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
46
47
|
Requires-Dist: pywinpty<4,>=3.0.5; (platform_system == 'Windows') and extra == 'dev'
|
|
47
48
|
Requires-Dist: ruff<0.17,>=0.16; extra == 'dev'
|
|
48
49
|
Provides-Extra: e2e
|
|
50
|
+
Requires-Dist: pillow>=10.0; extra == 'e2e'
|
|
49
51
|
Requires-Dist: playwright>=1.44; extra == 'e2e'
|
|
50
52
|
Requires-Dist: pywinpty<4,>=3.0.5; (platform_system == 'Windows') and extra == 'e2e'
|
|
51
53
|
Provides-Extra: release
|
|
@@ -188,6 +190,15 @@ The dashboard is designed to keep large, multi-agent runs inspectable without ch
|
|
|
188
190
|
- **Large-run folding:** high-cardinality node types can collapse older members while keeping them inspectable.
|
|
189
191
|
- **Selection-focused layout:** selecting an agent or runtime object de-emphasizes unrelated graph traffic.
|
|
190
192
|
|
|
193
|
+
**Download GIF** saves the graph viewport as it appeared while this Dashboard page
|
|
194
|
+
was open and visible, including labels, folding, camera changes, and elapsed time
|
|
195
|
+
(sampled at up to 10 frames per second). It excludes the inspector and logs. A
|
|
196
|
+
reopened finished run has no recorded screen history and exports a still image.
|
|
197
|
+
Keep the viewport size fixed for a consistent frame; resizing adds padding rather
|
|
198
|
+
than rescaling older frames. Recording stops with an explicit message if the page
|
|
199
|
+
is hidden during a live run, rendering is paused, or the 64 MB recording limit is
|
|
200
|
+
reached; it never substitutes an animation reconstructed from the final graph.
|
|
201
|
+
|
|
191
202
|
You can tune large-run rendering with:
|
|
192
203
|
|
|
193
204
|
```text
|
|
@@ -133,6 +133,15 @@ The dashboard is designed to keep large, multi-agent runs inspectable without ch
|
|
|
133
133
|
- **Large-run folding:** high-cardinality node types can collapse older members while keeping them inspectable.
|
|
134
134
|
- **Selection-focused layout:** selecting an agent or runtime object de-emphasizes unrelated graph traffic.
|
|
135
135
|
|
|
136
|
+
**Download GIF** saves the graph viewport as it appeared while this Dashboard page
|
|
137
|
+
was open and visible, including labels, folding, camera changes, and elapsed time
|
|
138
|
+
(sampled at up to 10 frames per second). It excludes the inspector and logs. A
|
|
139
|
+
reopened finished run has no recorded screen history and exports a still image.
|
|
140
|
+
Keep the viewport size fixed for a consistent frame; resizing adds padding rather
|
|
141
|
+
than rescaling older frames. Recording stops with an explicit message if the page
|
|
142
|
+
is hidden during a live run, rendering is paused, or the 64 MB recording limit is
|
|
143
|
+
reached; it never substitutes an animation reconstructed from the final graph.
|
|
144
|
+
|
|
136
145
|
You can tune large-run rendering with:
|
|
137
146
|
|
|
138
147
|
```text
|
|
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "execweave"
|
|
7
|
-
# ExecWeave v0.8.
|
|
8
|
-
version = "0.8.
|
|
7
|
+
# ExecWeave v0.8.16 release metadata
|
|
8
|
+
version = "0.8.16"
|
|
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"
|
|
@@ -44,6 +44,7 @@ dependencies = [
|
|
|
44
44
|
[project.optional-dependencies]
|
|
45
45
|
dev = [
|
|
46
46
|
"pytest>=8.0",
|
|
47
|
+
"pillow>=10.0",
|
|
47
48
|
"ruff>=0.16,<0.17",
|
|
48
49
|
"pywinpty>=3.0.5,<4; platform_system == 'Windows'",
|
|
49
50
|
]
|
|
@@ -55,6 +56,7 @@ release = [
|
|
|
55
56
|
# development install stays small; CI installs it and requires the checks to run.
|
|
56
57
|
e2e = [
|
|
57
58
|
"playwright>=1.44",
|
|
59
|
+
"pillow>=10.0",
|
|
58
60
|
"pywinpty>=3.0.5,<4; platform_system == 'Windows'",
|
|
59
61
|
]
|
|
60
62
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import ctypes
|
|
3
4
|
import os
|
|
4
5
|
import subprocess
|
|
6
|
+
import sys
|
|
5
7
|
import time
|
|
6
8
|
from dataclasses import dataclass
|
|
7
9
|
from pathlib import Path
|
|
@@ -22,6 +24,10 @@ from .schema import Entity, RuntimeEvent
|
|
|
22
24
|
from .sink import JsonlSink
|
|
23
25
|
|
|
24
26
|
|
|
27
|
+
_PR_SET_CHILD_SUBREAPER = 36
|
|
28
|
+
_PR_GET_CHILD_SUBREAPER = 37
|
|
29
|
+
|
|
30
|
+
|
|
25
31
|
@dataclass(frozen=True)
|
|
26
32
|
class ProcessSnapshot:
|
|
27
33
|
pid: int
|
|
@@ -129,6 +135,7 @@ class RuntimeCollector:
|
|
|
129
135
|
self._network_sample_successes = 0
|
|
130
136
|
self._network_sample_errors = 0
|
|
131
137
|
self._network_access_denied = 0
|
|
138
|
+
self._collector_children_baseline: dict[int, float] | None = None
|
|
132
139
|
|
|
133
140
|
def _filesystem_excluded_roots(self) -> list[Path]:
|
|
134
141
|
"""Return ExecWeave-owned paths that must never become workload evidence.
|
|
@@ -201,6 +208,7 @@ class RuntimeCollector:
|
|
|
201
208
|
interrupted = False
|
|
202
209
|
collector_error_type: str | None = None
|
|
203
210
|
workload_terminated_due_to_collector_error = False
|
|
211
|
+
subreaper_previous: bool | None = None
|
|
204
212
|
post_command_probe = prepare_post_command_specialized_probe(command)
|
|
205
213
|
try:
|
|
206
214
|
if watcher is not None:
|
|
@@ -211,6 +219,12 @@ class RuntimeCollector:
|
|
|
211
219
|
command,
|
|
212
220
|
server_relay=True,
|
|
213
221
|
) as launch_environment:
|
|
222
|
+
subreaper_previous = self._enable_linux_child_subreaper()
|
|
223
|
+
self._collector_children_baseline = (
|
|
224
|
+
self._direct_child_lifetimes()
|
|
225
|
+
if subreaper_previous is not None
|
|
226
|
+
else None
|
|
227
|
+
)
|
|
214
228
|
process = subprocess.Popen(
|
|
215
229
|
launch_command,
|
|
216
230
|
cwd=str(self.watch_root),
|
|
@@ -252,6 +266,7 @@ class RuntimeCollector:
|
|
|
252
266
|
collector_error_type is not None and bool(owned)
|
|
253
267
|
)
|
|
254
268
|
self._terminate_process_tree(process, owned=owned)
|
|
269
|
+
self._restore_linux_child_subreaper(subreaper_previous)
|
|
255
270
|
if watcher is not None:
|
|
256
271
|
watcher.stop()
|
|
257
272
|
# A failed termination must not become a false clean result merely
|
|
@@ -259,6 +274,7 @@ class RuntimeCollector:
|
|
|
259
274
|
workload_alive_after_cleanup = any(
|
|
260
275
|
self._process_is_live(candidate) for candidate in owned
|
|
261
276
|
) or bool(process is not None and self._owned_live_processes(process))
|
|
277
|
+
self._collector_children_baseline = None
|
|
262
278
|
self.sink.emit(
|
|
263
279
|
RuntimeEvent.create(
|
|
264
280
|
session_id=self.session_id,
|
|
@@ -286,6 +302,57 @@ class RuntimeCollector:
|
|
|
286
302
|
)
|
|
287
303
|
)
|
|
288
304
|
|
|
305
|
+
@staticmethod
|
|
306
|
+
def _linux_child_subreaper_state() -> bool | None:
|
|
307
|
+
if not sys.platform.startswith("linux"):
|
|
308
|
+
return None
|
|
309
|
+
try:
|
|
310
|
+
libc = ctypes.CDLL(None, use_errno=True)
|
|
311
|
+
state = ctypes.c_int()
|
|
312
|
+
if libc.prctl(_PR_GET_CHILD_SUBREAPER, ctypes.byref(state), 0, 0, 0) != 0:
|
|
313
|
+
return None
|
|
314
|
+
return bool(state.value)
|
|
315
|
+
except (AttributeError, OSError):
|
|
316
|
+
return None
|
|
317
|
+
|
|
318
|
+
@staticmethod
|
|
319
|
+
def _set_linux_child_subreaper(enabled: bool) -> bool:
|
|
320
|
+
if not sys.platform.startswith("linux"):
|
|
321
|
+
return False
|
|
322
|
+
try:
|
|
323
|
+
libc = ctypes.CDLL(None, use_errno=True)
|
|
324
|
+
return libc.prctl(_PR_SET_CHILD_SUBREAPER, int(enabled), 0, 0, 0) == 0
|
|
325
|
+
except (AttributeError, OSError):
|
|
326
|
+
return False
|
|
327
|
+
|
|
328
|
+
@classmethod
|
|
329
|
+
def _enable_linux_child_subreaper(cls) -> bool | None:
|
|
330
|
+
previous = cls._linux_child_subreaper_state()
|
|
331
|
+
if previous is None:
|
|
332
|
+
return None
|
|
333
|
+
if not previous and not cls._set_linux_child_subreaper(True):
|
|
334
|
+
return None
|
|
335
|
+
return previous
|
|
336
|
+
|
|
337
|
+
@classmethod
|
|
338
|
+
def _restore_linux_child_subreaper(cls, previous: bool | None) -> None:
|
|
339
|
+
if previous is False:
|
|
340
|
+
cls._set_linux_child_subreaper(False)
|
|
341
|
+
|
|
342
|
+
@staticmethod
|
|
343
|
+
def _direct_child_lifetimes() -> dict[int, float]:
|
|
344
|
+
try:
|
|
345
|
+
children = psutil.Process(os.getpid()).children(recursive=False)
|
|
346
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
347
|
+
return {}
|
|
348
|
+
lifetimes: dict[int, float] = {}
|
|
349
|
+
for child in children:
|
|
350
|
+
try:
|
|
351
|
+
lifetimes[child.pid] = child.create_time()
|
|
352
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
353
|
+
continue
|
|
354
|
+
return lifetimes
|
|
355
|
+
|
|
289
356
|
@staticmethod
|
|
290
357
|
def _process_is_live(proc: psutil.Process) -> bool:
|
|
291
358
|
try:
|
|
@@ -340,6 +407,21 @@ class RuntimeCollector:
|
|
|
340
407
|
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
341
408
|
pass
|
|
342
409
|
|
|
410
|
+
baseline = self._collector_children_baseline
|
|
411
|
+
if baseline is not None:
|
|
412
|
+
try:
|
|
413
|
+
collector_children = psutil.Process(os.getpid()).children(recursive=False)
|
|
414
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
415
|
+
collector_children = []
|
|
416
|
+
for candidate in collector_children:
|
|
417
|
+
try:
|
|
418
|
+
create_time = candidate.create_time()
|
|
419
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
420
|
+
continue
|
|
421
|
+
if baseline.get(candidate.pid) == create_time:
|
|
422
|
+
continue
|
|
423
|
+
add_with_descendants(candidate)
|
|
424
|
+
|
|
343
425
|
snapshots = {**self._seen_processes, **self._discovered_processes}
|
|
344
426
|
for snapshot in snapshots.values():
|
|
345
427
|
tracked = self._process_for_snapshot(snapshot)
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import re
|
|
4
|
-
|
|
5
3
|
from .live_view_extra_style import LIVE_EXTRA_STYLE
|
|
6
4
|
from .live_view_markup import LIVE_MARKUP
|
|
7
5
|
from .live_view_process_layout import LIVE_PROCESS_LAYOUT_SCRIPT
|
|
@@ -15,21 +13,6 @@ from .viewer_agent_panel import inject_agent_panel
|
|
|
15
13
|
from .viewer_dashboard_hardening_v2 import harden_dashboard_html
|
|
16
14
|
|
|
17
15
|
|
|
18
|
-
_SAFE_GIF_LZW = (
|
|
19
|
-
"function lzw(indices,minCodeSize=8){"
|
|
20
|
-
"const clear=1<<minCodeSize,end=clear+1,out=[];"
|
|
21
|
-
"let buffer=0,bits=0;const codeSize=minCodeSize+1;"
|
|
22
|
-
"const chunk=Math.max(1,(1<<codeSize)-clear-8);"
|
|
23
|
-
"const emit=code=>{buffer|=code<<bits;bits+=codeSize;"
|
|
24
|
-
"while(bits>=8){out.push(buffer&255);buffer>>>=8;bits-=8}};"
|
|
25
|
-
"if(!indices.length)emit(clear);"
|
|
26
|
-
"for(let start=0;start<indices.length;start+=chunk){"
|
|
27
|
-
"emit(clear);const stop=Math.min(indices.length,start+chunk);"
|
|
28
|
-
"for(let i=start;i<stop;i++)emit(indices[i])}"
|
|
29
|
-
"emit(end);if(bits>0)out.push(buffer&255);return out}"
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
|
|
33
16
|
def _restore_live_safety_contracts(html: str) -> str:
|
|
34
17
|
"""Preserve live-view safety contracts while retiring legacy final-page swapping."""
|
|
35
18
|
html = html.replace(
|
|
@@ -62,16 +45,6 @@ def _restore_live_safety_contracts(html: str) -> str:
|
|
|
62
45
|
1,
|
|
63
46
|
)
|
|
64
47
|
|
|
65
|
-
html, lzw_count = re.subn(
|
|
66
|
-
r"function lzw\(indices,minCodeSize=8\)\{.*?\}\nfunction gifBlocks",
|
|
67
|
-
_SAFE_GIF_LZW + "\nfunction gifBlocks",
|
|
68
|
-
html,
|
|
69
|
-
count=1,
|
|
70
|
-
flags=re.DOTALL,
|
|
71
|
-
)
|
|
72
|
-
if lzw_count != 1:
|
|
73
|
-
raise RuntimeError("live GIF encoder patch target not found")
|
|
74
|
-
|
|
75
48
|
open_final_button = '<button id="open-final" type="button">Open final graph</button>'
|
|
76
49
|
if open_final_button not in html:
|
|
77
50
|
raise RuntimeError("legacy final action patch target not found")
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from .viewer_gif import GIF_SCRIPT
|
|
4
|
+
|
|
5
|
+
LIVE_SCRIPT_D = r"""
|
|
6
|
+
(()=>{
|
|
7
|
+
const core=window.__execweaveCore;
|
|
8
|
+
if(!core)return;
|
|
9
|
+
const structuredList=document.getElementById('activity-list'),rawLog=document.getElementById('raw-log'),rawRows=document.getElementById('raw-rows'),activityCount=document.getElementById('activity-count'),filterGroup=document.querySelector('.filter-group'),finishedActions=document.getElementById('finished-actions'),replayButton=document.getElementById('replay-run'),gifButton=document.getElementById('download-gif'),openFinalButton=document.getElementById('open-final'),details=document.getElementById('details'),detailsEmpty=document.getElementById('details-empty');
|
|
10
|
+
const MAX_RAW=640;
|
|
11
|
+
let rawEntries=[],logMode='structured',finishedShown=false,finalHtmlCache=null,replaying=false;
|
|
12
|
+
function rawId(entry){return`raw-${entry.stream||'events'}-${entry.line??'x'}-${entry.event?.event_id||entry.event?.sequence||''}`}
|
|
13
|
+
function rawTime(event){const value=event?.timestamp;if(!value)return'—';const d=new Date(value);if(Number.isNaN(d.getTime()))return String(value);return d.toLocaleTimeString([],{hour:'2-digit',minute:'2-digit',second:'2-digit',fractionalSecondDigits:3})}
|
|
14
|
+
function rawEventType(event){return String(event?.event_type||event?.type||'event')}
|
|
15
|
+
function rawRelation(event){return String(event?.relation||'—')}
|
|
16
|
+
function rawSummary(event){try{return JSON.stringify(event)}catch(_){return String(event)}}
|
|
17
|
+
function setRawEntries(items){rawEntries=(items||[]).slice(-MAX_RAW);renderRaw(false)}
|
|
18
|
+
function addRawEntries(items){if(!items?.length)return;rawEntries.push(...items);if(rawEntries.length>MAX_RAW)rawEntries=rawEntries.slice(-MAX_RAW);renderRaw(logMode==='raw')}
|
|
19
|
+
function findGraphEdge(event){const source=event?.source?.id,target=event?.target?.id,relation=event?.relation;if(!source||!target||!relation)return null;const visible=[...document.querySelectorAll('.edge')].find(el=>el.dataset.source===source&&el.dataset.target===target&&el.dataset.relation===String(relation).toLowerCase());return visible?.dataset.edgeId||null}
|
|
20
|
+
function showRaw(entry){const event=entry.event||{};detailsEmpty.hidden=true;details.innerHTML='';const title=document.createElement('div');title.className='current-title';title.textContent=rawEventType(event);const sub=document.createElement('div');sub.className='current-sub';sub.textContent=`${entry.stream||'events.jsonl'} line ${entry.line??'—'} · ${rawRelation(event)}`;const pre=document.createElement('pre');pre.textContent=JSON.stringify(event,null,2);const raw=document.createElement('details');raw.className='raw-toggle';raw.open=true;const summary=document.createElement('summary');summary.textContent='Raw event JSON';raw.append(summary,pre);details.append(title,sub,raw);const nodeMap=new Map();for(const node of(core.getGraph()?.nodes||[])){if(node?.id)nodeMap.set(node.id,node);for(const key of['viewer_member_ids','viewer_agent_member_ids'])for(const member of(node?.attributes?.[key]||[]))nodeMap.set(String(member),node)}const targets=document.createElement('div');targets.className='raw-target-actions';for(const entity of [event.source,event.target]){if(!entity?.id||!nodeMap.has(entity.id))continue;const node=nodeMap.get(entity.id);const button=document.createElement('button');button.type='button';button.textContent=`Inspect ${node.type||'node'}${node.name?` · ${node.name}`:''}`;button.addEventListener('click',()=>core.selectNode(node.id,{syncLog:false}));targets.appendChild(button)}if(targets.childElementCount)details.appendChild(targets)}
|
|
21
|
+
function selectRaw(entry,row){document.querySelectorAll('.raw-row.selected').forEach(el=>el.classList.remove('selected'));row.classList.add('selected');const edge=findGraphEdge(entry.event);if(edge)core.selectEdge(edge,{syncLog:false});showRaw(entry)}
|
|
22
|
+
function renderRaw(scrollLatest=false){rawRows.replaceChildren();activityCount.textContent=logMode==='raw'?`${rawEntries.length} raw event${rawEntries.length===1?'':'s'}`:`${core.getActivities().length} transition${core.getActivities().length===1?'':'s'}`;if(!rawEntries.length){const empty=document.createElement('div');empty.className='empty-activity';empty.textContent='Waiting for runtime or semantic activity…';rawRows.appendChild(empty);return}for(const entry of rawEntries){const row=document.createElement('div');row.className='raw-row';row.dataset.rawId=rawId(entry);const line=document.createElement('span');line.className='raw-line';line.textContent=String(entry.line??'—');const time=document.createElement('span');time.className='raw-time';time.textContent=rawTime(entry.event);const event=document.createElement('span');event.className='raw-event';event.textContent=rawEventType(entry.event);const relation=document.createElement('span');relation.className='raw-relation';relation.textContent=rawRelation(entry.event);const json=document.createElement('span');json.className='raw-json';json.textContent=rawSummary(entry.event);json.title=json.textContent;row.append(line,time,event,relation,json);row.onclick=()=>selectRaw(entry,row);rawRows.appendChild(row)}if(scrollLatest)rawRows.lastElementChild?.scrollIntoView({block:'nearest'})}
|
|
23
|
+
function setLogMode(mode){logMode=mode==='raw'?'raw':'structured';document.querySelectorAll('[data-log-mode]').forEach(button=>button.classList.toggle('active',button.dataset.logMode===logMode));structuredList.hidden=logMode==='raw';rawLog.hidden=logMode!=='raw';filterGroup.hidden=logMode==='raw';if(logMode==='raw')renderRaw(false);else activityCount.textContent=`${core.getActivities().length} transition${core.getActivities().length===1?'':'s'}`}
|
|
24
|
+
document.querySelectorAll('[data-log-mode]').forEach(button=>button.onclick=()=>setLogMode(button.dataset.logMode));
|
|
25
|
+
function onPayload(data){observeGifPayload(data);if(data.kind==='snapshot')setRawEntries(data.raw_events||[]);else if(data.kind==='delta'){const added=[];for(const update of data.updates||[])added.push(...(update.raw_events_added||[]));addRawEntries(added)}}
|
|
26
|
+
function timelineItems(){const activities=core.getActivities().filter(item=>item.edgeId||item.nodeId);return activities.length?activities:[]}
|
|
27
|
+
function revealNode(id){if(!id)return;document.querySelector(`.node[data-id="${CSS.escape(id)}"]`)?.classList.remove('replay-hidden')}
|
|
28
|
+
function revealEdge(id){if(!id)return;const edge=document.querySelector(`.edge[data-edge-id="${CSS.escape(id)}"]`);edge?.classList.remove('replay-hidden');document.querySelector(`.label[data-edge-id="${CSS.escape(id)}"]`)?.classList.remove('replay-hidden');if(edge){revealNode(edge.dataset.source);revealNode(edge.dataset.target)}}
|
|
29
|
+
function restoreReplayDom(){document.querySelectorAll('.replay-hidden,.replay-active').forEach(el=>el.classList.remove('replay-hidden','replay-active'))}
|
|
30
|
+
const sleep=ms=>new Promise(resolve=>setTimeout(resolve,ms));
|
|
31
|
+
async function replayRun(){if(replaying)return;const timeline=timelineItems();if(!timeline.length)return;replaying=true;replayButton.disabled=true;restoreReplayDom();document.querySelectorAll('.node,.edge,.label').forEach(el=>el.classList.add('replay-hidden'));core.setCameraMode('fit');const delay=Math.max(55,Math.min(180,7000/Math.max(1,timeline.length)));for(const item of timeline){document.querySelectorAll('.replay-active').forEach(el=>el.classList.remove('replay-active'));if(item.edgeId){revealEdge(item.edgeId);document.querySelector(`.edge[data-edge-id="${CSS.escape(item.edgeId)}"]`)?.classList.add('replay-active')}if(item.nodeId){revealNode(item.nodeId);document.querySelector(`.node[data-id="${CSS.escape(item.nodeId)}"]`)?.classList.add('replay-active')}core.markLatest(item.nodeId||null,item.edgeId||null);await sleep(delay)}await sleep(380);restoreReplayDom();const last=timeline[timeline.length-1];core.markLatest(last.nodeId||null,last.edgeId||null);replaying=false;replayButton.disabled=false}
|
|
32
|
+
""" + GIF_SCRIPT + r"""
|
|
33
|
+
async function prepareFinalView(){try{const response=await fetch('/final',{cache:'no-store'});if(!response.ok)throw new Error(String(response.status));finalHtmlCache=await response.text()}catch(_){finalHtmlCache=null}}
|
|
34
|
+
function openFinal(){if(!finalHtmlCache)return;document.open();document.write(finalHtmlCache);document.close()}
|
|
35
|
+
function onFinished(){if(finishedShown)return;finishedShown=true;finishedActions.hidden=false;prepareFinalView()}
|
|
36
|
+
replayButton.onclick=replayRun;gifButton.onclick=downloadGif;openFinalButton.onclick=openFinal;
|
|
37
|
+
window.__execweaveDashboard={onPayload,onFinished};
|
|
38
|
+
if(window.__execweaveStaticMode)onFinished();
|
|
39
|
+
})();
|
|
40
|
+
"""
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
LIVE_STYLE = r""":root{color-scheme:dark;--bg:#0a0f16;--panel:#101722;--panel2:#151f2c;--panel3:#0d141e;--text:#edf2f7;--muted:#8fa0b5;--border:#263446;--border-strong:#34485e;--edge:#6f8298;--causal:#65c79b;--noncausal:#e5aa61;--inferred:#b18cff;--selected:#75b8ff;--latest:#77d7ff;--danger:#ff7b86;--node-agent:#1e4b7a;--node-process:#1d4e5f;--node-file:#1f5438;--node-network:#643d1f;--node-tool:#4f2f75;--node-model:#662952;--node-other:#334255;--shadow:0 14px 40px rgba(0,0,0,.18)}
|
|
4
4
|
:root[data-theme="light"]{color-scheme:light;--bg:#eef3f8;--panel:#ffffff;--panel2:#f6f9fc;--panel3:#f9fbfd;--text:#172033;--muted:#66758a;--border:#d5dee8;--border-strong:#b9c7d7;--edge:#738195;--causal:#16855a;--noncausal:#b56a16;--inferred:#7b4dd8;--selected:#2563eb;--latest:#0f8fc5;--danger:#c2414f;--node-agent:#2d6391;--node-process:#2b697b;--node-file:#2c6e49;--node-network:#865328;--node-tool:#673d8e;--node-model:#7f3465;--node-other:#495c72;--shadow:0 14px 35px rgba(30,41,59,.08)}
|
|
5
5
|
*{box-sizing:border-box}html,body{margin:0;width:100%;height:100%;overflow:hidden;background:var(--bg);color:var(--text);font:14px/1.45 Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}
|
|
6
|
-
button,input{font:inherit}button{color:inherit}button:focus-visible,input:focus-visible{outline:2px solid var(--selected);outline-offset:2px}
|
|
6
|
+
button,input,select{font:inherit}button{color:inherit}button:focus-visible,input:focus-visible,select:focus-visible{outline:2px solid var(--selected);outline-offset:2px}
|
|
7
7
|
#app{display:grid;grid-template-columns:minmax(0,1fr) 340px;grid-template-rows:64px minmax(0,1fr) 230px;width:100%;height:100%;gap:0}
|
|
8
8
|
header{grid-column:1/3;display:flex;align-items:center;gap:12px;padding:0 16px;background:color-mix(in srgb,var(--panel) 95%,transparent);border-bottom:1px solid var(--border);box-shadow:0 1px 0 rgba(255,255,255,.02);z-index:10;min-width:0}
|
|
9
9
|
.brand{display:flex;align-items:center;gap:10px;min-width:max-content}.brand-mark{width:28px;height:28px;border-radius:8px;display:grid;place-items:center;background:linear-gradient(145deg,var(--panel2),var(--panel));border:1px solid var(--border-strong);font-weight:800;letter-spacing:-.06em}.brand-copy{display:flex;flex-direction:column;line-height:1.1}.brand-copy strong{font-size:14px}.brand-copy span{font-size:10px;color:var(--muted);letter-spacing:.08em;text-transform:uppercase;margin-top:3px}
|
|
@@ -14,6 +14,7 @@ header{grid-column:1/3;display:flex;align-items:center;gap:12px;padding:0 16px;b
|
|
|
14
14
|
.icon-btn{height:34px;min-width:34px;padding:0 10px;border:1px solid var(--border);border-radius:8px;background:var(--panel2);cursor:pointer;transition:border-color .15s ease,background .15s ease}.icon-btn:hover{border-color:var(--border-strong);background:color-mix(in srgb,var(--panel2) 76%,var(--selected) 8%)}
|
|
15
15
|
#graph-panel{grid-column:1;grid-row:2;min-width:0;min-height:0;display:grid;grid-template-rows:46px minmax(0,1fr);border-right:1px solid var(--border);background:var(--panel3)}
|
|
16
16
|
.panel-bar{display:flex;align-items:center;gap:10px;padding:0 12px;border-bottom:1px solid var(--border);background:var(--panel);min-width:0}.panel-title{font-size:12px;font-weight:750;text-transform:uppercase;letter-spacing:.08em}.panel-subtitle{color:var(--muted);font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.panel-spacer{flex:1}
|
|
17
|
+
.graph-file-filter{display:flex;align-items:center;gap:6px;color:var(--muted);font-size:11px;white-space:nowrap}.graph-file-filter select{height:30px;padding:0 8px;border:1px solid var(--border);border-radius:8px;background:var(--panel2);color:var(--text);cursor:pointer}.graph-file-filter select:hover{border-color:var(--border-strong)}
|
|
17
18
|
.segmented{display:flex;align-items:center;padding:2px;border:1px solid var(--border);border-radius:9px;background:var(--panel2);gap:2px}.segmented button{height:28px;padding:0 10px;border:0;border-radius:7px;background:transparent;color:var(--muted);cursor:pointer;font-size:12px}.segmented button:hover{color:var(--text)}.segmented button.active{background:var(--panel);color:var(--text);box-shadow:inset 0 0 0 1px var(--border-strong)}
|
|
18
19
|
.graph-actions{display:flex;align-items:center;gap:6px}.graph-actions button{height:30px;min-width:30px;padding:0 9px;border:1px solid var(--border);border-radius:8px;background:var(--panel2);cursor:pointer;color:var(--muted)}.graph-actions button:hover{color:var(--text);border-color:var(--border-strong)}
|
|
19
20
|
#wrap{position:relative;overflow:hidden;min-width:0;min-height:0;background-image:radial-gradient(circle at 1px 1px,color-mix(in srgb,var(--border) 52%,transparent) 1px,transparent 0);background-size:22px 22px}svg{width:100%;height:100%;display:block;cursor:grab;user-select:none;touch-action:none}svg.panning{cursor:grabbing}
|
|
@@ -99,6 +99,24 @@ function execweaveDashboardGraph(data){
|
|
|
99
99
|
if(!outgoing.has(edge.source))outgoing.set(edge.source,[]);
|
|
100
100
|
incoming.get(edge.target).push(edge);outgoing.get(edge.source).push(edge);
|
|
101
101
|
}
|
|
102
|
+
const fileDisplayMode=String(globalThis.__execweaveFileDisplayMode||'changed');
|
|
103
|
+
const fileTypes=new Set(['file','directory']);
|
|
104
|
+
const fileMutationEvents=new Set(['filesystem.created','filesystem.modified','filesystem.moved','filesystem.deleted']);
|
|
105
|
+
const fileMutationRelation=relation=>/(^|_)(WROTE|WRITE|WRITES|CREATE|CREATED|UPDATE|UPDATED|EDIT|EDITED|DELETE|DELETED|MOVE|MOVED|RENAME|RENAMED|PATCH|REPLACE|REPLACED|SAVE|SAVED|MODIFY|MODIFIED)($|_)/.test(String(relation||'').toUpperCase());
|
|
106
|
+
const fileReadRelation=relation=>/(^|_)(READ|OPEN|SCAN|LIST|STAT|INSPECT|OBSERVE|OBSERVED)($|_)/.test(String(relation||'').toUpperCase());
|
|
107
|
+
const fileActivity=node=>{
|
|
108
|
+
if(!fileTypes.has(String(node?.type||'')))return'other';
|
|
109
|
+
const eventTypes=Array.isArray(node?.event_types)?node.event_types:[];
|
|
110
|
+
const related=[...(incoming.get(node.id)||[]),...(outgoing.get(node.id)||[])];
|
|
111
|
+
const relatedEventTypes=related.flatMap(edge=>Array.isArray(edge?.event_types)?edge.event_types:[]);
|
|
112
|
+
const allEventTypes=[...eventTypes,...relatedEventTypes].map(String);
|
|
113
|
+
if(allEventTypes.some(value=>fileMutationEvents.has(value)))return'changed';
|
|
114
|
+
if(related.some(edge=>fileMutationRelation(edge?.relation)))return'changed';
|
|
115
|
+
const observedEvents=allEventTypes.some(value=>value.startsWith('filesystem.'));
|
|
116
|
+
if(observedEvents||related.some(edge=>fileReadRelation(edge?.relation)))return'observed';
|
|
117
|
+
return'unknown';
|
|
118
|
+
};
|
|
119
|
+
const fileVisible=node=>{const activity=fileActivity(node);if(activity==='other')return true;if(fileDisplayMode==='hide')return false;if(fileDisplayMode==='all')return true;return activity!=='observed'};
|
|
102
120
|
const provider=node=>String(node?.attributes?.provider||'unknown').toLowerCase();
|
|
103
121
|
const toolName=node=>String(node?.attributes?.tool_name||node?.attributes?.native_name||node?.name||'tool');
|
|
104
122
|
const toolKey=node=>`${provider(node)}\u0000${toolName(node).trim().toLowerCase()}`;
|
|
@@ -205,7 +223,10 @@ function execweaveDashboardGraph(data){
|
|
|
205
223
|
};
|
|
206
224
|
for(const group of groups.values())group.occurrences.sort(occurrenceOrder);
|
|
207
225
|
for(const list of toolOccurrences.values())list.sort(occurrenceOrder);
|
|
208
|
-
|
|
226
|
+
const candidateNodes=allNodes.filter(node=>node&&node.id&&!hiddenIds.has(node.id)).filter(node=>node.type!=='tool'||toolCanonicalId.get(node.id)===node.id);
|
|
227
|
+
const hiddenFileObservationCount=candidateNodes.filter(node=>fileTypes.has(String(node?.type||''))&&!fileVisible(node)).length;
|
|
228
|
+
let visibleNodes=candidateNodes.filter(node=>fileVisible(node)).map(node=>{
|
|
229
|
+
if(fileTypes.has(String(node?.type||'')))return{...node,attributes:{...attrsOf(node),viewer_file_activity:fileActivity(node)}};
|
|
209
230
|
if(node.type!=='tool')return node;
|
|
210
231
|
const occurrences=toolOccurrences.get(node.id)||[],members=toolMembersByRepresentative.get(node.id)||[node];
|
|
211
232
|
if(!occurrences.length&&members.length===1)return node;
|
|
@@ -214,7 +235,8 @@ function execweaveDashboardGraph(data){
|
|
|
214
235
|
});
|
|
215
236
|
|
|
216
237
|
const canonicalTypes=new Set(['process','file']);
|
|
217
|
-
const foldableTypes=new Set(['process','file','network_endpoint']);
|
|
238
|
+
const foldableTypes=new Set(['process','file','directory','network_endpoint']);
|
|
239
|
+
const foldType=node=>{const type=String(node?.type||'');return type==='file'||type==='directory'?'filesystem':type};
|
|
218
240
|
const declaredBudget=Number(globalThis.__execweaveFoldBudget);
|
|
219
241
|
const FOLD_BUDGET=Number.isFinite(declaredBudget)&&declaredBudget>=1?Math.floor(declaredBudget):12;
|
|
220
242
|
const canonicalGroups=new Map();
|
|
@@ -246,19 +268,21 @@ function execweaveDashboardGraph(data){
|
|
|
246
268
|
|
|
247
269
|
let foldedNodeCount=0;
|
|
248
270
|
const byType=new Map();
|
|
249
|
-
for(const node of nodes){const
|
|
271
|
+
for(const node of nodes){const rawType=String(node?.type||'');if(!foldableTypes.has(rawType))continue;const type=foldType(node);if(!byType.has(type))byType.set(type,[]);byType.get(type).push(node)}
|
|
250
272
|
const folds=[];
|
|
251
273
|
for(const[type,members]of byType){
|
|
252
274
|
if(members.length<=FOLD_BUDGET)continue;
|
|
253
275
|
const recency=node=>String(node?.last_seen||node?.first_seen||'');
|
|
254
276
|
const ordered=[...members].sort((a,b)=>recency(b).localeCompare(recency(a)));
|
|
255
277
|
const older=ordered.slice(FOLD_BUDGET);if(!older.length)continue;
|
|
256
|
-
const
|
|
278
|
+
const removeIds=new Set(older.map(node=>node.id));
|
|
257
279
|
const foldId=`viewer:folded:${type}`;
|
|
258
280
|
for(const node of older)canonicalId.set(node.id,foldId);
|
|
259
281
|
foldedNodeCount+=older.length;
|
|
260
|
-
|
|
261
|
-
|
|
282
|
+
const foldedType=type==='filesystem'?'file_cluster':type,foldedName=type==='filesystem'?`${older.length} earlier files / directories`:`${older.length} earlier ${type.replace(/_/g,' ')}${older.length===1?'':'s'}`;
|
|
283
|
+
const activities=[...new Set(older.map(node=>node?.attributes?.viewer_file_activity).filter(Boolean))];
|
|
284
|
+
folds.push({id:foldId,type:foldedType,name:foldedName,first_seen:older.reduce((value,node)=>earlier(value,node.first_seen),null),last_seen:older.reduce((value,node)=>later(value,node.last_seen),null),attributes:{viewer_folded:true,viewer_folded_type:type,viewer_folded_count:older.length,viewer_file_activity:type==='filesystem'?(activities.length===1?activities[0]:'mixed'):undefined,viewer_folded_members:older.map(node=>({id:node.id,type:node.type,name:node.name||node.id,activity:node?.attributes?.viewer_file_activity||null,first_seen:node.first_seen||null,last_seen:node.last_seen||null}))}});
|
|
285
|
+
for(let index=nodes.length-1;index>=0;index--)if(removeIds.has(nodes[index].id))nodes.splice(index,1);
|
|
262
286
|
}
|
|
263
287
|
nodes.push(...folds);
|
|
264
288
|
|
|
@@ -280,7 +304,7 @@ function execweaveDashboardGraph(data){
|
|
|
280
304
|
const incident=new Set();for(const edge of edges){incident.add(edge.source);incident.add(edge.target)}
|
|
281
305
|
visibleNodes=nodes.filter(node=>node.type!=='tool'||incident.has(node.id));
|
|
282
306
|
nodeIds=new Set(visibleNodes.map(node=>node.id));edges=edges.filter(edge=>nodeIds.has(edge.source)&&nodeIds.has(edge.target));
|
|
283
|
-
return{...data,nodes:visibleNodes,edges,node_count:visibleNodes.length,edge_count:edges.length,dashboard_projection:{hidden_detail_node_count:hiddenDetailIds.size,hidden_internal_staging_node_count:internalStagingIds.size,canonicalized_process_occurrence_count:canonicalizedProcessOccurrenceCount,canonicalized_tool_entity_count:[...toolMembersByRepresentative.values()].reduce((sum,members)=>sum+Math.max(0,members.length-1),0),folded_node_count:foldedNodeCount,collapsed_tool_call_count:invocationMap.size,raw_tool_call_detail_count:allNodes.filter(node=>['tool_call','tool_call_observation'].includes(String(node?.type||''))).length}};
|
|
307
|
+
return{...data,nodes:visibleNodes,edges,node_count:visibleNodes.length,edge_count:edges.length,dashboard_projection:{hidden_detail_node_count:hiddenDetailIds.size,hidden_internal_staging_node_count:internalStagingIds.size,canonicalized_process_occurrence_count:canonicalizedProcessOccurrenceCount,canonicalized_tool_entity_count:[...toolMembersByRepresentative.values()].reduce((sum,members)=>sum+Math.max(0,members.length-1),0),folded_node_count:foldedNodeCount,collapsed_tool_call_count:invocationMap.size,raw_tool_call_detail_count:allNodes.filter(node=>['tool_call','tool_call_observation'].includes(String(node?.type||''))).length,file_display_mode:fileDisplayMode,hidden_file_observation_node_count:hiddenFileObservationCount}};
|
|
284
308
|
}
|
|
285
309
|
""".strip()
|
|
286
310
|
|
|
@@ -310,7 +334,7 @@ _LIVE_SET_SNAPSHOT_CLEAN = "function setSnapshot(data){const signature=`${data.n
|
|
|
310
334
|
_LIVE_APPLY_DELTA_CLEAN = "function applyDelta(update){if(update.live_payload_compact){updateStats(update);enterProtectiveMode(update);return}const rawNodes=new Map((graph.nodes||[]).map(n=>[n.id,n])),rawEdges=new Map((graph.edges||[]).map(e=>[edgeId(e),e]));for(const node of [...(update.nodes_added||[]),...(update.nodes_updated||[])])if(node?.id)rawNodes.set(node.id,node);for(const edge of [...(update.edges_added||[]),...(update.edges_updated||[])])rawEdges.set(edgeId(edge),edge);graph={...graph,event_count:update.event_count,node_count:update.node_count,edge_count:update.edge_count,nodes:[...rawNodes.values()],edges:[...rawEdges.values()]};const display=execweaveDashboardGraph(graph);updateStats({...update,node_count:display.node_count,edge_count:display.edge_count});if(!withinRenderBudget(display)){enterProtectiveMode(display);return}if(protectedMode)leaveProtectiveMode();nodeById=new Map((display.nodes||[]).map(n=>[n.id,n]));edgeById=new Map((display.edges||[]).map(e=>[edgeId(e),e]));rebuildAdjacency();renderSnapshot();seedActivities();const sortedEdges=[...edgeById.values()].sort((a,b)=>String(a.last_seen||'').localeCompare(String(b.last_seen||''))),sortedNodes=[...nodeById.values()].sort((a,b)=>String(a.last_seen||'').localeCompare(String(b.last_seen||''))),lastEdge=sortedEdges.length?sortedEdges[sortedEdges.length-1]:null,lastNode=sortedNodes.length?sortedNodes[sortedNodes.length-1]:null;markLatest(lastEdge?.target||lastNode?.id||null,lastEdge?edgeId(lastEdge):null);scheduleCamera(false);if(!hasFitted&&positions.size){fit(false);hasFitted=true}}"
|
|
311
335
|
|
|
312
336
|
_LIVE_CORE_EXPORT = "window.__execweaveCore={getActivities:()=>activities.slice(),getGraph:()=>graph,getPositions:()=>new Map(positions),selectEdge,selectNode,focusNode,markLatest,setCameraMode};"
|
|
313
|
-
_LIVE_CORE_EXPORT_CLEAN = "window.__execweaveCore={getActivities:()=>activities.slice(),getGraph:()=>graph,getDisplayGraph:()=>({...graph,nodes:[...nodeById.values()],edges:[...edgeById.values()],node_count:nodeById.size,edge_count:edgeById.size}),getPositions:()=>new Map(positions),selectEdge,selectNode,focusNode,markLatest,setCameraMode};"
|
|
337
|
+
_LIVE_CORE_EXPORT_CLEAN = "const execweaveFileGraphFilter=document.getElementById('file-graph-filter');globalThis.__execweaveFileDisplayMode=execweaveFileGraphFilter?.value||'changed';if(execweaveFileGraphFilter)execweaveFileGraphFilter.addEventListener('change',()=>{globalThis.__execweaveFileDisplayMode=execweaveFileGraphFilter.value||'changed';setSnapshot(graph)});window.__execweaveCore={getActivities:()=>activities.slice(),getGraph:()=>graph,getDisplayGraph:()=>({...graph,nodes:[...nodeById.values()],edges:[...edgeById.values()],node_count:nodeById.size,edge_count:edgeById.size}),getPositions:()=>new Map(positions),selectEdge,selectNode,focusNode,markLatest,setCameraMode};"
|
|
314
338
|
|
|
315
339
|
_LIVE_NOOP_STATS = "else if(data.kind==='noop'){liveSequence=Number(data.sequence)||liveSequence;updateStats(data);}"
|
|
316
340
|
_LIVE_NOOP_STATS_CLEAN = "else if(data.kind==='noop'){liveSequence=Number(data.sequence)||liveSequence;updateStats(protectedMode?data:{...data,node_count:nodeById.size,edge_count:edgeById.size});}"
|
|
@@ -338,6 +362,11 @@ def inject_standalone_dashboard_clean(html: str) -> str:
|
|
|
338
362
|
|
|
339
363
|
def inject_live_dashboard_clean(html: str) -> str:
|
|
340
364
|
"""Simplify only the browser canvas; the live JSON protocol remains unchanged."""
|
|
365
|
+
control_seam = '<div class="panel-spacer"></div>\n <div class="segmented" aria-label="Camera mode">'
|
|
366
|
+
control = '<div class="panel-spacer"></div>\n <label class="graph-file-filter" title="Choose which file and directory nodes appear in the graph"><span>Files</span><select id="file-graph-filter"><option value="changed" selected>Changed only</option><option value="all">All observed</option><option value="hide">Hidden</option></select></label>\n <div class="segmented" aria-label="Camera mode">'
|
|
367
|
+
if html.count(control_seam) != 1:
|
|
368
|
+
raise RuntimeError("file graph filter control seam changed")
|
|
369
|
+
html = html.replace(control_seam, control, 1)
|
|
341
370
|
marker = "function renderSnapshot(){"
|
|
342
371
|
if "function execweaveDashboardGraph(data){" not in html and marker in html:
|
|
343
372
|
html = html.replace(marker, _DASHBOARD_JS + "\n" + marker, 1)
|
|
@@ -368,9 +397,4 @@ def inject_live_dashboard_clean(html: str) -> str:
|
|
|
368
397
|
html = html[:render_index] + html[render_index:].replace(render_marker, render_replacement, 1)
|
|
369
398
|
html = html.replace(_LIVE_CORE_EXPORT, _LIVE_CORE_EXPORT_CLEAN, 1)
|
|
370
399
|
html = html.replace(_LIVE_NOOP_STATS, _LIVE_NOOP_STATS_CLEAN, 1)
|
|
371
|
-
html = html.replace(
|
|
372
|
-
"const graph=core.getGraph(),positions=core.getPositions(),steps=sortedGifSteps(graph);",
|
|
373
|
-
"const graph=core.getDisplayGraph?.()||core.getGraph(),positions=core.getPositions(),steps=sortedGifSteps(graph);",
|
|
374
|
-
1,
|
|
375
|
-
)
|
|
376
400
|
return html
|
|
@@ -58,26 +58,5 @@ def harden_dashboard_html(html: str) -> str:
|
|
|
58
58
|
label="delta geometry rerender",
|
|
59
59
|
)
|
|
60
60
|
|
|
61
|
-
#
|
|
62
|
-
# node rectangle even after the dashboard became adaptive. Export is a projection of
|
|
63
|
-
# the same graph, so its bounds, edge anchors and drawn rectangles must use the same
|
|
64
|
-
# per-node geometry as Live/Finished/viewer rather than silently reverting to v0.8.2.
|
|
65
|
-
html = _replace_once(
|
|
66
|
-
html,
|
|
67
|
-
"minX=Math.min(minX,p.x);maxX=Math.max(maxX,p.x+160);minY=Math.min(minY,p.y);maxY=Math.max(maxY,p.y+50)",
|
|
68
|
-
"minX=Math.min(minX,p.x);maxX=Math.max(maxX,p.x+execweaveCameraWidth(node.id));minY=Math.min(minY,p.y);maxY=Math.max(maxY,p.y+execweaveCameraHeight(node.id))",
|
|
69
|
-
label="gif adaptive bounds",
|
|
70
|
-
)
|
|
71
|
-
html = _replace_once(
|
|
72
|
-
html,
|
|
73
|
-
"const point=(id,right=false)=>{const p=positions.get(id)||{x:0,y:0};return{x:ox+(p.x+(right?160:0))*scale,y:oy+(p.y+25)*scale}};",
|
|
74
|
-
"const point=(id,right=false)=>{const p=positions.get(id)||{x:0,y:0},w=execweaveCameraWidth(id),h=execweaveCameraHeight(id);return{x:ox+(p.x+(right?w:0))*scale,y:oy+(p.y+h/2)*scale}};",
|
|
75
|
-
label="gif adaptive anchors",
|
|
76
|
-
)
|
|
77
|
-
html = _replace_once(
|
|
78
|
-
html,
|
|
79
|
-
"const x=ox+p.x*scale,y=oy+p.y*scale,w=160*scale,h=50*scale;",
|
|
80
|
-
"const x=ox+p.x*scale,y=oy+p.y*scale,w=execweaveCameraWidth(node.id)*scale,h=execweaveCameraHeight(node.id)*scale;",
|
|
81
|
-
label="gif adaptive rectangles",
|
|
82
|
-
)
|
|
61
|
+
# GIF captures measured SVG geometry directly; it has no separate layout.
|
|
83
62
|
return html
|