synapse-cli-agent 0.1.41__tar.gz → 0.1.43__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 (575) hide show
  1. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/.github/workflows/release.yml +10 -1
  2. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/CHANGELOG.md +26 -0
  3. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/PKG-INFO +15 -1
  4. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/README.md +14 -0
  5. synapse_cli_agent-0.1.43/bucket/synapse.json +21 -0
  6. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/pyproject.toml +1 -1
  7. synapse_cli_agent-0.1.43/release_body.md +12 -0
  8. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/models/rust_openai.py +48 -29
  9. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/middleware.py +18 -2
  10. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/rendering.py +67 -0
  11. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/status_controller.py +15 -3
  12. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/transcript/controller.py +9 -2
  13. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/transcript_blocks.py +152 -2
  14. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/tui.py +3 -0
  15. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/tui_launch.py +3 -0
  16. synapse_cli_agent-0.1.43/src/synapse/ui/workspace.py +64 -0
  17. synapse_cli_agent-0.1.43/tests/test_markdown_image.py +147 -0
  18. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_model_request_compression_middleware.py +26 -1
  19. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_model_retry.py +12 -0
  20. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_rust_openai_model.py +100 -0
  21. synapse_cli_agent-0.1.43/tests/test_status_controller.py +31 -0
  22. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_transcript_controller.py +14 -0
  23. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/uv.lock +1 -1
  24. synapse_cli_agent-0.1.41/release_body.md +0 -7
  25. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/.dockerignore +0 -0
  26. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/.github/workflows/ci.yml +0 -0
  27. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/.github/workflows/docs.yml +0 -0
  28. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/.github/workflows/native-compression-wheels.yml +0 -0
  29. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/.github/workflows/native-core-tool-wheels.yml +0 -0
  30. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/.gitignore +0 -0
  31. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/.python-version +0 -0
  32. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/.readthedocs.yaml +0 -0
  33. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/.zed/settings.json +0 -0
  34. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/AGENTS.md +0 -0
  35. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/Dockerfile.web +0 -0
  36. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/LICENSE +0 -0
  37. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/README.zh-CN.md +0 -0
  38. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/agent_upstream.txt +0 -0
  39. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/approval-behavior.md +0 -0
  40. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/assets/demo.gif +0 -0
  41. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/assets/synapse-logo.svg +0 -0
  42. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/assets/tui-preview.png +0 -0
  43. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/cli_upstream.txt +0 -0
  44. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/debug_compact.py +0 -0
  45. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/decode_screenshot.py +0 -0
  46. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/acp-adapter/capability-matrix.md +0 -0
  47. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/acp-adapter/decisions.md +0 -0
  48. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/acp-adapter/index.md +0 -0
  49. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/acp-adapter/phase-0-protocol-baseline.md +0 -0
  50. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/acp-adapter/phase-1-core-transport.md +0 -0
  51. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/acp-adapter/phase-2-prompt-semantics.md +0 -0
  52. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/acp-adapter/phase-3-permissions.md +0 -0
  53. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/acp-adapter/phase-4-session-lifecycle.md +0 -0
  54. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/acp-adapter/phase-5-session-mcp.md +0 -0
  55. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/acp-adapter/phase-6-client-services.md +0 -0
  56. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/acp-adapter/phase-7-advanced-capabilities.md +0 -0
  57. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/acp-adapter/phase-8-compliance.md +0 -0
  58. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/acp-adapter/progress.md +0 -0
  59. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-development-guide.md +0 -0
  60. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/baseline-report.md +0 -0
  61. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/decisions.md +0 -0
  62. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/index.md +0 -0
  63. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/migration.md +0 -0
  64. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/phase-0-baseline.md +0 -0
  65. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/phase-1-streaming-core.md +0 -0
  66. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/phase-2-turn-runtime.md +0 -0
  67. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/phase-3-tui-cutover.md +0 -0
  68. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/phase-4-session-runtime.md +0 -0
  69. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/phase-5-multi-session.md +0 -0
  70. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/phase-6-project-runtime.md +0 -0
  71. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/phase-7-global-control-plane.md +0 -0
  72. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/phase-8-hardening.md +0 -0
  73. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/post-review-fix-plan.md +0 -0
  74. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/agent-runtime-decoupling/progress.md +0 -0
  75. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/architecture-flow.md +0 -0
  76. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/architecture.md +0 -0
  77. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/cli.md +0 -0
  78. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/codex-session-discovery-phase-1.md +0 -0
  79. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/codex-session-import-phase-2.md +0 -0
  80. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/config.md +0 -0
  81. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/design.md +0 -0
  82. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/docker-web.md +0 -0
  83. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/index.md +0 -0
  84. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/install.md +0 -0
  85. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/math-formulas-test.md +0 -0
  86. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/mcp.md +0 -0
  87. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/models.md +0 -0
  88. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/native-compression-core.md +0 -0
  89. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/native-core-tool.md +0 -0
  90. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/permissions.md +0 -0
  91. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/quickstart.md +0 -0
  92. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/sessions.md +0 -0
  93. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/skills.md +0 -0
  94. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/smith_output.md +0 -0
  95. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/subagents.md +0 -0
  96. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/tool-output-transform.md +0 -0
  97. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/tui-cursor-refactor.md +0 -0
  98. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/tutorial.md +0 -0
  99. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/docs/x-agent-development-guide.md +0 -0
  100. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/examples/mcp.example.json +0 -0
  101. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/examples/models.example.json +0 -0
  102. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/examples/settings.example.json +0 -0
  103. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/middleware_upstream.txt +0 -0
  104. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/mkdocs.yml +0 -0
  105. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-core-tool/Cargo.lock +0 -0
  106. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-core-tool/Cargo.toml +0 -0
  107. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-core-tool/LICENSE +0 -0
  108. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-core-tool/NOTICE +0 -0
  109. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-core-tool/README.md +0 -0
  110. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-core-tool/pyproject.toml +0 -0
  111. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-core-tool/python/synapse_core_tool/__init__.py +0 -0
  112. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-core-tool/src/file_access.rs +0 -0
  113. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-core-tool/src/file_tools.rs +0 -0
  114. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-core-tool/src/lib.rs +0 -0
  115. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-core-tool/src/llm.rs +0 -0
  116. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-core-tool/src/math_render.rs +0 -0
  117. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-core-tool/src/search.rs +0 -0
  118. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-core-tool/uv.lock +0 -0
  119. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/Cargo.lock +0 -0
  120. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/Cargo.toml +0 -0
  121. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/LICENSE +0 -0
  122. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/NOTICE +0 -0
  123. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/README.md +0 -0
  124. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/pyproject.toml +0 -0
  125. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/python/synapse_tool_compress_core/__init__.py +0 -0
  126. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/ccr.rs +0 -0
  127. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/ccr_in_memory.rs +0 -0
  128. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/mod.rs +0 -0
  129. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/relevance/base.rs +0 -0
  130. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/relevance/bm25.rs +0 -0
  131. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/signals/keyword_detector.rs +0 -0
  132. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/signals/line_importance.rs +0 -0
  133. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/adaptive_sizer.rs +0 -0
  134. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/anchor_selector.rs +0 -0
  135. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/code_compressor.rs +0 -0
  136. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/diff_compressor.rs +0 -0
  137. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/log_compressor.rs +0 -0
  138. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/search_compressor.rs +0 -0
  139. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/analyzer.rs +0 -0
  140. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/anchors.rs +0 -0
  141. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/builder.rs +0 -0
  142. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/classifier.rs +0 -0
  143. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/compaction/classifier.rs +0 -0
  144. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/compaction/compactor.rs +0 -0
  145. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/compaction/formatter.rs +0 -0
  146. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/compaction/ir.rs +0 -0
  147. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/compaction/mod.rs +0 -0
  148. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/compaction/walker.rs +0 -0
  149. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/config.rs +0 -0
  150. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/constraints.rs +0 -0
  151. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/crusher.rs +0 -0
  152. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/crushers.rs +0 -0
  153. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/error_keywords.rs +0 -0
  154. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/field_detect.rs +0 -0
  155. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/hashing.rs +0 -0
  156. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/mod.rs +0 -0
  157. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/observer.rs +0 -0
  158. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/orchestration.rs +0 -0
  159. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/outliers.rs +0 -0
  160. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/planning.rs +0 -0
  161. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/statistics.rs +0 -0
  162. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/stats_math.rs +0 -0
  163. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/traits.rs +0 -0
  164. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/headroom_port/transforms/smart_crusher/types.rs +0 -0
  165. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/rust/synapse-tool-compress-core/src/lib.rs +0 -0
  166. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/scripts/build_check_rust_openai.py +0 -0
  167. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/scripts/install.ps1 +0 -0
  168. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/scripts/release.ps1 +0 -0
  169. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/scripts/serve_web.py +0 -0
  170. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/slash_cmds_upstream.txt +0 -0
  171. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/__init__.py +0 -0
  172. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/__main__.py +0 -0
  173. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/acp/__init__.py +0 -0
  174. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/acp/agent.py +0 -0
  175. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/acp/client_services.py +0 -0
  176. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/acp/content.py +0 -0
  177. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/acp/events.py +0 -0
  178. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/acp/lifecycle.py +0 -0
  179. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/acp/mcp.py +0 -0
  180. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/acp/permissions.py +0 -0
  181. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/acp/server.py +0 -0
  182. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/acp/sessions.py +0 -0
  183. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/acp/updates.py +0 -0
  184. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/app/__init__.py +0 -0
  185. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/app/agent.py +0 -0
  186. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/app/agent_assembly.py +0 -0
  187. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/app/agent_md.py +0 -0
  188. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/cli.py +0 -0
  189. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/commands/__init__.py +0 -0
  190. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/commands/compression.py +0 -0
  191. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/commands/goal.py +0 -0
  192. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/commands/helpers.py +0 -0
  193. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/commands/mcp.py +0 -0
  194. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/commands/model.py +0 -0
  195. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/commands/result.py +0 -0
  196. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/commands/sessions.py +0 -0
  197. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/commands/slash_cmds.py +0 -0
  198. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/commands/slash_complete.py +0 -0
  199. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/commands/theme.py +0 -0
  200. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/config.py +0 -0
  201. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/content/__init__.py +0 -0
  202. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/content/input_history.py +0 -0
  203. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/content/multimodal.py +0 -0
  204. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/content/prompts.py +0 -0
  205. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/content/skills_catalog.py +0 -0
  206. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/entry.py +0 -0
  207. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/goals/__init__.py +0 -0
  208. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/goals/middleware.py +0 -0
  209. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/goals/model.py +0 -0
  210. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/goals/runtime.py +0 -0
  211. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/goals/steering.py +0 -0
  212. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/goals/store.py +0 -0
  213. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/goals/tools.py +0 -0
  214. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/__init__.py +0 -0
  215. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/checkpoint_seed.py +0 -0
  216. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/codex_config.py +0 -0
  217. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/codex_history.py +0 -0
  218. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/codex_import.py +0 -0
  219. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/codex_sessions.py +0 -0
  220. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/describe_image.py +0 -0
  221. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/herdr.py +0 -0
  222. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/http_clients.py +0 -0
  223. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/llm_openai_compat.py +0 -0
  224. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/llm_openai_websocket.py +0 -0
  225. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/mcp_client.py +0 -0
  226. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/openai_oauth.py +0 -0
  227. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/openai_oauth_middleware.py +0 -0
  228. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/openai_usage.py +0 -0
  229. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/turbo.py +0 -0
  230. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/integrations/vision_middleware.py +0 -0
  231. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/memory/__init__.py +0 -0
  232. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/memory/auto_recorder.py +0 -0
  233. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/memory/embedder.py +0 -0
  234. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/memory/long_term.py +0 -0
  235. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/models/__init__.py +0 -0
  236. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/models/config.py +0 -0
  237. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/models/helpers.py +0 -0
  238. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/models/persist.py +0 -0
  239. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/models/profile.py +0 -0
  240. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/models/providers.py +0 -0
  241. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/models/registry.py +0 -0
  242. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/models_registry.py +0 -0
  243. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/observability/__init__.py +0 -0
  244. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/observability/debug_inspector.html +0 -0
  245. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/observability/debug_server.py +0 -0
  246. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/observability/exit_trace.py +0 -0
  247. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/observability/heap_dump.py +0 -0
  248. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/observability/llm_debug.py +0 -0
  249. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/observability/startup_trace.py +0 -0
  250. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/planner/__init__.py +0 -0
  251. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/planner/task_planner.py +0 -0
  252. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/projects/__init__.py +0 -0
  253. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/projects/catalog.py +0 -0
  254. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/rag/__init__.py +0 -0
  255. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/rag/knowledge_base.py +0 -0
  256. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/__init__.py +0 -0
  257. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/agent_loop/__init__.py +0 -0
  258. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/agent_loop/model.py +0 -0
  259. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/agent_loop/request.py +0 -0
  260. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/agent_loop/turn.py +0 -0
  261. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/async_runtime.py +0 -0
  262. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/backends.py +0 -0
  263. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/cancellation.py +0 -0
  264. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/context_compact.py +0 -0
  265. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/debug_capture_middleware.py +0 -0
  266. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/execute_capture.py +0 -0
  267. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/filesystem_tool_prompt_middleware.py +0 -0
  268. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/fs_permissions.py +0 -0
  269. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/harness.py +0 -0
  270. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/hitl.py +0 -0
  271. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/interaction_ledger.py +0 -0
  272. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/model_request_compression_middleware.py +0 -0
  273. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/pathing.py +0 -0
  274. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/projects/__init__.py +0 -0
  275. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/projects/identity.py +0 -0
  276. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/projects/runtime.py +0 -0
  277. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/safety.py +0 -0
  278. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/session_header_middleware.py +0 -0
  279. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/session_headers.py +0 -0
  280. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/session_prewarm.py +0 -0
  281. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/sessions/__init__.py +0 -0
  282. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/sessions/events.py +0 -0
  283. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/sessions/manager.py +0 -0
  284. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/sessions/persistence.py +0 -0
  285. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/sessions/ref.py +0 -0
  286. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/sessions/runtime.py +0 -0
  287. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/steer.py +0 -0
  288. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/streaming/__init__.py +0 -0
  289. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/streaming/accumulator.py +0 -0
  290. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/streaming/adapters.py +0 -0
  291. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/streaming/events.py +0 -0
  292. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/streaming/parser.py +0 -0
  293. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/streaming/protocol.py +0 -0
  294. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/streaming/runtime.py +0 -0
  295. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/streaming/stream_events.py +0 -0
  296. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/streaming/tool_model.py +0 -0
  297. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/subagent_config_persist.py +0 -0
  298. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/subagent_specs.py +0 -0
  299. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/subagents.py +0 -0
  300. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/timeline.py +0 -0
  301. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/token_rate.py +0 -0
  302. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/tool_ignore.py +0 -0
  303. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/tool_output_eval.py +0 -0
  304. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/tool_output_middleware.py +0 -0
  305. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/runtime/tool_output_usage_middleware.py +0 -0
  306. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/sessions/__init__.py +0 -0
  307. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/sessions/cancel_repair.py +0 -0
  308. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/sessions/search_index.py +0 -0
  309. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/sessions/store.py +0 -0
  310. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/sessions/summary.py +0 -0
  311. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/sessions/transcript.py +0 -0
  312. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/sessions/transcript_migration.py +0 -0
  313. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/sessions/transcript_projection.py +0 -0
  314. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/settings/__init__.py +0 -0
  315. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/settings/config_paths.py +0 -0
  316. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/settings/schema.py +0 -0
  317. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/subagents.py +0 -0
  318. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/tool_output/__init__.py +0 -0
  319. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/tool_output/detection.py +0 -0
  320. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/tool_output/metrics.py +0 -0
  321. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/tool_output/models.py +0 -0
  322. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/tool_output/pipeline.py +0 -0
  323. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/tool_output/repository.py +0 -0
  324. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/tool_output/transformers.py +0 -0
  325. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/tools/__init__.py +0 -0
  326. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/tools/describe_image.py +0 -0
  327. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/tools/filesystem_patch.py +0 -0
  328. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/tools/filesystem_search.py +0 -0
  329. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/tools/session_tools.py +0 -0
  330. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/__init__.py +0 -0
  331. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/agent_lifecycle.py +0 -0
  332. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/answer_divider.py +0 -0
  333. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/approval.py +0 -0
  334. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/bottombar/__init__.py +0 -0
  335. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/bottombar/components/__init__.py +0 -0
  336. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/bottombar/components/codex_usage.py +0 -0
  337. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/bottombar/components/fast.py +0 -0
  338. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/bottombar/components/goal.py +0 -0
  339. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/bottombar/components/key_hints.py +0 -0
  340. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/bottombar/components/mcp.py +0 -0
  341. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/bottombar/components/mode.py +0 -0
  342. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/bottombar/components/model.py +0 -0
  343. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/bottombar/components/thread.py +0 -0
  344. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/bottombar/components/turbo.py +0 -0
  345. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/bottombar/components/turn_stats.py +0 -0
  346. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/bottombar/context.py +0 -0
  347. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/bottombar/core.py +0 -0
  348. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/chrome/__init__.py +0 -0
  349. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/chrome/controller.py +0 -0
  350. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/clipboard.py +0 -0
  351. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/__init__.py +0 -0
  352. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/active_session_switcher.py +0 -0
  353. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/base.py +0 -0
  354. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/codex_config_import.py +0 -0
  355. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/codex_reset.py +0 -0
  356. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/codex_session_list.py +0 -0
  357. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/compression_diagnostics.py +0 -0
  358. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/controller.py +0 -0
  359. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/git_explore.py +0 -0
  360. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/mcp_panel.py +0 -0
  361. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/model_form.py +0 -0
  362. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/model_manager.py +0 -0
  363. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/model_picker.py +0 -0
  364. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/provider_catalog.py +0 -0
  365. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/safety_panel.py +0 -0
  366. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/session_list.py +0 -0
  367. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/subagent_config.py +0 -0
  368. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/theme_designer.py +0 -0
  369. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/dialogs/theme_picker.py +0 -0
  370. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/drawer.py +0 -0
  371. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/formatters.py +0 -0
  372. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/git_explore/__init__.py +0 -0
  373. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/git_explore/engine.py +0 -0
  374. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/git_explore/provider.py +0 -0
  375. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/git_explore/unified.py +0 -0
  376. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/image_preview.py +0 -0
  377. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/image_render.py +0 -0
  378. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/image_viewer.py +0 -0
  379. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/math_image.py +0 -0
  380. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/mermaid_image.py +0 -0
  381. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/prompt_controller.py +0 -0
  382. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/selectable_static.py +0 -0
  383. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/selectable_text.py +0 -0
  384. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/sink.py +0 -0
  385. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/steer_controller.py +0 -0
  386. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/steer_widget.py +0 -0
  387. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/stream.py +0 -0
  388. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/stream_events.py +0 -0
  389. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/stream_runtime.py +0 -0
  390. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/textual_lifecycle.py +0 -0
  391. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/textual_stream_sink.py +0 -0
  392. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/theme.py +0 -0
  393. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/theme_controller.py +0 -0
  394. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/timeline.py +0 -0
  395. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/tool_blocks.py +0 -0
  396. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/topbar/__init__.py +0 -0
  397. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/topbar/components/__init__.py +0 -0
  398. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/topbar/components/branch.py +0 -0
  399. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/topbar/components/title.py +0 -0
  400. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/topbar/components/tool_output.py +0 -0
  401. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/topbar/components/usage.py +0 -0
  402. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/topbar/components/workspace.py +0 -0
  403. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/topbar/context.py +0 -0
  404. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/topbar/core.py +0 -0
  405. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/topbar/git_changes_popover.py +0 -0
  406. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/topbar/git_chrome.py +0 -0
  407. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/topbar/tool_output_popover.py +0 -0
  408. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/topbar/widget.py +0 -0
  409. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/transcript/__init__.py +0 -0
  410. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/transcript/factory.py +0 -0
  411. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/transcript/history.py +0 -0
  412. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/transcript/state.py +0 -0
  413. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/tui_styles.py +0 -0
  414. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/turn/__init__.py +0 -0
  415. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/turn/controller.py +0 -0
  416. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/turn/event_bridge.py +0 -0
  417. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/turn/event_renderer.py +0 -0
  418. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/turn/persistence.py +0 -0
  419. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/turn/request.py +0 -0
  420. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/turn_rail.py +0 -0
  421. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/turn_rail_widgets.py +0 -0
  422. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/user_turn.py +0 -0
  423. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/user_turn_block.py +0 -0
  424. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/ui/welcome.py +0 -0
  425. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/src/synapse/web.py +0 -0
  426. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/synapse.cmd +0 -0
  427. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/__init__.py +0 -0
  428. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/fixtures/acp/initialize.jsonl +0 -0
  429. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/fixtures/agent_stream/core_scenarios.json +0 -0
  430. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/fixtures/codex_rollouts/duplicate_response_item.jsonl +0 -0
  431. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/fixtures/codex_rollouts/incomplete_and_aborted.jsonl +0 -0
  432. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/fixtures/codex_rollouts/legacy_compaction.jsonl +0 -0
  433. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/fixtures/codex_rollouts/normal_completed.jsonl +0 -0
  434. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/fixtures/codex_rollouts/replacement_history.jsonl +0 -0
  435. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/fixtures/codex_rollouts/rollback.jsonl +0 -0
  436. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/fixtures/codex_rollouts/unsupported_replacement.jsonl +0 -0
  437. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/fixtures/sample_repo/calculator.py +0 -0
  438. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/fixtures/sample_repo/test_calculator.py +0 -0
  439. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/fixtures/tool_output_eval.json +0 -0
  440. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test.py +0 -0
  441. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_acp_p0_baseline.py +0 -0
  442. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_acp_p1_core.py +0 -0
  443. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_acp_p1_transport.py +0 -0
  444. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_acp_p2_content.py +0 -0
  445. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_acp_p2_events.py +0 -0
  446. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_acp_p2_updates.py +0 -0
  447. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_acp_p3_agent.py +0 -0
  448. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_acp_p3_permissions.py +0 -0
  449. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_acp_p4_history.py +0 -0
  450. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_acp_p4_lifecycle.py +0 -0
  451. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_acp_p5_mcp.py +0 -0
  452. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_acp_p6_client_services.py +0 -0
  453. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_acp_p8_compliance.py +0 -0
  454. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_agent_factory.py +0 -0
  455. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_agent_lifecycle.py +0 -0
  456. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_agent_turn_runtime.py +0 -0
  457. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_approval.py +0 -0
  458. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_async_checkpointer.py +0 -0
  459. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_backends.py +0 -0
  460. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_bottombar_registry.py +0 -0
  461. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_cancel_repair.py +0 -0
  462. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_capabilities.py +0 -0
  463. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_checkpoint_seed.py +0 -0
  464. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_chrome_controller.py +0 -0
  465. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_cli.py +0 -0
  466. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_cli_codex_import.py +0 -0
  467. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_clipboard.py +0 -0
  468. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_codex_config.py +0 -0
  469. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_codex_history.py +0 -0
  470. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_codex_import.py +0 -0
  471. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_codex_sessions.py +0 -0
  472. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_codex_sessions_windows.py +0 -0
  473. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_compact_tool_descriptions.py +0 -0
  474. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_config.py +0 -0
  475. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_context_compact.py +0 -0
  476. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_context_window.py +0 -0
  477. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_debug_capture_middleware.py +0 -0
  478. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_debug_inspector.py +0 -0
  479. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_describe_image.py +0 -0
  480. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_dialogs.py +0 -0
  481. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_entry.py +0 -0
  482. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_filesystem_patch_tool.py +0 -0
  483. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_filesystem_search_tools.py +0 -0
  484. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_git_changes_popover.py +0 -0
  485. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_git_chrome.py +0 -0
  486. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_git_explore.py +0 -0
  487. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_goal_live_tui.py +0 -0
  488. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_goals.py +0 -0
  489. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_heap_dump.py +0 -0
  490. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_herdr_integration.py +0 -0
  491. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_http_clients.py +0 -0
  492. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_image_render.py +0 -0
  493. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_image_viewer.py +0 -0
  494. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_input_history.py +0 -0
  495. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_iteration_abc.py +0 -0
  496. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_layered_config.py +0 -0
  497. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_math_image_render.py +0 -0
  498. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_mcp_schema.py +0 -0
  499. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_mermaid_image.py +0 -0
  500. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_mermaid_render.py +0 -0
  501. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_middleware_async.py +0 -0
  502. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_model_dialogs.py +0 -0
  503. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_model_providers.py +0 -0
  504. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_models_persist.py +0 -0
  505. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_multimodal.py +0 -0
  506. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_native_math_render.py +0 -0
  507. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_openai_compat_reasoning.py +0 -0
  508. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_openai_oauth.py +0 -0
  509. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_openai_oauth_middleware.py +0 -0
  510. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_openai_usage.py +0 -0
  511. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_openai_websocket.py +0 -0
  512. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_pathing.py +0 -0
  513. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_project_catalog.py +0 -0
  514. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_project_drawer.py +0 -0
  515. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_project_runtime.py +0 -0
  516. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_project_switch.py +0 -0
  517. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_prompt_controller.py +0 -0
  518. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_prompts.py +0 -0
  519. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_runtime_hardening.py +0 -0
  520. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_runtime_manager.py +0 -0
  521. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_runtime_streaming.py +0 -0
  522. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_safety.py +0 -0
  523. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_search_index.py +0 -0
  524. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_session_headers.py +0 -0
  525. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_session_persistence.py +0 -0
  526. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_session_prewarm.py +0 -0
  527. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_session_runtime.py +0 -0
  528. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_session_store.py +0 -0
  529. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_session_summary.py +0 -0
  530. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_slash_and_mcp.py +0 -0
  531. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_slash_complete.py +0 -0
  532. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_slash_effects.py +0 -0
  533. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_startup_defer.py +0 -0
  534. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_startup_trace.py +0 -0
  535. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_steer.py +0 -0
  536. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_steer_controller.py +0 -0
  537. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_stream_cancel.py +0 -0
  538. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_stream_semantic_fixtures.py +0 -0
  539. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_stream_tool_items.py +0 -0
  540. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_stream_ui.py +0 -0
  541. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_subagent_config_dialog.py +0 -0
  542. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_subagent_config_persist.py +0 -0
  543. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_subagent_status.py +0 -0
  544. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_subagents.py +0 -0
  545. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_textual_stream_sink.py +0 -0
  546. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_theme.py +0 -0
  547. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_theme_controller.py +0 -0
  548. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_timeline.py +0 -0
  549. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_token_rate.py +0 -0
  550. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_tool_blocks.py +0 -0
  551. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_tool_ignore.py +0 -0
  552. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_tool_intent.py +0 -0
  553. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_tool_output.py +0 -0
  554. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_tool_output_eval.py +0 -0
  555. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_tool_output_slash.py +0 -0
  556. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_tool_output_usage_middleware.py +0 -0
  557. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_topbar_context_ratio.py +0 -0
  558. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_topbar_registry.py +0 -0
  559. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_transcript.py +0 -0
  560. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_transcript_history.py +0 -0
  561. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_transcript_history_controller.py +0 -0
  562. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_transcript_migration.py +0 -0
  563. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_transcript_projection.py +0 -0
  564. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_tui_active_session_switcher.py +0 -0
  565. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_tui_codex_import.py +0 -0
  566. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_tui_paste.py +0 -0
  567. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_tui_selection.py +0 -0
  568. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_turn_controller.py +0 -0
  569. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_turn_event_renderer.py +0 -0
  570. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_turn_rail_minimap.py +0 -0
  571. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_turn_request.py +0 -0
  572. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_usage_restore.py +0 -0
  573. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_user_turn_style.py +0 -0
  574. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/test_welcome.py +0 -0
  575. {synapse_cli_agent-0.1.41 → synapse_cli_agent-0.1.43}/tests/tool_output_plugin_fixture.py +0 -0
