flowproof 0.23.26__tar.gz → 0.23.28__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 (190) hide show
  1. {flowproof-0.23.26 → flowproof-0.23.28}/Cargo.lock +7 -7
  2. {flowproof-0.23.26 → flowproof-0.23.28}/Cargo.toml +1 -1
  3. {flowproof-0.23.26 → flowproof-0.23.28}/PKG-INFO +1 -1
  4. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/sap_com.rs +82 -2
  5. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/recorder.rs +141 -1
  6. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/src/lib.rs +400 -12
  7. {flowproof-0.23.26 → flowproof-0.23.28}/flowproof/__init__.py +1 -1
  8. {flowproof-0.23.26 → flowproof-0.23.28}/pyproject.toml +1 -1
  9. {flowproof-0.23.26 → flowproof-0.23.28}/README.md +0 -0
  10. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/Cargo.toml +0 -0
  11. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/examples/vision_bench.rs +0 -0
  12. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/examples/vision_do.rs +0 -0
  13. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/agent_proxy.rs +0 -0
  14. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/agent_runner.rs +0 -0
  15. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/egress.rs +0 -0
  16. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/egress_linux.rs +0 -0
  17. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/egress_windows/audit.rs +0 -0
  18. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/egress_windows/capture.rs +0 -0
  19. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/egress_windows/env_block.rs +0 -0
  20. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/egress_windows/filters.rs +0 -0
  21. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/egress_windows/identity.rs +0 -0
  22. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/egress_windows/logon.rs +0 -0
  23. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/egress_windows/netevents.rs +0 -0
  24. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/egress_windows/run.rs +0 -0
  25. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/egress_windows/spawn.rs +0 -0
  26. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/egress_windows/wfp.rs +0 -0
  27. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/egress_windows.rs +0 -0
  28. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/fiori.rs +0 -0
  29. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/fs_observe.rs +0 -0
  30. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/lib.rs +0 -0
  31. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/mcp_core.rs +0 -0
  32. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/mcp_http.rs +0 -0
  33. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/mcp_stdio.rs +0 -0
  34. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/vision/start.rs +0 -0
  35. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/vision.rs +0 -0
  36. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/vision_bench.rs +0 -0
  37. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/vision_elements.rs +0 -0
  38. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/vision_winocr.rs +0 -0
  39. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/src/web.rs +0 -0
  40. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/tests/a11y_capture.rs +0 -0
  41. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/tests/drag_spike.rs +0 -0
  42. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/tests/fingerprint_capture.rs +0 -0
  43. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/tests/fixtures/windows-start.png +0 -0
  44. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/tests/fs_observation_e2e.rs +0 -0
  45. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/tests/grid_scene_e2e.rs +0 -0
  46. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/tests/list_scene_e2e.rs +0 -0
  47. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/tests/network_idle_e2e.rs +0 -0
  48. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/tests/password_recording_e2e.rs +0 -0
  49. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/tests/shared_browser_shutdown_e2e.rs +0 -0
  50. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/tests/side_effect_http_e2e.rs +0 -0
  51. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/tests/static_area_e2e.rs +0 -0
  52. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/tests/visibility_detach_e2e.rs +0 -0
  53. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-adapters/tests/windows_containment_e2e.rs +0 -0
  54. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/Cargo.toml +0 -0
  55. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/agent_steps.rs +0 -0
  56. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/author.rs +0 -0
  57. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/clarify.rs +0 -0
  58. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/code_author.rs +0 -0
  59. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/doc_author.rs +0 -0
  60. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/doc_formats/hp_alm.rs +0 -0
  61. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/doc_formats.rs +0 -0
  62. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/draft_assembly.rs +0 -0
  63. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/heal.rs +0 -0
  64. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/lib.rs +0 -0
  65. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/llm.rs +0 -0
  66. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/repair.rs +0 -0
  67. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/rules.rs +0 -0
  68. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/src/spec.rs +0 -0
  69. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-agent/tests/model_client_http.rs +0 -0
  70. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/Cargo.toml +0 -0
  71. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/skills/flowproof-config/SKILL.md +0 -0
  72. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/src/agent_flow.rs +0 -0
  73. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/src/agent_surface.rs +0 -0
  74. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/src/capture.rs +0 -0
  75. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/src/config.rs +0 -0
  76. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/src/doctor.rs +0 -0
  77. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/src/main.rs +0 -0
  78. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/src/suite.rs +0 -0
  79. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/src/suite_checkpoint.rs +0 -0
  80. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/src/suite_inputs.rs +0 -0
  81. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/src/suite_journal.rs +0 -0
  82. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/src/update_check.rs +0 -0
  83. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/a11y_selector_e2e.rs +0 -0
  84. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/agent_conversation_anthropic_e2e.rs +0 -0
  85. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/agent_conversation_streaming_e2e.rs +0 -0
  86. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/agent_flow_e2e.rs +0 -0
  87. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/agent_url_record_e2e.rs +0 -0
  88. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/api_pipeline.rs +0 -0
  89. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/audit_record_e2e.rs +0 -0
  90. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/author_from_code_e2e.rs +0 -0
  91. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/calc_e2e.rs +0 -0
  92. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/citrix_start.rs +0 -0
  93. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/clock_e2e.rs +0 -0
  94. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/config_cli_e2e.rs +0 -0
  95. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/config_seed_e2e.rs +0 -0
  96. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/config_skill_e2e.rs +0 -0
  97. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/cookie_e2e.rs +0 -0
  98. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/doctor_ai_e2e.rs +0 -0
  99. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/doctor_e2e.rs +0 -0
  100. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/documented_flags.rs +0 -0
  101. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/egress_e2e.rs +0 -0
  102. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/examples_resolve.rs +0 -0
  103. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/export_e2e.rs +0 -0
  104. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/falsifiability_arg_matchers.rs +0 -0
  105. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/falsifiability_audit_since.rs +0 -0
  106. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/falsifiability_call_order.rs +0 -0
  107. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/falsifiability_capability_regression.rs +0 -0
  108. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/falsifiability_control_verdict.rs +0 -0
  109. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/falsifiability_mcp_kill.rs +0 -0
  110. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/falsifiability_no_tool_call.rs +0 -0
  111. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/falsifiability_reply_contains.rs +0 -0
  112. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/falsifiability_side_effect.rs +0 -0
  113. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/fiori_field_commit_e2e.rs +0 -0
  114. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/grid_cell_e2e.rs +0 -0
  115. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/heal_apply_proposal.rs +0 -0
  116. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/heal_vars_e2e.rs +0 -0
  117. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/iframe_e2e.rs +0 -0
  118. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/llm_author_e2e.rs +0 -0
  119. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/mcp_http_e2e.rs +0 -0
  120. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/mcp_stdio_e2e.rs +0 -0
  121. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/notepad_author_e2e.rs +0 -0
  122. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/notepad_e2e.rs +0 -0
  123. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/page_title_e2e.rs +0 -0
  124. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/pinned_random_e2e.rs +0 -0
  125. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/record_progress.rs +0 -0
  126. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/sap_e2e.rs +0 -0
  127. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/sap_pipeline.rs +0 -0
  128. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/sap_sim_e2e.rs +0 -0
  129. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/scoped_container_e2e.rs +0 -0
  130. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/select_missing_option_e2e.rs +0 -0
  131. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/sigterm_shared_browser_e2e.rs +0 -0
  132. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/skip_unless_env.rs +0 -0
  133. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/suite_checkpoint.rs +0 -0
  134. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/suite_env_from.rs +0 -0
  135. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/suite_flow_isolation.rs +0 -0
  136. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/suite_missing_trace.rs +0 -0
  137. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/suite_policy.rs +0 -0
  138. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/support/sap_simulator.py +0 -0
  139. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/visibility_e2e.rs +0 -0
  140. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/vision_pipeline.rs +0 -0
  141. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/vision_start_replay.rs +0 -0
  142. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-cli/tests/web_e2e.rs +0 -0
  143. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-driver/Cargo.toml +0 -0
  144. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-driver/src/app.rs +0 -0
  145. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-driver/src/backend.rs +0 -0
  146. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-driver/src/gdi.rs +0 -0
  147. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-driver/src/lib.rs +0 -0
  148. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-driver/src/mock.rs +0 -0
  149. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-driver/src/oob.rs +0 -0
  150. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-driver/src/recording.rs +0 -0
  151. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-driver/src/redact.rs +0 -0
  152. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-driver/src/surface.rs +0 -0
  153. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-driver/src/uia_scan.rs +0 -0
  154. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-driver/src/visual.rs +0 -0
  155. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-driver/src/window.rs +0 -0
  156. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-python/Cargo.toml +0 -0
  157. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-python/src/lib.rs +0 -0
  158. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-replay/Cargo.toml +0 -0
  159. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-replay/src/lib.rs +0 -0
  160. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-replay/src/report.rs +0 -0
  161. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-replay/src/runrecord.rs +0 -0
  162. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-replay/tests/replay_calc.rs +0 -0
  163. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/Cargo.toml +0 -0
  164. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/schema/cassette-v1.schema.json +0 -0
  165. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/schema/side-effect-v1.schema.json +0 -0
  166. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/schema/trace-v1.schema.json +0 -0
  167. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/src/captures.rs +0 -0
  168. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/src/cassette.rs +0 -0
  169. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/src/cassette_diff.rs +0 -0
  170. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/src/egress.rs +0 -0
  171. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/src/format.rs +0 -0
  172. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/src/lib.rs +0 -0
  173. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/src/secret.rs +0 -0
  174. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/src/secret_scan.rs +0 -0
  175. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/src/side_effect.rs +0 -0
  176. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/src/substitution.rs +0 -0
  177. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/src/toolcalls.rs +0 -0
  178. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/src/tosca.rs +0 -0
  179. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/tests/cassette_conformance.rs +0 -0
  180. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/tests/fixtures/guarded.trace.jsonl +0 -0
  181. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/tests/fixtures/multi.trace.jsonl +0 -0
  182. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/tests/fixtures/repeat.trace.jsonl +0 -0
  183. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/tests/fixtures/sample.trace.jsonl +0 -0
  184. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/tests/schema_conformance.rs +0 -0
  185. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/tests/side_effect_conformance.rs +0 -0
  186. {flowproof-0.23.26 → flowproof-0.23.28}/crates/flowproof-trace/tests/tosca_export.rs +0 -0
  187. {flowproof-0.23.26 → flowproof-0.23.28}/flowproof/cli.py +0 -0
  188. {flowproof-0.23.26 → flowproof-0.23.28}/flowproof/flow.py +0 -0
  189. {flowproof-0.23.26 → flowproof-0.23.28}/flowproof/mcp_server.py +0 -0
  190. {flowproof-0.23.26 → flowproof-0.23.28}/flowproof/py.typed +0 -0