@@ -118,11 +118,20 @@ jobs:
118
118
  if: runner.os != 'Windows'
119
119
  run: chmod +x "dist/${{ matrix.binname }}"
120
120
 
121
+ - name: Generate SHA256 checksum
122
+ shell: pwsh
123
+ run: |
124
+ $hash = (Get-FileHash -Algorithm SHA256 -LiteralPath "dist/${{ matrix.binname }}").Hash.ToLower()
125
+ Set-Content -LiteralPath "dist/${{ matrix.binname }}.sha256" -Value $hash -NoNewline
126
+ Write-Host "sha256 for ${{ matrix.binname }}: $hash"
127
+
121
128
  - name: Upload executable artifact
122
129
  uses: actions/upload-artifact@v4
123
130
  with:
124
131
  name: ${{ matrix.artifact }}
125
- path: dist/${{ matrix.binname }}
132
+ path: |
133
+ dist/${{ matrix.binname }}
134
+ dist/${{ matrix.binname }}.sha256
126
135
  if-no-files-found: error
127
136
 
128
137
  release:
@@ -8,6 +8,32 @@ All entries are written in English.
8
8
 
9
9
  ---
10
10
 
11
+ ## v0.1.43
12
+
13
+ ### New Features
14
+
15
+ - Added Scoop distribution support: a new `bucket/synapse.json` manifest (with `checkver`/`autoupdate`) and a single-file Windows executable let Windows users install and auto-update Synapse via Scoop (`scoop install synapse`).
16
+
17
+ ### Engineering
18
+
19
+ - The release workflow now publishes a SHA-256 checksum (`<bin>.sha256`) alongside each platform executable, so Scoop's `autoupdate` can verify downloads without manual hash maintenance.
20
+ - Documented Scoop installation in the README.
21
+
22
+ ---
23
+
24
+ ## v0.1.42
25
+
26
+ ### Bug Fixes
27
+
28
+ - Retried a stale native Responses WebSocket connection once on a fresh socket when the request failed before any output, while avoiding replay after partial streaming output.
29
+ - Classified native WebSocket send/receive connection failures as transient without broadly retrying unrelated operating-system errors.
30
+
31
+ ### Engineering
32
+
33
+ - Added focused coverage for WebSocket reconnect/replay behavior and transient transport-error classification.
34
+
35
+ ---
36
+
11
37
  ## v0.1.41
12
38
 
13
39
  ### New Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: synapse-cli-agent
3
- Version: 0.1.41
3
+ Version: 0.1.43
4
4
  Summary: Local coding agent built on LangChain Deep Agents (LocalShell, no sandbox)
5
5
  Project-URL: Homepage, https://github.com/alex8224/synapse-agent
6
6
  Project-URL: Repository, https://github.com/alex8224/synapse-agent
@@ -270,6 +270,20 @@ One command, no clone required:
270
270
  uv tool install synapse-cli-agent
271
271
  ```
272
272
 
273
+ Windows users can also install via Scoop (single-file executable, auto-updated
274
+ through `checkver`): add the bucket, then install:
275
+
276
+ ```powershell
277
+ scoop bucket add synapse https://github.com/alex8224/synapse-agent
278
+ scoop install synapse
279
+ ```
280
+
281
+ Or install directly from the manifest URL:
282
+
283
+ ```powershell
284
+ scoop install https://raw.githubusercontent.com/alex8224/synapse-agent/main/bucket/synapse.json
285
+ ```
286
+
273
287
  Then start the TUI from anywhere:
274
288
 
275
289
  ```bash
@@ -37,6 +37,20 @@ One command, no clone required:
37
37
  uv tool install synapse-cli-agent
38
38
  ```
39
39
 
40
+ Windows users can also install via Scoop (single-file executable, auto-updated
41
+ through `checkver`): add the bucket, then install:
42
+
43
+ ```powershell
44
+ scoop bucket add synapse https://github.com/alex8224/synapse-agent
45
+ scoop install synapse
46
+ ```
47
+
48
+ Or install directly from the manifest URL:
49
+
50
+ ```powershell
51
+ scoop install https://raw.githubusercontent.com/alex8224/synapse-agent/main/bucket/synapse.json
52
+ ```
53
+
40
54
  Then start the TUI from anywhere:
41
55
 
42
56
  ```bash