@@ -930,7 +930,7 @@ dependencies = [
930
930
 
931
931
  [[package]]
932
932
  name = "flowproof-adapters"
933
- version = "0.23.26"
933
+ version = "0.23.28"
934
934
  dependencies = [
935
935
  "anyhow",
936
936
  "flowproof-driver",
@@ -949,7 +949,7 @@ dependencies = [
949
949
 
950
950
  [[package]]
951
951
  name = "flowproof-agent"
952
- version = "0.23.26"
952
+ version = "0.23.28"
953
953
  dependencies = [
954
954
  "base64",
955
955
  "chrono",
@@ -968,7 +968,7 @@ dependencies = [
968
968
 
969
969
  [[package]]
970
970
  name = "flowproof-cli"
971
- version = "0.23.26"
971
+ version = "0.23.28"
972
972
  dependencies = [
973
973
  "ab_glyph",
974
974
  "chrono",
@@ -994,7 +994,7 @@ dependencies = [
994
994
 
995
995
  [[package]]
996
996
  name = "flowproof-driver"
997
- version = "0.23.26"
997
+ version = "0.23.28"
998
998
  dependencies = [
999
999
  "calamine",
1000
1000
  "flowproof-trace",
@@ -1010,7 +1010,7 @@ dependencies = [
1010
1010
 
1011
1011
  [[package]]
1012
1012
  name = "flowproof-python"
1013
- version = "0.23.26"
1013
+ version = "0.23.28"
1014
1014
  dependencies = [
1015
1015
  "flowproof-agent",
1016
1016
  "flowproof-cli",
@@ -1022,7 +1022,7 @@ dependencies = [
1022
1022
 
1023
1023
  [[package]]
1024
1024
  name = "flowproof-replay"
1025
- version = "0.23.26"
1025
+ version = "0.23.28"
1026
1026
  dependencies = [
1027
1027
  "chrono",
1028
1028
  "flowproof-agent",
@@ -1036,7 +1036,7 @@ dependencies = [
1036
1036
 
1037
1037
  [[package]]
1038
1038
  name = "flowproof-trace"
1039
- version = "0.23.26"
1039
+ version = "0.23.28"
1040
1040
  dependencies = [
1041
1041
  "jsonschema",
1042
1042
  "regex",
@@ -22,7 +22,7 @@ members = ["crates/flowproof-driver", "crates/flowproof-trace", "crates/flowproo
22
22
  exclude = ["spike/windows-containment"]
23
23
 
24
24
  [workspace.package]
25
- version = "0.23.26"
25
+ version = "0.23.28"
26
26
  edition = "2021"
27
27
  license = "Apache-2.0"
28
28
  repository = "https://github.com/automators-com/flowproof"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flowproof
3
- Version: 0.23.26
3
+ Version: 0.23.28
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: Programming Language :: Python :: 3
@@ -98,6 +98,13 @@ pub trait SapEngine {
98
98
  /// VKey table has no Alt chords, so this is the only way to send it.
99
99
  fn close_window(&mut self) -> Result<(), DriverError>;
100
100
  fn screen_size(&mut self) -> Result<(u32, u32), DriverError>;
101
+ /// Maximize the connected session's main window and bring it to the
102
+ /// foreground, as a headed browser is at launch, so a person watching
103
+ /// the run sees the screen being driven. Scripting works on a window
104
+ /// that is behind others, so this is for the watcher, not the driver.
105
+ fn present_window(&mut self) -> Result<(), DriverError> {
106
+ Ok(())
107
+ }
101
108
  /// The session's `Info`: where the user is, for a failure report.
102
109
  /// `Ok(None)` when the engine cannot say.
103
110
  fn session_info(&mut self) -> Result<Option<SapSessionInfo>, DriverError> {
@@ -307,7 +314,15 @@ impl<E: SapEngine> AppDriver for SapAppDriver<E> {
307
314
  // `command` carries the SAP Logon connection description (may be
308
315
  // empty: attach to whatever logged-in session exists).
309
316
  self.engine
310
- .connect(command, self.credentials.as_ref(), timeout)
317
+ .connect(command, self.credentials.as_ref(), timeout)?;
318
+ // Every launch presents, including a multi-surface return visit, so
319
+ // coming back from the browser puts SAP in front again. A window
320
+ // that will not come forward is no reason to fail a run that can
321
+ // still drive it.
322
+ if let Err(error) = self.engine.present_window() {
323
+ eprintln!("sap: could not bring the SAP GUI window to the front: {error}");
324
+ }
325
+ Ok(())
311
326
  }
312
327
 
313
328
  fn stage_credentials(&mut self, credentials: LoginCredentials) -> Result<(), DriverError> {
@@ -577,6 +592,10 @@ pub mod fake {
577
592
  pub vkeys: Vec<u16>,
578
593
  pub set_texts: Vec<(String, String)>,
579
594
  pub session_info: Option<SapSessionInfo>,
595
+ /// How many times the window was maximized and brought to the front.
596
+ pub presented: u32,
597
+ /// Make `present_window` fail, as a refused foreground would.
598
+ pub refuse_present: bool,
580
599
  }
581
600
 
582
601
  impl FakeEngine {
@@ -693,6 +712,18 @@ pub mod fake {
693
712
  Ok((1920, 1080))
694
713
  }
695
714
 
715
+ /// Only a connected session has a window to present.
716
+ fn present_window(&mut self) -> Result<(), DriverError> {
717
+ if self.connected.is_none() {
718
+ return Err(DriverError::Uia("fake sap: not connected".into()));
719
+ }
720
+ if self.refuse_present {
721
+ return Err(DriverError::Uia("fake sap: foreground refused".into()));
722
+ }
723
+ self.presented += 1;
724
+ Ok(())
725
+ }
726
+
696
727
  fn session_info(&mut self) -> Result<Option<SapSessionInfo>, DriverError> {
697
728
  Ok(self.session_info.clone())
698
729
  }
@@ -748,6 +779,7 @@ pub mod com {
748
779
  use std::time::{Duration, Instant};
749
780
 
750
781
  use windows::core::{Interface, BSTR, GUID, PCWSTR};
782
+ use windows::Win32::Foundation::HWND;
751
783
  use windows::Win32::System::Com::{
752
784
  CoInitializeEx, CoTaskMemFree, CreateBindCtx, GetRunningObjectTable, IDispatch,
753
785
  COINIT_APARTMENTTHREADED, DISPATCH_FLAGS, DISPATCH_METHOD, DISPATCH_PROPERTYGET,
@@ -755,7 +787,9 @@ pub mod com {
755
787
  };
756
788
  use windows::Win32::System::Ole::DISPID_PROPERTYPUT;
757
789
  use windows::Win32::System::Variant::VARIANT;
758
- use windows::Win32::UI::WindowsAndMessaging::{GetSystemMetrics, SM_CXSCREEN, SM_CYSCREEN};
790
+ use windows::Win32::UI::WindowsAndMessaging::{
791
+ GetSystemMetrics, SetForegroundWindow, SM_CXSCREEN, SM_CYSCREEN,
792
+ };
759
793
 
760
794
  use super::{SapElement, SapEngine, SapSessionInfo};
761
795
  use flowproof_driver::{DriverError, LoginCredentials};
@@ -1462,6 +1496,25 @@ pub mod com {
1462
1496
  Ok((w.unsigned_abs().max(1), h.unsigned_abs().max(1)))
1463
1497
  }
1464
1498
 
1499
+ /// The main window, not the active one: a popup open at launch is
1500
+ /// owned by `wnd[0]` and comes forward with it, and maximizing the
1501
+ /// popup itself would fill the screen with a dialog.
1502
+ fn present_window(&mut self) -> Result<(), DriverError> {
1503
+ let window = self
1504
+ .find_disp("wnd[0]")?
1505
+ .ok_or_else(|| DriverError::Uia("sap-com: no main window".into()))?;
1506
+ // Maximize also restores a minimized window.
1507
+ window.call("Maximize", vec![])?;
1508
+ // `Handle` is the window's HWND as a Long; Windows sign-extends
1509
+ // 32-bit handles, so the cast is the documented conversion.
1510
+ if let Some(handle) = window.get_i32("Handle").filter(|handle| *handle != 0) {
1511
+ // Foregrounding can be refused (focus-steal prevention); the
1512
+ // window is still maximized and drivable, so not an error.
1513
+ let _ = unsafe { SetForegroundWindow(HWND(handle as isize as *mut _)) };
1514
+ }
1515
+ Ok(())
1516
+ }
1517
+
1465
1518
  fn session_info(&mut self) -> Result<Option<SapSessionInfo>, DriverError> {
1466
1519
  let info = self.session()?.get_disp("Info")?;
1467
1520
  Ok(Some(SapSessionInfo {
@@ -1813,6 +1866,33 @@ mod tests {
1813
1866
  );
1814
1867
  }
1815
1868
 
1869
+ /// A person watching a run sees SAP in front, as they see the browser,
1870
+ /// and again on every return visit from another surface.
1871
+ #[test]
1872
+ fn every_launch_brings_the_connected_window_to_the_front() {
1873
+ let mut driver = driver();
1874
+ driver
1875
+ .launch("TS3", "SAP", Duration::from_secs(1))
1876
+ .expect("connects");
1877
+ assert_eq!(driver.engine.presented, 1);
1878
+ driver
1879
+ .launch("TS3", "SAP", Duration::from_secs(1))
1880
+ .expect("re-attaches");
1881
+ assert_eq!(driver.engine.presented, 2);
1882
+ }
1883
+
1884
+ #[test]
1885
+ fn a_window_that_will_not_come_forward_does_not_fail_the_launch() {
1886
+ let mut driver = SapAppDriver::with_engine(FakeEngine {
1887
+ refuse_present: true,
1888
+ ..FakeEngine::with_elements(order_screen())
1889
+ });
1890
+ driver
1891
+ .launch("TS3", "SAP", Duration::from_secs(1))
1892
+ .expect("scripting still drives a window behind others");
1893
+ assert_eq!(driver.engine.connected.as_deref(), Some("TS3"));
1894
+ }
1895
+
1816
1896
  /// A password that reaches a log line or an error is a password that
1817
1897
  /// reaches CI output.
1818
1898
  #[test]
@@ -1562,8 +1562,13 @@ fn driver_key_mod(m: &flowproof_trace::format::KeyModifier) -> flowproof_driver:
1562
1562
  /// the inverse of `selectors_for` for the shapes the recorder itself
1563
1563
  /// emits. `None` = not reconstructable (reuse falls back to fresh
1564
1564
  /// authoring, never to a guess).
1565
+ ///
1566
+ /// An `a11y` selector is not the target the step was recorded with: it is a
1567
+ /// hint [`enrich_a11y_hint`] prepends afterwards so replay tries it first,
1568
+ /// and it carries a role and name, not a target. Read past it, or every web
1569
+ /// step with an accessible name is authored again on reuse.
1565
1570
  fn target_from_selector(selectors: &[Selector]) -> Option<Target> {
1566
- let primary = selectors.first()?;
1571
+ let primary = selectors.iter().find(|s| s.tier != SelectorTier::A11y)?;
1567
1572
  let get = |key: &str| primary.payload.get(key).and_then(|v| v.as_str());
1568
1573
  let base = if let Some(css) = get("css") {
1569
1574
  Target::css(css)
@@ -3108,6 +3113,12 @@ struct LiveSteps {
3108
3113
  finished: usize,
3109
3114
  current: Option<(String, std::time::Instant)>,
3110
3115
  lines: Vec<String>,
3116
+ /// The trace steps of every flow step that passed, kept as each one
3117
+ /// finishes so a failure can hand them back (see
3118
+ /// [`LocatedRecordError::completed`]).
3119
+ completed: Vec<Step>,
3120
+ /// How far into the recorder's `steps` [`Self::completed`] has read.
3121
+ kept_through: usize,
3111
3122
  }
3112
3123
 
3113
3124
  impl LiveSteps {
@@ -3122,6 +3133,20 @@ impl LiveSteps {
3122
3133
  self.current = Some((intent.to_string(), std::time::Instant::now()));
3123
3134
  }
3124
3135
 
3136
+ /// Keep the trace steps the flow step that just passed added, less the
3137
+ /// writes the page refused - the same pruning the trace gets - so what a
3138
+ /// failure hands back is exactly what the trace would have held.
3139
+ fn keep_passed(&mut self, steps: &[Step], superseded: &std::collections::BTreeSet<usize>) {
3140
+ for (index, step) in steps.iter().enumerate().skip(self.kept_through) {
3141
+ if !superseded.contains(&index) {
3142
+ let mut step = step.clone();
3143
+ step.id = format!("s{:04}", self.completed.len() + 1);
3144
+ self.completed.push(step);
3145
+ }
3146
+ }
3147
+ self.kept_through = steps.len();
3148
+ }
3149
+
3125
3150
  /// Closes the step in progress, if any: an error raised between steps
3126
3151
  /// (a `when:` condition, a surface switch, writing the trace) names none.
3127
3152
  fn finish(&mut self, mark: &str) {
@@ -3188,6 +3213,11 @@ pub struct LocatedRecordError {
3188
3213
  pub error: RecordError,
3189
3214
  /// Boxed so a `Result` carrying this stays small (clippy::result_large_err).
3190
3215
  pub at: Box<FailurePoint>,
3216
+ /// The trace steps of every flow step that passed before the failure,
3217
+ /// pruned as the trace would be. Nothing of the step that failed is in
3218
+ /// it, even the actions it got through. Held in memory only: a failed
3219
+ /// recording writes no trace, and this is not one.
3220
+ pub completed: Vec<Step>,
3191
3221
  }
3192
3222
 
3193
3223
  impl From<RecordError> for LocatedRecordError {
@@ -3195,6 +3225,7 @@ impl From<RecordError> for LocatedRecordError {
3195
3225
  Self {
3196
3226
  error,
3197
3227
  at: Box::default(),
3228
+ completed: Vec::new(),
3198
3229
  }
3199
3230
  }
3200
3231
  }
@@ -3257,6 +3288,7 @@ fn record_with_reuse_located<D: AppDriver, C: ModelClient>(
3257
3288
  step,
3258
3289
  screen: driver.failure_screen(),
3259
3290
  }),
3291
+ completed: std::mem::take(&mut live.completed),
3260
3292
  }
3261
3293
  })
3262
3294
  }
@@ -4915,6 +4947,7 @@ fn record_steps<D: AppDriver, C: ModelClient>(
4915
4947
  if let Some(last) = prior_history.last_mut() {
4916
4948
  *last = step_history(&step_intent, &executed_summaries, is_check);
4917
4949
  }
4950
+ live.keep_passed(&steps, &superseded_steps);
4918
4951
  live.finish("PASS");
4919
4952
  }
4920
4953
 
@@ -6041,6 +6074,82 @@ steps:
6041
6074
  std::fs::remove_file(&out).ok();
6042
6075
  }
6043
6076
 
6077
+ /// What a failed recording hands back is what a repair retry replays:
6078
+ /// every step that passed, none of the one that failed, so the retry
6079
+ /// asks the model only about the step it patched.
6080
+ #[test]
6081
+ fn a_failed_recording_hands_back_the_steps_that_passed() {
6082
+ let spec = FlowSpec::parse(
6083
+ "name: Signup\napp: web\nurl: https://example.test\nsteps:\n \
6084
+ - Fill in the email and continue\n - Save the profile\n - Publish it\n",
6085
+ )
6086
+ .expect("spec parses");
6087
+ let scene = r##"[{"target":"css:#email","tag":"input","label":"Email"},
6088
+ {"target":"css:#next","tag":"button","text":"Next"},
6089
+ {"target":"css:#save","tag":"button","text":"Save"},
6090
+ {"target":"css:#publish","tag":"button","text":"Publish"}]"##;
6091
+ let dir = std::env::temp_dir().join("flowproof-failed-hands-back-passed");
6092
+ std::fs::create_dir_all(&dir).expect("temp dir");
6093
+ let out = dir.join("signup.trace.jsonl");
6094
+ let _ = std::fs::remove_file(&out);
6095
+ let options = flowproof_driver::RecordingOptions::default;
6096
+
6097
+ // The model answers the first two steps and has nothing for the third.
6098
+ let mut driver = MockAppDriver::new(&["#email", "#next", "#save", "#publish"]);
6099
+ driver.scene = Some(scene.into());
6100
+ let mut client = ScriptedClient::new(&[
6101
+ r##"[{"action":"type_text","target":"css:#email","text":"me@work.example"},
6102
+ {"action":"click","target":"css:#next"}]"##,
6103
+ r##"[{"action":"click","target":"css:#save"}]"##,
6104
+ ]);
6105
+ let failed = record_with_reuse_located(
6106
+ &spec,
6107
+ &mut driver,
6108
+ &out,
6109
+ Author::Auto,
6110
+ Some(&mut client),
6111
+ None,
6112
+ options(),
6113
+ )
6114
+ .expect_err("the third step has no answer");
6115
+ let intents: Vec<&str> = failed.completed.iter().map(|s| s.intent.as_str()).collect();
6116
+ assert_eq!(
6117
+ intents,
6118
+ [
6119
+ "Fill in the email and continue",
6120
+ "Fill in the email and continue",
6121
+ "Save the profile"
6122
+ ]
6123
+ );
6124
+ let ids: Vec<&str> = failed.completed.iter().map(|s| s.id.as_str()).collect();
6125
+ assert_eq!(ids, ["s0001", "s0002", "s0003"]);
6126
+ assert!(!out.exists(), "a failed recording writes no trace");
6127
+
6128
+ // Replaying them, the model is asked about the third step only.
6129
+ let mut driver = MockAppDriver::new(&["#email", "#next", "#save", "#publish"]);
6130
+ driver.scene = Some(scene.into());
6131
+ let mut client =
6132
+ ScriptedClient::new(&[r##"[{"action":"click","target":"css:#publish"}]"##]);
6133
+ let summary = record_with_reuse_located(
6134
+ &spec,
6135
+ &mut driver,
6136
+ &out,
6137
+ Author::Auto,
6138
+ Some(&mut client),
6139
+ Some(&failed.completed),
6140
+ options(),
6141
+ )
6142
+ .expect("the retry records");
6143
+ assert_eq!(
6144
+ client.prompts.len(),
6145
+ 1,
6146
+ "only the step that failed is authored"
6147
+ );
6148
+ assert_eq!(summary.reused_steps, 3);
6149
+ assert_eq!(summary.steps, 4);
6150
+ std::fs::remove_dir_all(&dir).ok();
6151
+ }
6152
+
6044
6153
  /// The rejected-form guard is scoped to model authoring, and stays that
6045
6154
  /// way.
6046
6155
  ///
@@ -7049,6 +7158,37 @@ steps:
7049
7158
  std::fs::remove_dir_all(&dir).ok();
7050
7159
  }
7051
7160
 
7161
+ #[test]
7162
+ fn a_step_with_an_a11y_hint_still_decodes_for_reuse() {
7163
+ let click = ResolvedAction::Press {
7164
+ target: Target::css("#greet"),
7165
+ label: "Press the greet button".into(),
7166
+ dialog: None,
7167
+ };
7168
+ let mut step = step_for(1, "Press the greet button", "web", &click);
7169
+ enrich_a11y_hint(
7170
+ &mut step,
7171
+ &flowproof_driver::A11yHints {
7172
+ role: "button".into(),
7173
+ name: "Greet".into(),
7174
+ ancestor_role: Some("RootWebArea".into()),
7175
+ ancestor_name: Some("Greeter".into()),
7176
+ },
7177
+ );
7178
+ assert_eq!(step.selectors[0].tier, SelectorTier::A11y, "the hint leads");
7179
+ assert_eq!(decode_step(&step), Some(click));
7180
+
7181
+ let only_a_hint = Step {
7182
+ selectors: step.selectors[..1].to_vec(),
7183
+ ..step
7184
+ };
7185
+ assert_eq!(
7186
+ decode_step(&only_a_hint),
7187
+ None,
7188
+ "a role and name alone are not a target to reuse"
7189
+ );
7190
+ }
7191
+
7052
7192
  #[test]
7053
7193
  fn upload_and_right_click_decode_back_for_reuse() {
7054
7194
  // decode_step must be a strict inverse of step_for so `record