@@ -0,0 +1,21 @@
1
+ {
2
+ "version": "0.1.42",
3
+ "description": "Local coding agent built on LangChain Deep Agents (LocalShell, no sandbox)",
4
+ "homepage": "https://github.com/alex8224/synapse-agent",
5
+ "license": "Apache-2.0",
6
+ "url": "https://github.com/alex8224/synapse-agent/releases/download/v0.1.42/synapse-windows-x64.exe",
7
+ "hash": "4a912ce91a11d87bfdada45257579689fe502840e09c5eb39424e63b5c21ec40",
8
+ "bin": [
9
+ ["synapse-windows-x64.exe", "synapse"]
10
+ ],
11
+ "checkver": {
12
+ "github": "https://github.com/alex8224/synapse-agent"
13
+ },
14
+ "autoupdate": {
15
+ "url": "https://github.com/alex8224/synapse-agent/releases/download/v$version/synapse-windows-x64.exe",
16
+ "hash": {
17
+ "url": "https://github.com/alex8224/synapse-agent/releases/download/v$version/synapse-windows-x64.exe.sha256",
18
+ "mode": "extract"
19
+ }
20
+ }
21
+ }
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "synapse-cli-agent"
3
- version = "0.1.41"
3
+ version = "0.1.43"
4
4
  description = "Local coding agent built on LangChain Deep Agents (LocalShell, no sandbox)"
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -0,0 +1,12 @@
1
+ ## v0.1.43
2
+
3
+ ### New Features
4
+
5
+ - Added Scoop distribution support: a new `bucket/synapse.json` manifest (with `checkver`/`autoupdate`) and a single-file Windows executable let Windows users install and auto-update Synapse via Scoop (`scoop install synapse`).
6
+
7
+ ### Engineering
8
+
9
+ - The release workflow now publishes a SHA-256 checksum (`<bin>.sha256`) alongside each platform executable, so Scoop's `autoupdate` can verify downloads without manual hash maintenance.
10
+ - Documented Scoop installation in the README.
11
+
12
+ ---
@@ -1052,37 +1052,56 @@ class RustOpenAIChatModel(BaseChatModel):
1052
1052
  req = self._build_request(messages, tools=tools, stop=stop, streaming=True, **kwargs)
1053
1053
  response_state: dict[str, Any] = {}
1054
1054
  if self.use_responses_api and self.use_websocket:
1055
- from synapse.integrations.llm_openai_websocket import (
1056
- prepare_responses_websocket_event,
1057
- )
1055
+ from synapse.integrations.llm_openai_websocket import prepare_responses_websocket_event
1056
+ from synapse.runtime.middleware import should_retry_transient_model_error
1058
1057
 
1059
1058
  event = prepare_responses_websocket_event(req)
1060
- ws: Any | None = None
1061
- try:
1062
- ws = self._ensure_websocket()
1063
- stream = ws.request(json.dumps(event, default=str))
1064
- for raw in stream:
1065
- payload = json.loads(raw)
1066
- chunk_msg = aimessage_chunk_from_responses_event(payload, response_state)
1067
- if chunk_msg is None:
1068
- continue
1069
- gen = ChatGenerationChunk(message=chunk_msg)
1070
- if run_manager:
1071
- text = chunk_msg.content if isinstance(chunk_msg.content, str) else ""
1072
- if text:
1073
- run_manager.on_llm_new_token(text, chunk=gen)
1074
- yield gen
1075
- except Exception:
1076
- # A socket error (or consumer cancellation) leaves the connection
1077
- # unusable; drop it so the next request opens a fresh one.
1078
- self._reset_websocket()
1079
- raise
1080
- except BaseException:
1081
- # GeneratorExit is raised when a synchronous consumer closes the
1082
- # iterator early. The native producer then closes its socket, so
1083
- # do not leave the now-invalid handle cached on this model.
1084
- self._reset_websocket()
1085
- raise
1059
+ # A long-lived WebSocket connection sits idle in the cache while the
1060
+ # peer or an intermediate idle-timeout recycles the socket, so the
1061
+ # next ``send_raw`` can fail with a connection-aborted IO error
1062
+ # (Windows 10053) without any warning. Retry once on a fresh
1063
+ # connection, but only before any chunk has been emitted — replaying
1064
+ # after output would duplicate tokens.
1065
+ websocket_replay_attempts = 1
1066
+ for attempt in range(websocket_replay_attempts + 1):
1067
+ response_state = {}
1068
+ yielded_chunk = False
1069
+ try:
1070
+ ws = self._ensure_websocket()
1071
+ stream = ws.request(json.dumps(event, default=str))
1072
+ for raw in stream:
1073
+ payload = json.loads(raw)
1074
+ chunk_msg = aimessage_chunk_from_responses_event(payload, response_state)
1075
+ if chunk_msg is None:
1076
+ continue
1077
+ gen = ChatGenerationChunk(message=chunk_msg)
1078
+ yielded_chunk = True
1079
+ if run_manager:
1080
+ text = chunk_msg.content if isinstance(chunk_msg.content, str) else ""
1081
+ if text:
1082
+ run_manager.on_llm_new_token(text, chunk=gen)
1083
+ yield gen
1084
+ return
1085
+ except Exception as exc:
1086
+ # A socket error (or consumer cancellation) leaves the
1087
+ # connection unusable; drop it so the next attempt opens a
1088
+ # fresh one.
1089
+ self._reset_websocket()
1090
+ if (
1091
+ yielded_chunk
1092
+ or attempt >= websocket_replay_attempts
1093
+ or not should_retry_transient_model_error(exc)
1094
+ ):
1095
+ raise
1096
+ # Connection failed before any output; reconnect and retry.
1097
+ continue
1098
+ except BaseException:
1099
+ # GeneratorExit is raised when a synchronous consumer closes
1100
+ # the iterator early. The native producer then closes its
1101
+ # socket, so do not leave the now-invalid handle cached on
1102
+ # this model.
1103
+ self._reset_websocket()
1104
+ raise
1086
1105
  return
1087
1106
  client = self._ensure_client()
1088
1107
  if self.use_responses_api:
@@ -39,6 +39,18 @@ _TRANSIENT_MODEL_ERROR_MARKERS = (
39
39
  "upstream request timeout",
40
40
  "rate limit",
41
41
  "rate_limit",
42
+ # Connection-level failures (TCP reset / aborted / timed-out sockets and
43
+ # the native WebSocket transport) are transient: the underlying peer or an
44
+ # intermediate idle-timeout recycles the socket, but a fresh connection
45
+ # usually succeeds. Match these so the model retry middleware recovers the
46
+ # call instead of surfacing a one-shot "websocket send failed" to the user.
47
+ "connection reset",
48
+ "connection aborted",
49
+ "connection closed",
50
+ "software caused connection abort",
51
+ "websocket send failed",
52
+ "websocket recv failed",
53
+ "websocket connection is closed",
42
54
  )
43
55
 
44
56
  # ---------------------------------------------------------------------------
@@ -668,11 +680,15 @@ def current_prompt_cleanup_saved_tokens() -> int:
668
680
  # Text block prefixes injected by deepagents middleware. Each block
669
681
  # duplicates content already present in the corresponding tool definition
670
682
  # (e.g. ``write_todos`` description, filesystem tool docs). Stripping them
671
- # saves ~720 tokens per model call without losing any capability.
683
+ # saves tokens per model call without losing any capability.
684
+ #
685
+ # ``## Skills System`` is intentionally NOT stripped: it is the skill index
686
+ # (name + description + path) that lets the model auto-discover and trigger
687
+ # local skills. Without it, skills are not auto-discoverable from the prompt
688
+ # and must be surfaced via the /skills command or a human pointer.
672
689
 
673
690
  _REDUNDANT_BLOCK_PREFIXES: tuple[str, ...] = (
674
691
  "\n\n## `write_todos`",
675
- "\n\n## Skills System",
676
692
  "\n\n## Following Conventions",
677
693
  )
678
694
 
@@ -11,6 +11,7 @@ from rich import box
11
11
  from rich.console import Console, ConsoleOptions, RenderResult
12
12
  from rich.markdown import BlockQuote as _BlockQuote
13
13
  from rich.markdown import CodeBlock as _CodeBlock
14
+ from rich.markdown import ImageItem as _RichImageItem
14
15
  from rich.markdown import Markdown as _Markdown
15
16
  from rich.markdown import MarkdownElement
16
17
  from rich.markdown import TableElement as _TableElement
@@ -633,11 +634,77 @@ class _QuoteLineBlockQuote(_BlockQuote):
633
634
  yield new_line
634
635
 
635
636
 
637
+ _IMAGE_MAX_COLS = 100
638
+ _IMAGE_MAX_ROWS = 30
639
+
640
+
641
+ def _render_image_path(destination: str) -> Any | None:
642
+ """Best-effort terminal pixel renderable for a local image path.
643
+
644
+ Mirrors ``_render_mermaid_image``: decode the image with Pillow and wrap it
645
+ in the active ``textual_image`` protocol renderer (sixel / TGP / half-cell /
646
+ unicode). Returns ``None`` when the path is not a readable local image or no
647
+ renderer is available so callers can fall back to the Rich ``[image]``
648
+ placeholder. HTTP(S) URLs are not resolved here and fall through.
649
+ """
650
+ if not destination or destination.startswith(("http://", "https://")):
651
+ return None
652
+ try:
653
+ from PIL import Image as PILImage
654
+
655
+ from synapse.ui.image_render import (
656
+ _resolve_renderer,
657
+ fit_cell_size,
658
+ renderer_needs_extra_row,
659
+ )
660
+ from synapse.ui.workspace import resolve_workspace_path
661
+
662
+ renderer_cls = _resolve_renderer()
663
+ if renderer_cls is None:
664
+ return None
665
+ path = resolve_workspace_path(destination)
666
+ if path is None:
667
+ return None
668
+ image = PILImage.open(path)
669
+ image.load()
670
+ width, height = image.size
671
+ cols, rows = fit_cell_size(
672
+ width,
673
+ height,
674
+ max_cols=_IMAGE_MAX_COLS,
675
+ max_rows=_IMAGE_MAX_ROWS,
676
+ extra_rows=1 if renderer_needs_extra_row() else 0,
677
+ )
678
+ return renderer_cls(image, width=cols, height=rows)
679
+ except Exception: # noqa: BLE001 - any image-path failure falls back to placeholder
680
+ return None
681
+
682
+
683
+ class _ImageItem(_RichImageItem):
684
+ """Markdown image element that renders local images via the pixel pipeline.
685
+
686
+ Overrides Rich's ``ImageItem`` placeholder so ``![alt](path)`` resolves a
687
+ readable local image through ``_render_image_path`` (the same Pillow +
688
+ ``textual_image`` pipeline used for mermaid / math). Any failure falls back
689
+ to the original Rich ``[image]`` placeholder.
690
+ """
691
+
692
+ def __rich_console__(
693
+ self, console: Console, options: ConsoleOptions
694
+ ) -> RenderResult:
695
+ image = _render_image_path(self.destination)
696
+ if image is not None:
697
+ yield image
698
+ return
699
+ yield from super().__rich_console__(console, options)
700
+
701
+
636
702
  class _FullBorderMarkdown(_Markdown):
637
703
  """Rich Markdown with full table borders and mermaid diagram fences."""
638
704
 
639
705
  elements: ClassVar[dict[str, type[MarkdownElement]]] = {
640
706
  **_Markdown.elements,
707
+ "image": _ImageItem,
641
708
  "table_open": _FullTableElement,
642
709
  "fence": _MermaidCodeBlock,
643
710
  "code_block": _MermaidCodeBlock,
@@ -10,6 +10,7 @@ import time
10
10
  from typing import Any
11
11
 
12
12
  from rich.text import Text
13
+ from textual.css.query import NoMatches
13
14
  from textual.widgets import Input, Static
14
15
 
15
16
  import synapse.ui.tui_styles as _styles
@@ -45,7 +46,13 @@ class StatusController:
45
46
  self._phase = phase or "idle"
46
47
  self._detail = detail
47
48
  busy = self._phase not in {"idle", "ready", ""}
48
- app.query_one("#status", Static).set_class(busy, "busy")
49
+ try:
50
+ app.query_one("#status", Static).set_class(busy, "busy")
51
+ except NoMatches:
52
+ # A timer/worker callback can race with screen teardown. Keep the
53
+ # controller state, but do not turn an already-unmounted UI into
54
+ # an application error.
55
+ return
49
56
  if busy:
50
57
  app.sub_title = f"{model_status_label(app.settings)} · {self._phase}"
51
58
  else:
@@ -158,7 +165,12 @@ class StatusController:
158
165
  app = self._app
159
166
  elapsed = max(0.0, time.monotonic() - self._activity_started)
160
167
  busy = self._phase not in {"idle", "ready", ""}
161
- status = app.query_one("#status", Static)
168
+ try:
169
+ status = app.query_one("#status", Static)
170
+ except NoMatches:
171
+ # Textual removes the screen tree before all interval callbacks
172
+ # have necessarily drained during shutdown.
173
+ return
162
174
  width = max(int(getattr(app.size, "width", 0) or 0), 48)
163
175
  # Account for CSS padding (0 2).
164
176
  usable = max(16, width - 4)
@@ -228,4 +240,4 @@ class StatusController:
228
240
  except Exception: # noqa: BLE001
229
241
  pass
230
242
  self.render_status()
231
- self.sync_prompt_placeholder()
243
+ self.sync_prompt_placeholder()
@@ -13,6 +13,7 @@ from typing import Any
13
13
 
14
14
  from rich.text import Text
15
15
  from textual.containers import Vertical, VerticalScroll
16
+ from textual.css.query import NoMatches
16
17
  from textual.events import MouseUp
17
18
  from textual.widgets import Static
18
19
 
@@ -188,7 +189,13 @@ class TranscriptController:
188
189
  def _mount_block(self, block: Any, *, dismiss_welcome: bool = True) -> None:
189
190
  if dismiss_welcome:
190
191
  self._dismiss_welcome()
191
- timeline = self._app.query_one("#log", VerticalScroll)
192
+ try:
193
+ timeline = self._app.query_one("#log", VerticalScroll)
194
+ except NoMatches:
195
+ # Background callbacks may arrive after Textual has torn down the
196
+ # screen tree. The event is no longer renderable, so discard only
197
+ # the UI write instead of surfacing a shutdown error.
198
+ return
192
199
  follow = timeline.max_scroll_y <= 0 or timeline.scroll_y >= timeline.max_scroll_y - 1
193
200
  timeline.mount(block)
194
201
  self.state.current_turn_blocks.append(block)
@@ -716,4 +723,4 @@ class TranscriptController:
716
723
  st.last_answer_text = ""
717
724
  st.last_thought_body = ""
718
725
  st.last_thought_elapsed = 0.0
719
- st.thought_expanded = False
726
+ st.thought_expanded = False
@@ -2,6 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import io
6
+ import re
5
7
  import threading
6
8
  import time
7
9
  from collections.abc import Callable
@@ -47,6 +49,59 @@ _markdown_render_executor = ThreadPoolExecutor(
47
49
  )
48
50
 
49
51
 
52
+ _IMAGE_RENDER_WORKERS = 2
53
+ _image_render_executor = ThreadPoolExecutor(
54
+ max_workers=_IMAGE_RENDER_WORKERS,
55
+ thread_name_prefix="synapse-image",
56
+ )
57
+ _IMAGE_MAX_COLS = 100
58
+ _IMAGE_MAX_ROWS = 30
59
+
60
+ _MD_IMAGE_RE = re.compile(r"!\[[^\]]*\]\(([^)]*)\)")
61
+
62
+
63
+ def _image_src(destination: str) -> str:
64
+ """Extract the image path from an ``![alt](src "title")`` render target."""
65
+ stripped = destination.strip()
66
+ return stripped.split()[0] if stripped else ""
67
+
68
+
69
+ def split_markdown_images(text: str) -> list[tuple[str, str]]:
70
+ """Split Markdown into ``(kind, content)`` runs.
71
+
72
+ ``image`` runs carry the raw image source from ``![alt](path)``; ``markdown``
73
+ runs are plain text kept verbatim for the Rich renderer. Used by answer
74
+ blocks so attached images render through the terminal pixel pipeline.
75
+ """
76
+ if not text:
77
+ return [("markdown", "")]
78
+ parts: list[tuple[str, str]] = []
79
+ cursor = 0
80
+ for match in _MD_IMAGE_RE.finditer(text):
81
+ if match.start() > cursor:
82
+ parts.append(("markdown", text[cursor : match.start()]))
83
+ src = _image_src(match.group(1))
84
+ if src:
85
+ parts.append(("image", src))
86
+ cursor = match.end()
87
+ if cursor < len(text):
88
+ parts.append(("markdown", text[cursor:]))
89
+ return parts or [("markdown", text)]
90
+
91
+
92
+ def _read_image_bytes(source: str) -> bytes | None:
93
+ """Read a local image file in a background worker; ``None`` on failure."""
94
+ from synapse.ui.workspace import resolve_workspace_path
95
+
96
+ path = resolve_workspace_path(source)
97
+ if path is None:
98
+ return None
99
+ try:
100
+ return path.read_bytes()
101
+ except Exception: # noqa: BLE001 - unreadable image falls back to placeholder
102
+ return None
103
+
104
+
50
105
  def _render_mermaid_png(source: str) -> bytes | None:
51
106
  """Run only native Mermaid PNG rendering in a background worker."""
52
107
  from synapse.ui.rendering import render_mermaid_png
@@ -291,6 +346,7 @@ class AnswerBlock(SelectableStatic):
291
346
  self._markdown_max_chars = max(1, int(markdown_max_chars))
292
347
  self._mermaid_render_generation = 0
293
348
  self._markdown_render_generation = 0
349
+ self._image_render_generation = 0
294
350
  # Historical restore defers long-body markdown parsing to a worker so
295
351
  # first paint stays cheap: show plain text, then swap in the renderable.
296
352
  self._defer_markdown = bool(defer_markdown)
@@ -351,6 +407,9 @@ class AnswerBlock(SelectableStatic):
351
407
  if any(sub.kind == "math" for sub in split_block_math(segment.source)):
352
408
  has_enriched = True
353
409
  break
410
+ if _MD_IMAGE_RE.search(segment.source):
411
+ has_enriched = True
412
+ break
354
413
  if not has_enriched:
355
414
  return []
356
415
 
@@ -370,8 +429,12 @@ class AnswerBlock(SelectableStatic):
370
429
  if sub.kind == "math":
371
430
  widget = make_math_widget(sub.source, color=fg)
372
431
  widgets.append(widget or MathFallbackBlock(sub.source))
373
- elif sub.source.strip():
374
- widgets.append(Static(render_markdown(sub.source)))
432
+ continue
433
+ for kind, content in split_markdown_images(sub.source):
434
+ if kind == "image" and content:
435
+ widgets.append(_ImageRenderPlaceholder(content))
436
+ elif content.strip():
437
+ widgets.append(Static(render_markdown(content)))
375
438
  return widgets
376
439
  except Exception: # noqa: BLE001 - composite rendering is optional
377
440
  return []
@@ -384,11 +447,13 @@ class AnswerBlock(SelectableStatic):
384
447
  if widgets:
385
448
  self.mount(*widgets)
386
449
  self.call_after_refresh(self._start_mermaid_renders)
450
+ self.call_after_refresh(self._start_image_renders)
387
451
  except Exception: # noqa: BLE001 - widget may be detaching during session switch
388
452
  pass
389
453
 
390
454
  def on_mount(self) -> None:
391
455
  self.call_after_refresh(self._start_mermaid_renders)
456
+ self.call_after_refresh(self._start_image_renders)
392
457
  if self._pending_markdown:
393
458
  self._pending_markdown = False
394
459
  self._schedule_markdown_render(self.body)
@@ -461,8 +526,84 @@ class AnswerBlock(SelectableStatic):
461
526
  except Exception: # noqa: BLE001 - transcript may detach during session switch
462
527
  pass
463
528
 
529
+ def _start_image_renders(self) -> None:
530
+ """Submit unrendered image placeholders without blocking Textual's loop."""
531
+ if not self.is_attached:
532
+ return
533
+ generation = self._image_render_generation
534
+ for placeholder in self.query(_ImageRenderPlaceholder):
535
+ if placeholder.render_started:
536
+ continue
537
+ placeholder.render_started = True
538
+ future = _image_render_executor.submit(
539
+ _read_image_bytes, placeholder.source
540
+ )
541
+ future.add_done_callback(
542
+ lambda completed, target=placeholder, expected=generation: (
543
+ self._deliver_image(completed, target, expected)
544
+ )
545
+ )
546
+
547
+ def _deliver_image(
548
+ self,
549
+ future: Future[bytes | None],
550
+ placeholder: _ImageRenderPlaceholder,
551
+ generation: int,
552
+ ) -> None:
553
+ """Schedule a completed background image load back onto the UI thread."""
554
+ try:
555
+ data = future.result()
556
+ except Exception: # noqa: BLE001 - app/widget may be shutting down
557
+ return
558
+ try:
559
+ _schedule_on_app_thread(
560
+ self.app,
561
+ self._replace_image_placeholder,
562
+ placeholder,
563
+ data,
564
+ generation,
565
+ )
566
+ except Exception: # noqa: BLE001 - app/widget may be shutting down
567
+ pass
568
+
569
+ def _replace_image_placeholder(
570
+ self,
571
+ placeholder: _ImageRenderPlaceholder,
572
+ data: bytes | None,
573
+ generation: int,
574
+ ) -> None:
575
+ """Replace a still-current image placeholder once its file is loaded."""
576
+ if (
577
+ generation != self._image_render_generation
578
+ or not self.is_attached
579
+ or not placeholder.is_attached
580
+ ):
581
+ return
582
+ widget = None
583
+ if data:
584
+ try:
585
+ from PIL import Image as PILImage
586
+
587
+ from synapse.ui.image_render import make_pil_image_widget
588
+
589
+ img = PILImage.open(io.BytesIO(data))
590
+ img.load()
591
+ widget = make_pil_image_widget(
592
+ img, max_cols=_IMAGE_MAX_COLS, max_rows=_IMAGE_MAX_ROWS
593
+ )
594
+ except Exception: # noqa: BLE001 - corrupt image falls back to placeholder
595
+ widget = None
596
+ if widget is None:
597
+ widget = Static(Text(f"[image: {placeholder.source}]", style="dim italic"))
598
+ try:
599
+ self.mount(widget, before=placeholder)
600
+ placeholder.remove()
601
+ except Exception: # noqa: BLE001 - transcript may detach during session switch
602
+ pass
603
+
464
604
  def _render_block(self) -> None:
465
605
  self._mermaid_render_generation += 1
606
+ self._image_render_generation += 1
466
607
  body = self.body or ""
467
608
  fg = _resolve_color(self._fg_color, _DEFAULT_FG, "fg")
468
609
  if self.live:
@@ -560,6 +701,15 @@ class _MermaidRenderPlaceholder(Static):
560
701
  super().__init__(Text("Rendering Mermaid diagram...", style="dim italic"))
561
702
 
562
703
 
704
+ class _ImageRenderPlaceholder(Static):
705
+ """Lightweight UI-thread placeholder while a local image loads on a worker."""
706
+
707
+ def __init__(self, source: str) -> None:
708
+ self.source = source
709
+ self.render_started = False
710
+ super().__init__(Text("Loading image...", style="dim italic"))
711
+
712
+
563
713
  class _MarkdownBlock(Static):
564
714
  """A Markdown transcript block that can rebuild after a theme switch."""
565
715
 
@@ -1490,6 +1490,9 @@ class CodingAgentApp(App[None]):
1490
1490
  # Swap the app's project context.
1491
1491
  self.settings = project_settings
1492
1492
  self.project_root = workspace
1493
+ from synapse.ui.workspace import set_current_workspace
1494
+
1495
+ set_current_workspace(workspace)
1493
1496
  self.thread_id = target_thread
1494
1497
  if turn is not None:
1495
1498
  try:
@@ -24,6 +24,9 @@ def run_tui(
24
24
  # ``run_tui`` re-export, so CodingAgentApp must resolve lazily.
25
25
  from synapse.observability.startup_trace import global_mark, span
26
26
  from synapse.ui.tui import CodingAgentApp
27
+ from synapse.ui.workspace import set_current_workspace
28
+
29
+ set_current_workspace(settings.workspace)
27
30
 
28
31
  try:
29
32
  from synapse.ui.theme import bootstrap_theme