meridian-cli 0.3.28__tar.gz → 0.3.30__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 (558) hide show
  1. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/PKG-INFO +2 -2
  2. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/pyproject.toml +1 -1
  3. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/__init__.py +1 -1
  4. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/codex.py +2 -1
  5. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/connections/codex_ws.py +51 -16
  6. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/connections/managed_backend.py +5 -1
  7. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/connections/opencode_http.py +2 -1
  8. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/launch_types.py +1 -1
  9. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/process/.context/CONTEXT.md +9 -0
  10. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/process/ports.py +24 -13
  11. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/process/primary_attach.py +115 -22
  12. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/process/pty_launcher.py +41 -24
  13. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/process/runner.py +9 -2
  14. meridian_cli-0.3.30/src/meridian/lib/launch/process/subprocess_launcher.py +253 -0
  15. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/process/windows_launcher.py +4 -6
  16. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/.context/CONTEXT.md +8 -1
  17. meridian_cli-0.3.30/src/meridian/lib/platform/detached_process.py +263 -0
  18. meridian_cli-0.3.30/src/meridian/lib/platform/parent_watchdog.py +154 -0
  19. meridian_cli-0.3.28/src/meridian/lib/launch/process/subprocess_launcher.py +0 -161
  20. meridian_cli-0.3.28/src/meridian/lib/platform/detached_process.py +0 -132
  21. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/.gitignore +0 -0
  22. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/LICENSE +0 -0
  23. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/README.md +0 -0
  24. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/ag_ui/__init__.pyi +0 -0
  25. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/ag_ui/core.pyi +0 -0
  26. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/AGENTS.md +0 -0
  27. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/CLAUDE.md +0 -0
  28. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/__main__.py +0 -0
  29. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/.context/CONTEXT.md +0 -0
  30. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/AGENTS.md +0 -0
  31. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/CLAUDE.md +0 -0
  32. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/__init__.py +0 -0
  33. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/_cmd_utils.py +0 -0
  34. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/agent_help.py +0 -0
  35. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/app_tree.py +0 -0
  36. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/argv_normalization.py +0 -0
  37. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/bootstrap.py +0 -0
  38. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/bootstrap_cmd.py +0 -0
  39. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/command_groups.py +0 -0
  40. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/config_cmd.py +0 -0
  41. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/doctor_cmd.py +0 -0
  42. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/entrypoint.py +0 -0
  43. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/ext_cmd.py +0 -0
  44. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/ext_registration.py +0 -0
  45. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/help_content.py +0 -0
  46. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/help_tiers.py +0 -0
  47. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/hooks_authority.py +0 -0
  48. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/hooks_commands.py +0 -0
  49. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/kg_cmd.py +0 -0
  50. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/main.py +0 -0
  51. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/mars_passthrough.py +0 -0
  52. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/mermaid_cmd.py +0 -0
  53. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/migrate_cmd.py +0 -0
  54. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/misc_commands.py +0 -0
  55. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/mode.py +0 -0
  56. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/models_cmd.py +0 -0
  57. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/output.py +0 -0
  58. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/primary_launch.py +0 -0
  59. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/qi_cmd.py +0 -0
  60. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/report_cmd.py +0 -0
  61. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/session_cmd.py +0 -0
  62. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/spawn.py +0 -0
  63. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/spawn_inject.py +0 -0
  64. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/startup/__init__.py +0 -0
  65. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/startup/catalog.py +0 -0
  66. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/startup/classify.py +0 -0
  67. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/startup/cyclopts_app.py +0 -0
  68. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/startup/help.py +0 -0
  69. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/startup/lazy_dispatch.py +0 -0
  70. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/startup/policy.py +0 -0
  71. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/streaming_serve.py +0 -0
  72. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/sync_cmd.py +0 -0
  73. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/task_dir_cmd.py +0 -0
  74. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/telemetry_cmd.py +0 -0
  75. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/utils.py +0 -0
  76. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/work_cmd.py +0 -0
  77. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/cli/workspace_cmd.py +0 -0
  78. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/dev/AGENTS.md +0 -0
  79. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/dev/CLAUDE.md +0 -0
  80. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/dev/__init__.py +0 -0
  81. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/dev/pytests.py +0 -0
  82. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/__init__.py +0 -0
  83. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/bootstrap/.context/CONTEXT.md +0 -0
  84. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/bootstrap/AGENTS.md +0 -0
  85. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/bootstrap/CLAUDE.md +0 -0
  86. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/bootstrap/__init__.py +0 -0
  87. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/bootstrap/config.py +0 -0
  88. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/bootstrap/project_state.py +0 -0
  89. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/bootstrap/runtime_state.py +0 -0
  90. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/bootstrap/services.py +0 -0
  91. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/catalog/.context/CONTEXT.md +0 -0
  92. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/catalog/AGENTS.md +0 -0
  93. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/catalog/CLAUDE.md +0 -0
  94. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/catalog/__init__.py +0 -0
  95. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/catalog/agent.py +0 -0
  96. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/catalog/bootstrap.py +0 -0
  97. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/catalog/catalog_session.py +0 -0
  98. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/catalog/model_aliases.py +0 -0
  99. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/catalog/models.py +0 -0
  100. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/catalog/skill.py +0 -0
  101. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/config/.context/CONTEXT.md +0 -0
  102. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/config/AGENTS.md +0 -0
  103. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/config/CLAUDE.md +0 -0
  104. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/config/__init__.py +0 -0
  105. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/config/catalog.py +0 -0
  106. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/config/context_config.py +0 -0
  107. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/config/preserving_edit.py +0 -0
  108. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/config/project_config_state.py +0 -0
  109. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/config/project_paths.py +0 -0
  110. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/config/project_root.py +0 -0
  111. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/config/schema.py +0 -0
  112. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/config/settings.py +0 -0
  113. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/config/workspace.py +0 -0
  114. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/context/.context/CONTEXT.md +0 -0
  115. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/context/AGENTS.md +0 -0
  116. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/context/CLAUDE.md +0 -0
  117. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/context/__init__.py +0 -0
  118. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/context/resolver.py +0 -0
  119. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/.context/CONTEXT.md +0 -0
  120. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/AGENTS.md +0 -0
  121. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/CLAUDE.md +0 -0
  122. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/__init__.py +0 -0
  123. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/child_env.py +0 -0
  124. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/clock.py +0 -0
  125. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/codec.py +0 -0
  126. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/command_strings.py +0 -0
  127. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/context.py +0 -0
  128. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/conversation.py +0 -0
  129. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/depth.py +0 -0
  130. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/domain.py +0 -0
  131. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/execution_policy.py +0 -0
  132. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/formatting.py +0 -0
  133. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/launch_policy_snapshot.py +0 -0
  134. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/lifecycle.py +0 -0
  135. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/logging.py +0 -0
  136. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/overrides.py +0 -0
  137. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/process_cleanup.py +0 -0
  138. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/resolved_context.py +0 -0
  139. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/sink.py +0 -0
  140. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/spawn_lifecycle.py +0 -0
  141. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/spawn_service.py +0 -0
  142. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/spawn_start.py +0 -0
  143. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/telemetry.py +0 -0
  144. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/types.py +0 -0
  145. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/core/util.py +0 -0
  146. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/diagnostics.py +0 -0
  147. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/.context/CONTEXT.md +0 -0
  148. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/AGENTS.md +0 -0
  149. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/CLAUDE.md +0 -0
  150. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/__init__.py +0 -0
  151. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/commands/.context/CONTEXT.md +0 -0
  152. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/commands/AGENTS.md +0 -0
  153. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/commands/CLAUDE.md +0 -0
  154. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/commands/__init__.py +0 -0
  155. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/commands/biomed.py +0 -0
  156. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/commands/mermaid.py +0 -0
  157. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/commands/sessions.py +0 -0
  158. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/commands/workbench.py +0 -0
  159. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/context.py +0 -0
  160. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/descriptors.py +0 -0
  161. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/dispatcher.py +0 -0
  162. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/first_party.py +0 -0
  163. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/observability.py +0 -0
  164. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/registry.py +0 -0
  165. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/extensions/types.py +0 -0
  166. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/.context/CONTEXT.md +0 -0
  167. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/AGENTS.md +0 -0
  168. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/CLAUDE.md +0 -0
  169. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/__init__.py +0 -0
  170. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/adapter.py +0 -0
  171. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/bundle.py +0 -0
  172. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/claude.py +0 -0
  173. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/claude_preflight.py +0 -0
  174. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/claude_sessions.py +0 -0
  175. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/claude_utils.py +0 -0
  176. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/codex_rollout.py +0 -0
  177. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/common.py +0 -0
  178. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/connections/.context/CONTEXT.md +0 -0
  179. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/connections/AGENTS.md +0 -0
  180. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/connections/CLAUDE.md +0 -0
  181. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/connections/__init__.py +0 -0
  182. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/connections/base.py +0 -0
  183. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/connections/claude_ws.py +0 -0
  184. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/connections/cursor_subprocess.py +0 -0
  185. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/connections/errors.py +0 -0
  186. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/connections/liveness.py +0 -0
  187. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/connections/pi_rpc.py +0 -0
  188. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/connections/resident_backend.py +0 -0
  189. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/control_action.py +0 -0
  190. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/cost.py +0 -0
  191. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/cursor.py +0 -0
  192. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/errors.py +0 -0
  193. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/extractor.py +0 -0
  194. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/extractors/.context/CONTEXT.md +0 -0
  195. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/extractors/AGENTS.md +0 -0
  196. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/extractors/CLAUDE.md +0 -0
  197. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/extractors/__init__.py +0 -0
  198. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/extractors/base.py +0 -0
  199. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/extractors/claude.py +0 -0
  200. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/extractors/codex.py +0 -0
  201. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/extractors/cursor.py +0 -0
  202. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/extractors/opencode.py +0 -0
  203. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/extractors/pi.py +0 -0
  204. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/launch_spec.py +0 -0
  205. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/launch_types.py +0 -0
  206. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/opencode.py +0 -0
  207. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/opencode_report.py +0 -0
  208. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/opencode_storage.py +0 -0
  209. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/opencode_transcript.py +0 -0
  210. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/passthrough/.context/CONTEXT.md +0 -0
  211. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/passthrough/AGENTS.md +0 -0
  212. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/passthrough/CLAUDE.md +0 -0
  213. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/passthrough/__init__.py +0 -0
  214. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/passthrough/base.py +0 -0
  215. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/passthrough/claude.py +0 -0
  216. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/passthrough/codex.py +0 -0
  217. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/passthrough/opencode.py +0 -0
  218. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/passthrough/registry.py +0 -0
  219. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/permission_broker.py +0 -0
  220. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/pi.py +0 -0
  221. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/pi_lifecycle_events.py +0 -0
  222. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/pi_paths.py +0 -0
  223. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/pi_runtime_resolver.py +0 -0
  224. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/.context/CONTEXT.md +0 -0
  225. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/AGENTS.md +0 -0
  226. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/CLAUDE.md +0 -0
  227. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/__init__.py +0 -0
  228. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/_guards.py +0 -0
  229. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/permission_flags.py +0 -0
  230. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/pi_extension_projection.py +0 -0
  231. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/project_claude.py +0 -0
  232. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/project_codex_common.py +0 -0
  233. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/project_codex_streaming.py +0 -0
  234. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/project_codex_subprocess.py +0 -0
  235. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/project_cursor.py +0 -0
  236. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/project_opencode_streaming.py +0 -0
  237. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/project_opencode_subprocess.py +0 -0
  238. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/project_pi_native_tui.py +0 -0
  239. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/project_pi_rpc.py +0 -0
  240. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/projections/projection_errors.py +0 -0
  241. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/registry.py +0 -0
  242. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/semantics.py +0 -0
  243. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/session_detection.py +0 -0
  244. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/harness/transcript.py +0 -0
  245. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/.context/CONTEXT.md +0 -0
  246. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/AGENTS.md +0 -0
  247. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/CLAUDE.md +0 -0
  248. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/__init__.py +0 -0
  249. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/builtin/.context/CONTEXT.md +0 -0
  250. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/builtin/AGENTS.md +0 -0
  251. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/builtin/CLAUDE.md +0 -0
  252. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/builtin/__init__.py +0 -0
  253. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/builtin/autosync_store.py +0 -0
  254. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/builtin/base.py +0 -0
  255. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/builtin/git_autosync.py +0 -0
  256. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/builtin_registry.py +0 -0
  257. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/config.py +0 -0
  258. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/dispatch.py +0 -0
  259. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/interval.py +0 -0
  260. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/registry.py +0 -0
  261. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/runner.py +0 -0
  262. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/hooks/types.py +0 -0
  263. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ignores.py +0 -0
  264. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/kg/.context/CONTEXT.md +0 -0
  265. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/kg/AGENTS.md +0 -0
  266. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/kg/CLAUDE.md +0 -0
  267. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/kg/__init__.py +0 -0
  268. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/kg/graph.py +0 -0
  269. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/kg/report.py +0 -0
  270. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/kg/serializer.py +0 -0
  271. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/kg/types.py +0 -0
  272. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/.context/CONTEXT.md +0 -0
  273. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/AGENTS.md +0 -0
  274. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/CLAUDE.md +0 -0
  275. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/__init__.py +0 -0
  276. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/artifact_io.py +0 -0
  277. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/bundle_adapter.py +0 -0
  278. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/claude_session_access.py +0 -0
  279. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/command.py +0 -0
  280. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/compiler.py +0 -0
  281. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/composition.py +0 -0
  282. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/composition_spawn.py +0 -0
  283. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/constants.py +0 -0
  284. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/context.py +0 -0
  285. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/continue_replay.py +0 -0
  286. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/cwd.py +0 -0
  287. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/env.py +0 -0
  288. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/errors.py +0 -0
  289. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/extract.py +0 -0
  290. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/fork.py +0 -0
  291. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/materialize.py +0 -0
  292. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/permissions.py +0 -0
  293. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/plan.py +0 -0
  294. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/policies.py +0 -0
  295. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/policy_snapshot.py +0 -0
  296. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/process/AGENTS.md +0 -0
  297. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/process/CLAUDE.md +0 -0
  298. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/process/__init__.py +0 -0
  299. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/process/session.py +0 -0
  300. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/prompt.py +0 -0
  301. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/prompt_context.py +0 -0
  302. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/reference.py +0 -0
  303. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/report.py +0 -0
  304. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/request.py +0 -0
  305. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/resolution.py +0 -0
  306. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/resolve.py +0 -0
  307. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/run_inputs.py +0 -0
  308. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/runner_helpers.py +0 -0
  309. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/session_scope.py +0 -0
  310. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/signals.py +0 -0
  311. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/spawn_guidance.py +0 -0
  312. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/streaming/.context/CONTEXT.md +0 -0
  313. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/streaming/AGENTS.md +0 -0
  314. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/streaming/CLAUDE.md +0 -0
  315. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/streaming/__init__.py +0 -0
  316. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/streaming/heartbeat.py +0 -0
  317. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/streaming/terminal_arbitrator.py +0 -0
  318. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/streaming_runner.py +0 -0
  319. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/text_utils.py +0 -0
  320. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/types.py +0 -0
  321. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/workspace.py +0 -0
  322. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/workspace_projection.py +0 -0
  323. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/launch/written_files.py +0 -0
  324. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/markdown/.context/CONTEXT.md +0 -0
  325. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/markdown/AGENTS.md +0 -0
  326. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/markdown/CLAUDE.md +0 -0
  327. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/markdown/__init__.py +0 -0
  328. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/markdown/extract.py +0 -0
  329. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/markdown/types.py +0 -0
  330. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/.context/CONTEXT.md +0 -0
  331. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/AGENTS.md +0 -0
  332. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/CLAUDE.md +0 -0
  333. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/__init__.py +0 -0
  334. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/report.py +0 -0
  335. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/scanner.py +0 -0
  336. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/serializer.py +0 -0
  337. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/style/.context/CONTEXT.md +0 -0
  338. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/style/AGENTS.md +0 -0
  339. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/style/CLAUDE.md +0 -0
  340. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/style/__init__.py +0 -0
  341. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/style/bare_end.py +0 -0
  342. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/style/fill_no_color.py +0 -0
  343. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/style/line_map.py +0 -0
  344. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/style/ox_edge.py +0 -0
  345. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/style/preprocess.py +0 -0
  346. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/style/suppression.py +0 -0
  347. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/style/types.py +0 -0
  348. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/mermaid/validator.py +0 -0
  349. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/observability/.context/CONTEXT.md +0 -0
  350. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/observability/AGENTS.md +0 -0
  351. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/observability/CLAUDE.md +0 -0
  352. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/observability/__init__.py +0 -0
  353. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/observability/debug_tracer.py +0 -0
  354. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/observability/trace_helpers.py +0 -0
  355. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/.context/CONTEXT.md +0 -0
  356. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/AGENTS.md +0 -0
  357. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/CLAUDE.md +0 -0
  358. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/__init__.py +0 -0
  359. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/catalog.py +0 -0
  360. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/commands.py +0 -0
  361. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/config.py +0 -0
  362. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/config_surface.py +0 -0
  363. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/context.py +0 -0
  364. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/diag.py +0 -0
  365. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/hooks.py +0 -0
  366. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/init_ops.py +0 -0
  367. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/mars.py +0 -0
  368. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/migration.py +0 -0
  369. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/pruning.py +0 -0
  370. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/qi.py +0 -0
  371. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/reference.py +0 -0
  372. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/reference_recovery.py +0 -0
  373. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/report.py +0 -0
  374. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/runtime.py +0 -0
  375. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/session_corpus.py +0 -0
  376. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/session_export.py +0 -0
  377. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/session_log.py +0 -0
  378. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/session_log_render.py +0 -0
  379. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/session_render.py +0 -0
  380. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/session_repair.py +0 -0
  381. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/session_repair_target.py +0 -0
  382. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/session_search.py +0 -0
  383. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/session_target.py +0 -0
  384. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/session_transcript.py +0 -0
  385. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/.context/CONTEXT.md +0 -0
  386. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/AGENTS.md +0 -0
  387. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/CLAUDE.md +0 -0
  388. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/__init__.py +0 -0
  389. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/api.py +0 -0
  390. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/context_ref.py +0 -0
  391. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/execute.py +0 -0
  392. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/execute_bg.py +0 -0
  393. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/execute_init.py +0 -0
  394. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/execute_runner.py +0 -0
  395. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/execute_session.py +0 -0
  396. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/failure_policy.py +0 -0
  397. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/models.py +0 -0
  398. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/pre_init.py +0 -0
  399. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/prepare.py +0 -0
  400. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/query.py +0 -0
  401. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/spawn/task_dir.py +0 -0
  402. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/sync_conflicts.py +0 -0
  403. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/work_attachment.py +0 -0
  404. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/work_dashboard.py +0 -0
  405. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/work_lifecycle.py +0 -0
  406. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/work_sessions.py +0 -0
  407. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/ops/workspace.py +0 -0
  408. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/AGENTS.md +0 -0
  409. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/CLAUDE.md +0 -0
  410. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/__init__.py +0 -0
  411. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/locking.py +0 -0
  412. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/process_scope/.context/CONTEXT.md +0 -0
  413. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/process_scope/AGENTS.md +0 -0
  414. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/process_scope/CLAUDE.md +0 -0
  415. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/process_scope/__init__.py +0 -0
  416. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/process_scope/base.py +0 -0
  417. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/process_scope/fallback.py +0 -0
  418. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/process_scope/posix.py +0 -0
  419. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/process_scope/windows_job.py +0 -0
  420. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/terminate.py +0 -0
  421. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/platform/unix_modules.py +0 -0
  422. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/safety/.context/CONTEXT.md +0 -0
  423. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/safety/AGENTS.md +0 -0
  424. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/safety/CLAUDE.md +0 -0
  425. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/safety/__init__.py +0 -0
  426. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/safety/budget.py +0 -0
  427. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/safety/guardrails.py +0 -0
  428. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/safety/permissions.py +0 -0
  429. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/safety/redaction.py +0 -0
  430. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/service_context.py +0 -0
  431. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/spawn/.context/CONTEXT.md +0 -0
  432. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/spawn/AGENTS.md +0 -0
  433. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/spawn/CLAUDE.md +0 -0
  434. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/spawn/__init__.py +0 -0
  435. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/spawn/archive.py +0 -0
  436. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/.context/CONTEXT.md +0 -0
  437. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/AGENTS.md +0 -0
  438. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/CLAUDE.md +0 -0
  439. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/__init__.py +0 -0
  440. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/artifact_store.py +0 -0
  441. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/atomic.py +0 -0
  442. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/event_store.py +0 -0
  443. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/history.py +0 -0
  444. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/launch_boundary.py +0 -0
  445. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/liveness.py +0 -0
  446. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/managed_primary.py +0 -0
  447. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/paths.py +0 -0
  448. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/primary_meta.py +0 -0
  449. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/process_scope_projection.py +0 -0
  450. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/reaper.py +0 -0
  451. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/runtime_root.py +0 -0
  452. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/session_identity.py +0 -0
  453. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/session_store.py +0 -0
  454. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/spawn/.context/CONTEXT.md +0 -0
  455. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/spawn/AGENTS.md +0 -0
  456. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/spawn/CLAUDE.md +0 -0
  457. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/spawn/__init__.py +0 -0
  458. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/spawn/model.py +0 -0
  459. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/spawn/repository.py +0 -0
  460. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/spawn/terminal_policy.py +0 -0
  461. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/spawn/transitions.py +0 -0
  462. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/spawn_report.py +0 -0
  463. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/spawn_scope.py +0 -0
  464. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/spawn_signals.py +0 -0
  465. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/spawn_store.py +0 -0
  466. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/spawn_tree.py +0 -0
  467. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/timestamps.py +0 -0
  468. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/user_paths.py +0 -0
  469. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/wordgen.py +0 -0
  470. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/wordlists.py +0 -0
  471. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/work_scope.py +0 -0
  472. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/state/work_store.py +0 -0
  473. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/.context/CONTEXT.md +0 -0
  474. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/AGENTS.md +0 -0
  475. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/CLAUDE.md +0 -0
  476. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/__init__.py +0 -0
  477. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/completion_nudge.py +0 -0
  478. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/control_socket.py +0 -0
  479. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/disk_watcher.py +0 -0
  480. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/drain_coordinator.py +0 -0
  481. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/drain_policy.py +0 -0
  482. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/drain_wait.py +0 -0
  483. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/event_observers.py +0 -0
  484. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/heartbeat.py +0 -0
  485. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/pi_drain.py +0 -0
  486. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/pi_process_cleanup.py +0 -0
  487. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/pi_quiescence.py +0 -0
  488. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/pi_subspawn_tracker.py +0 -0
  489. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/resident_drain.py +0 -0
  490. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/signal_canceller.py +0 -0
  491. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/spawn_dispatch.py +0 -0
  492. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/spawn_drain_loop.py +0 -0
  493. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/spawn_manager.py +0 -0
  494. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/spawn_session.py +0 -0
  495. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/streaming/types.py +0 -0
  496. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/__init__.py +0 -0
  497. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/bootstrap.py +0 -0
  498. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/correlation.py +0 -0
  499. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/events.py +0 -0
  500. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/init.py +0 -0
  501. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/local_jsonl.py +0 -0
  502. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/maintenance.py +0 -0
  503. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/observer.py +0 -0
  504. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/observers.py +0 -0
  505. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/query.py +0 -0
  506. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/reader.py +0 -0
  507. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/retention.py +0 -0
  508. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/router.py +0 -0
  509. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/sinks.py +0 -0
  510. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/telemetry/status.py +0 -0
  511. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/tools.py +0 -0
  512. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/utils/__init__.py +0 -0
  513. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/lib/utils/time.py +0 -0
  514. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/.context/CONTEXT.md +0 -0
  515. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/README.md +0 -0
  516. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/__init__.py +0 -0
  517. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/dist/extensions/managed-bash/index.js +0 -0
  518. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/dist/extensions/meridian-spawn-watch/index.js +0 -0
  519. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/managed-bash/bundle.smoke.test.ts +0 -0
  520. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/managed-bash/src/bash_log_store.ts +0 -0
  521. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/managed-bash/src/bash_runtime.test.ts +0 -0
  522. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/managed-bash/src/bash_runtime.ts +0 -0
  523. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/managed-bash/src/index.ts +0 -0
  524. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/meridian-spawn-watch/bundle.smoke.test.ts +0 -0
  525. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/meridian-spawn-watch/src/index.test.ts +0 -0
  526. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/meridian-spawn-watch/src/index.ts +0 -0
  527. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/shared/ids.ts +0 -0
  528. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/shared/json_file.ts +0 -0
  529. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/shared/log_overlay.ts +0 -0
  530. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/shared/meridian_cli.ts +0 -0
  531. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/shared/meridian_spawn.test.ts +0 -0
  532. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/shared/meridian_spawn.ts +0 -0
  533. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/shared/pi_harness_profile.ts +0 -0
  534. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/shared/pi_state_paths.ts +0 -0
  535. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/shared/schemas.ts +0 -0
  536. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/shared/selectable_panel.test.ts +0 -0
  537. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/shared/selectable_panel.ts +0 -0
  538. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/shared/spawn_origins.test.ts +0 -0
  539. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/shared/spawn_origins.ts +0 -0
  540. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/extensions/shared/ui.ts +0 -0
  541. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/package.json +0 -0
  542. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/pnpm-lock.yaml +0 -0
  543. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/pnpm-workspace.yaml +0 -0
  544. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/scripts/verify-extensions-loop.mjs +0 -0
  545. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/pi_runtime/vitest.config.ts +0 -0
  546. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/plugin_api/AGENTS.md +0 -0
  547. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/plugin_api/CLAUDE.md +0 -0
  548. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/plugin_api/__init__.py +0 -0
  549. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/plugin_api/config.py +0 -0
  550. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/plugin_api/fs.py +0 -0
  551. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/plugin_api/git.py +0 -0
  552. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/plugin_api/state.py +0 -0
  553. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/plugin_api/types.py +0 -0
  554. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/py.typed +0 -0
  555. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/server/AGENTS.md +0 -0
  556. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/server/CLAUDE.md +0 -0
  557. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/server/__init__.py +0 -0
  558. {meridian_cli-0.3.28 → meridian_cli-0.3.30}/src/meridian/server/main.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meridian-cli
3
- Version: 0.3.28
3
+ Version: 0.3.30
4
4
  Summary: Orchestrate CLI + MCP server for multi-model agent workflows
5
5
  Project-URL: Homepage, https://github.com/haowjy/meridian-cli
6
6
  Project-URL: Repository, https://github.com/haowjy/meridian-cli
@@ -24,7 +24,7 @@ Requires-Dist: coolname>=4.0.0
24
24
  Requires-Dist: cyclopts>=3.0
25
25
  Requires-Dist: fastapi>=0.115
26
26
  Requires-Dist: markdown-it-py>=4.0
27
- Requires-Dist: mars-agents==0.10.3
27
+ Requires-Dist: mars-agents==0.10.5
28
28
  Requires-Dist: mcp>=1.0
29
29
  Requires-Dist: pathspec>=1.1.0
30
30
  Requires-Dist: psutil>=7.2.2
@@ -24,7 +24,7 @@ dependencies = [
24
24
  "cyclopts>=3.0",
25
25
  "fastapi>=0.115",
26
26
  "markdown-it-py>=4.0",
27
- "mars-agents==0.10.3",
27
+ "mars-agents==0.10.5",
28
28
  "mcp>=1.0",
29
29
  "pathspec>=1.1.0",
30
30
  "psutil>=7.2.2",
@@ -2,4 +2,4 @@
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.3.28"
5
+ __version__ = "0.3.30"
@@ -271,6 +271,7 @@ class CodexAdapter(BaseHarnessAdapter[ResolvedLaunchSpec]):
271
271
  "mcp_tools",
272
272
  "projected_roots",
273
273
  "control_root",
274
+ "agent",
274
275
  "adhoc_agent_payload",
275
276
  "appended_system_prompt",
276
277
  "user_turn_content",
@@ -279,7 +280,6 @@ class CodexAdapter(BaseHarnessAdapter[ResolvedLaunchSpec]):
279
280
  _EXPLICITLY_IGNORED_FIELDS: ClassVar[frozenset[str]] = frozenset(
280
281
  {
281
282
  "skills",
282
- "agent",
283
283
  "context_from_payload",
284
284
  "reference_items",
285
285
  "task_cwd",
@@ -382,6 +382,7 @@ class CodexAdapter(BaseHarnessAdapter[ResolvedLaunchSpec]):
382
382
  interactive=run.interactive,
383
383
  mcp_tools=run.mcp_tools,
384
384
  projected_roots=run.projected_roots,
385
+ agent_name=run.agent,
385
386
  base_instructions=run.adhoc_agent_payload.strip() or None,
386
387
  developer_instructions=run.appended_system_prompt,
387
388
  user_turn_content=run.user_turn_content,
@@ -76,7 +76,7 @@ from meridian.lib.observability.trace_helpers import (
76
76
  trace_state_change,
77
77
  trace_wire_send,
78
78
  )
79
- from meridian.lib.platform.detached_process import ParentDeathLink
79
+ from meridian.lib.platform.detached_process import ParentDeathLink, release_parent_death_link
80
80
  from meridian.lib.platform.process_scope import (
81
81
  ProcessScopeSnapshot,
82
82
  ScopedProcessHandle,
@@ -240,6 +240,8 @@ class CodexConnection(HarnessConnection[ResolvedLaunchSpec]):
240
240
  self._current_turn_id: str | None = None
241
241
  self._thread_id: str | None = None
242
242
  self._main_turn_thread_id: str | None = None
243
+ self._last_completed_turn_id: str | None = None
244
+ self._turn_completed_event = asyncio.Event()
243
245
  self._tracer: DebugTracer | None = None
244
246
  self._cancel_requested = False
245
247
  self._signal_in_flight = False
@@ -361,6 +363,8 @@ class CodexConnection(HarnessConnection[ResolvedLaunchSpec]):
361
363
  self._current_turn_id = None
362
364
  self._thread_id = None
363
365
  self._main_turn_thread_id = None
366
+ self._last_completed_turn_id = None
367
+ self._turn_completed_event.clear()
364
368
  self._liveness.reset()
365
369
  self._cancel_requested = False
366
370
  self._signal_in_flight = False
@@ -440,14 +444,8 @@ class CodexConnection(HarnessConnection[ResolvedLaunchSpec]):
440
444
  # Fresh primary sessions need a bootstrap turn to materialize the
441
445
  # Codex rollout before the TUI can attach. Without this, Codex
442
446
  # cannot resume a fresh thread because no rollout file exists.
443
- #
444
- # The load-bearing requirement is "thread is attachable", not
445
- # "bootstrap response is semantically complete". We gate on
446
- # rollout materialization because that is the earliest observed
447
- # durable signal that `codex resume --remote` can attach.
448
- # Do not optimize this by mutating Codex model/reasoning defaults.
449
447
  self._emit_startup_phase(StartupPhase.INITIALIZING_SESSION)
450
- await self._send_bootstrap_turn_and_wait()
448
+ await self._send_bootstrap_turn_and_wait(agent_name=spec.agent_name)
451
449
 
452
450
  self._transition("connected")
453
451
  self._liveness.mark_activity()
@@ -847,6 +845,7 @@ class CodexConnection(HarnessConnection[ResolvedLaunchSpec]):
847
845
  process.kill()
848
846
  await process.wait()
849
847
 
848
+ await asyncio.to_thread(release_parent_death_link, self._parent_death_link)
850
849
  self._parent_death_link = None
851
850
  self._fail_pending_requests(RuntimeError("Codex connection stopped"))
852
851
  await self._clear_stale_hitl_requests(reason="connection_stopped")
@@ -1198,7 +1197,7 @@ class CodexConnection(HarnessConnection[ResolvedLaunchSpec]):
1198
1197
  raise RuntimeError("Codex connection config is unavailable")
1199
1198
  return config.control_root
1200
1199
 
1201
- async def _send_bootstrap_turn_and_wait(self) -> None:
1200
+ async def _send_bootstrap_turn_and_wait(self, *, agent_name: str | None) -> None:
1202
1201
  """Send a minimal bootstrap turn and wait for completion.
1203
1202
 
1204
1203
  This materializes the Codex rollout file so the TUI can later attach
@@ -1208,23 +1207,32 @@ class CodexConnection(HarnessConnection[ResolvedLaunchSpec]):
1208
1207
  attachability gate, not by mutating user-visible Codex defaults.
1209
1208
  """
1210
1209
  thread_id = self._require_thread_id("bootstrap_turn")
1211
- await self._request(
1210
+ normalized_agent = (agent_name or "").strip()
1211
+ prompt = _BOOTSTRAP_TURN_PROMPT
1212
+ if normalized_agent:
1213
+ prompt = f"{prompt} (agent: {normalized_agent})"
1214
+ result = await self._request(
1212
1215
  "turn/start",
1213
1216
  {
1214
1217
  "threadId": thread_id,
1215
- "input": _build_text_user_input(_BOOTSTRAP_TURN_PROMPT),
1218
+ "input": _build_text_user_input(prompt),
1216
1219
  },
1217
1220
  )
1218
1221
  await self._wait_for_rollout_materialization()
1222
+ turn_id = (
1223
+ _extract_turn_id(result)
1224
+ or self._current_turn_id
1225
+ or self._last_completed_turn_id
1226
+ )
1227
+ if turn_id is None:
1228
+ raise RuntimeError("Codex bootstrap turn did not provide a turn id")
1229
+ await self._wait_for_turn_completion(turn_id)
1219
1230
 
1220
1231
  async def _wait_for_rollout_materialization(self, timeout_seconds: float = 120.0) -> None:
1221
1232
  """Block until Codex has created an attachable rollout for the thread.
1222
1233
 
1223
- Fresh primary attach only needs the thread to be resumable by the Codex
1224
- TUI. The attach-safe signal is a rollout file whose session_meta exists
1225
- and whose cwd matches this project. We intentionally do not wait for
1226
- turn/completed and do not change model/effort settings to make bootstrap
1227
- cheaper.
1234
+ The attach-safe filesystem signal is a rollout file whose session_meta
1235
+ exists and whose cwd matches this project.
1228
1236
  """
1229
1237
  config = self._config
1230
1238
  codex_home = self._codex_home
@@ -1257,6 +1265,31 @@ class CodexConnection(HarnessConnection[ResolvedLaunchSpec]):
1257
1265
  if not process_running or not ws_open:
1258
1266
  raise RuntimeError("Codex connection lost during bootstrap turn")
1259
1267
 
1268
+ async def _wait_for_turn_completion(
1269
+ self,
1270
+ turn_id: str,
1271
+ timeout_seconds: float = 120.0,
1272
+ ) -> None:
1273
+ """Wait until the observer receives completion for the bootstrap turn."""
1274
+
1275
+ loop = asyncio.get_running_loop()
1276
+ deadline = loop.time() + timeout_seconds
1277
+ while self._last_completed_turn_id != turn_id:
1278
+ self._turn_completed_event.clear()
1279
+ if self._last_completed_turn_id == turn_id:
1280
+ return
1281
+ remaining = deadline - loop.time()
1282
+ if remaining <= 0:
1283
+ raise RuntimeError(
1284
+ f"Bootstrap turn timed out after {timeout_seconds}s waiting for completion"
1285
+ )
1286
+ try:
1287
+ await asyncio.wait_for(self._turn_completed_event.wait(), timeout=remaining)
1288
+ except TimeoutError as exc:
1289
+ raise RuntimeError(
1290
+ f"Bootstrap turn timed out after {timeout_seconds}s waiting for completion"
1291
+ ) from exc
1292
+
1260
1293
  async def _bootstrap_thread(self, spec: ResolvedLaunchSpec) -> dict[str, object]:
1261
1294
  method, payload = self._thread_bootstrap_request(spec)
1262
1295
  return await self._request(method, payload)
@@ -1294,7 +1327,9 @@ class CodexConnection(HarnessConnection[ResolvedLaunchSpec]):
1294
1327
  if thread_id is not None:
1295
1328
  self._main_turn_thread_id = thread_id
1296
1329
  if clears_signal(event, primary_event_scope=self.primary_event_scope):
1330
+ self._last_completed_turn_id = _extract_turn_id(payload) or self._current_turn_id
1297
1331
  self._end_current_turn()
1332
+ self._turn_completed_event.set()
1298
1333
  self._signal_in_flight = False
1299
1334
  self._liveness.signal_request_resolved("cancel")
1300
1335
  return
@@ -92,7 +92,11 @@ async def launch_managed_backend(
92
92
  except (psutil.NoSuchProcess, psutil.AccessDenied):
93
93
  birth_time = PROCESS_BIRTH_UNKNOWN_EPOCH
94
94
 
95
- parent_death_link = link_child_lifetime_to_parent(pid)
95
+ parent_death_link = (
96
+ ParentDeathLink(parent_death_linked=False)
97
+ if subprocess_config.parent_death_linked
98
+ else link_child_lifetime_to_parent(pid)
99
+ )
96
100
  parent_death_linked = (
97
101
  subprocess_config.parent_death_linked or parent_death_link.parent_death_linked
98
102
  )
@@ -69,7 +69,7 @@ from meridian.lib.observability.trace_helpers import (
69
69
  trace_wire_recv,
70
70
  trace_wire_send,
71
71
  )
72
- from meridian.lib.platform.detached_process import ParentDeathLink
72
+ from meridian.lib.platform.detached_process import ParentDeathLink, release_parent_death_link
73
73
  from meridian.lib.platform.process_scope import (
74
74
  ProcessScopeSnapshot,
75
75
  ScopedProcessHandle,
@@ -1044,6 +1044,7 @@ class OpenCodeConnection(HarnessConnection[ResolvedLaunchSpec]):
1044
1044
  process.kill()
1045
1045
  await process.wait()
1046
1046
 
1047
+ await asyncio.to_thread(release_parent_death_link, self._parent_death_link)
1047
1048
  self._parent_death_link = None
1048
1049
  self._base_url = None
1049
1050
  self._session_id = None
@@ -99,7 +99,7 @@ class ResolvedLaunchSpec(BaseModel):
99
99
  # All are optional and default to their zero values so unused adapters
100
100
  # don't need to set them.
101
101
 
102
- # Claude + OpenCode
102
+ # Harness-level agent identity. Codex also shows it in the managed bootstrap turn.
103
103
  agent_name: str | None = None
104
104
  appended_system_prompt: str | None = None
105
105
 
@@ -20,6 +20,15 @@ handles Windows-specific console inheritance. Subprocess is the portable fallbac
20
20
  `captures_output_to_artifact` on `ProcessPlatformContract` is authoritative — callers must
21
21
  not assume capture based on launcher type alone.
22
22
 
23
+ `ProcessLauncher.start()` returns a `RunningProcess` immediately after process birth.
24
+ PID/scope recording happens before `RunningProcess.wait()` begins the blocking terminal
25
+ relay. Keep those phases separate: managed-primary cancellation depends on having a
26
+ concrete process identity before it can wait for exit or terminate the scope.
27
+ `RunningProcess.cancel_wait()` must release its caller-facing wait even when scope
28
+ termination cannot confirm child exit. Managed attach also directly terminates the
29
+ concrete process as a fallback and bridges the synchronous wait through a daemon thread,
30
+ so an uncooperative relay cannot be re-joined by `asyncio.run()` during loop shutdown.
31
+
23
32
  ## Managed Attach vs Black-Box
24
33
 
25
34
  `_execute_primary_process()` checks `harness_contract.bootstrap.mode`. When mode is
@@ -19,9 +19,6 @@ class LaunchedProcess:
19
19
  pid: int | None
20
20
 
21
21
 
22
- ChildStartedHook = Callable[[int], None]
23
-
24
-
25
22
  class ProcessBackendId(StrEnum):
26
23
  """Named launch backends used for local harness process execution."""
27
24
 
@@ -48,26 +45,40 @@ class ProcessPlatformContract:
48
45
  platform_family: str
49
46
 
50
47
 
51
- @dataclass(frozen=True)
52
- class SelectedProcessLauncher:
53
- """Launcher instance paired with its explicit process/platform contract."""
48
+ class RunningProcess(Protocol):
49
+ """A started primary process whose blocking exit wait is a separate phase."""
54
50
 
55
- launcher: ProcessLauncher
56
- contract: ProcessPlatformContract
51
+ @property
52
+ def pid(self) -> int: ...
53
+
54
+ def wait(self) -> LaunchedProcess: ...
55
+
56
+ def terminate(self) -> None: ...
57
+
58
+ def cancel_wait(self) -> None:
59
+ """Unblock a concurrent wait without assuming the child exited."""
60
+ ...
57
61
 
58
62
 
59
63
  class ProcessLauncher(Protocol):
60
- """Protocol for primary process launch strategies."""
64
+ """Start a primary process and return as soon as its PID is available."""
61
65
 
62
- def launch(
66
+ def start(
63
67
  self,
64
68
  *,
65
69
  command: tuple[str, ...],
66
70
  cwd: Path,
67
71
  env: dict[str, str],
68
72
  output_log_path: Path | None,
69
- on_child_started: ChildStartedHook | None = None,
70
- ) -> LaunchedProcess: ...
73
+ ) -> RunningProcess: ...
74
+
75
+
76
+ @dataclass(frozen=True)
77
+ class SelectedProcessLauncher:
78
+ """Launcher instance paired with its explicit process/platform contract."""
79
+
80
+ launcher: ProcessLauncher
81
+ contract: ProcessPlatformContract
71
82
 
72
83
 
73
84
  ProcessLauncherSelector = Callable[[Path | None], ProcessLauncher]
@@ -75,12 +86,12 @@ ProcessLauncherSelector = Callable[[Path | None], ProcessLauncher]
75
86
 
76
87
  __all__ = [
77
88
  "PRIMARY_STDERR_LOG_PATH_ENV",
78
- "ChildStartedHook",
79
89
  "LaunchedProcess",
80
90
  "ProcessBackendId",
81
91
  "ProcessLauncher",
82
92
  "ProcessLauncherSelector",
83
93
  "ProcessPlatformContract",
84
94
  "ProcessSurfaceMode",
95
+ "RunningProcess",
85
96
  "SelectedProcessLauncher",
86
97
  ]
@@ -13,10 +13,11 @@ from collections.abc import Callable
13
13
  from contextlib import suppress
14
14
  from dataclasses import dataclass, field, replace
15
15
  from pathlib import Path
16
- from threading import Lock
16
+ from threading import Lock, Thread
17
17
  from typing import Any
18
18
 
19
19
  import psutil
20
+ import structlog
20
21
 
21
22
  from meridian.lib.core.types import HarnessId, SpawnId
22
23
  from meridian.lib.harness.connections.base import ConnectionConfig, HarnessConnection, HarnessEvent
@@ -33,10 +34,46 @@ from meridian.lib.state.history import HarnessHistoryWriter
33
34
  from meridian.lib.state.primary_meta import ActivityState, PrimaryMetadata, write_primary_metadata
34
35
  from meridian.lib.state.process_scope_projection import record_scope
35
36
 
36
- from .ports import ProcessLauncher
37
+ from .ports import LaunchedProcess, ProcessLauncher, RunningProcess
37
38
 
38
39
  TuiCommandBuilder = Callable[[str], tuple[str, ...]]
39
40
  MAX_PORT_RETRY_ATTEMPTS = 3
41
+ _TUI_LAUNCH_DRAIN_TIMEOUT_SECONDS = 1.0
42
+ _TUI_WAIT_CANCEL_TIMEOUT_SECONDS = 1.0
43
+
44
+ logger = structlog.get_logger(__name__)
45
+
46
+
47
+ def _start_process_wait(running_process: RunningProcess) -> asyncio.Future[LaunchedProcess]:
48
+ """Run a synchronous terminal relay without joining it during loop shutdown."""
49
+
50
+ loop = asyncio.get_running_loop()
51
+ result_future: asyncio.Future[LaunchedProcess] = loop.create_future()
52
+
53
+ def _publish_result(result: LaunchedProcess) -> None:
54
+ if not result_future.done():
55
+ result_future.set_result(result)
56
+
57
+ def _publish_error(error: BaseException) -> None:
58
+ if not result_future.done():
59
+ result_future.set_exception(error)
60
+
61
+ def _wait() -> None:
62
+ try:
63
+ result = running_process.wait()
64
+ except BaseException as exc:
65
+ with suppress(RuntimeError):
66
+ loop.call_soon_threadsafe(_publish_error, exc)
67
+ return
68
+ with suppress(RuntimeError):
69
+ loop.call_soon_threadsafe(_publish_result, result)
70
+
71
+ Thread(
72
+ target=_wait,
73
+ name=f"meridian-primary-wait-{running_process.pid}",
74
+ daemon=True,
75
+ ).start()
76
+ return result_future
40
77
 
41
78
 
42
79
  def _make_scope_snapshot(
@@ -209,6 +246,9 @@ class PrimaryAttachLauncher:
209
246
  self._history_writer = HarnessHistoryWriter(self._spawn_dir / "history.jsonl")
210
247
  connection_started = False
211
248
  session_id: str | None = None
249
+ running_process: RunningProcess | None = None
250
+ launch_task: asyncio.Future[LaunchedProcess] | None = None
251
+ tui_lifecycle_finished = False
212
252
  telemetry = _StartupTelemetry()
213
253
 
214
254
  try:
@@ -245,7 +285,6 @@ class PrimaryAttachLauncher:
245
285
 
246
286
  telemetry.update(f"Attaching {self._connection.harness_id.value.capitalize()} TUI...")
247
287
  command = tuple(self._tui_command_builder(session_id))
248
- loop = asyncio.get_running_loop()
249
288
  running_callback = on_running if on_running is not None else self._on_running
250
289
 
251
290
  def _handle_running(pid: int) -> None:
@@ -254,19 +293,19 @@ class PrimaryAttachLauncher:
254
293
  if running_callback is not None:
255
294
  running_callback(pid)
256
295
 
257
- def _on_child_started(pid: int) -> None:
258
- loop.call_soon_threadsafe(_handle_running, pid)
259
-
260
- launch_task = asyncio.create_task(
261
- asyncio.to_thread(
262
- self._process_launcher.launch,
263
- command=command,
264
- cwd=cwd,
265
- env=env,
266
- output_log_path=None,
267
- on_child_started=_on_child_started,
268
- )
296
+ running_process = self._process_launcher.start(
297
+ command=command,
298
+ cwd=cwd,
299
+ env=env,
300
+ output_log_path=None,
269
301
  )
302
+ try:
303
+ _handle_running(running_process.pid)
304
+ except Exception:
305
+ running_process.terminate()
306
+ await _start_process_wait(running_process)
307
+ raise
308
+ launch_task = _start_process_wait(running_process)
270
309
  telemetry.clear()
271
310
 
272
311
  writer_task = self._event_writer_task
@@ -281,22 +320,28 @@ class PrimaryAttachLauncher:
281
320
  if self._connection.harness_id is HarnessId.CODEX:
282
321
  # Codex TUI takes over the observer endpoint after attach;
283
322
  # the displaced observer stream closing is normal.
284
- launched = await launch_task
323
+ launched = await asyncio.shield(launch_task)
324
+ tui_lifecycle_finished = True
285
325
  return PrimaryAttachOutcome(
286
326
  exit_code=launched.exit_code,
287
327
  session_id=session_id,
288
328
  tui_pid=launched.pid,
289
329
  )
290
330
  await self._connection.stop(reason="event_stream_closed")
291
- await self._terminate_tui_scope()
292
- launched = await launch_task
331
+ await self._stop_tui_launch_task(
332
+ running_process,
333
+ launch_task,
334
+ reason="event_stream_closed",
335
+ )
336
+ tui_lifecycle_finished = True
293
337
  return PrimaryAttachOutcome(
294
338
  exit_code=1,
295
339
  session_id=session_id,
296
- tui_pid=launched.pid,
340
+ tui_pid=running_process.pid,
297
341
  )
298
342
 
299
- launched = await launch_task
343
+ launched = await asyncio.shield(launch_task)
344
+ tui_lifecycle_finished = True
300
345
 
301
346
  return PrimaryAttachOutcome(
302
347
  exit_code=launched.exit_code,
@@ -314,6 +359,16 @@ class PrimaryAttachLauncher:
314
359
  writer_task.cancel()
315
360
  with suppress(asyncio.CancelledError):
316
361
  await writer_task
362
+ if (
363
+ running_process is not None
364
+ and launch_task is not None
365
+ and not tui_lifecycle_finished
366
+ ):
367
+ await self._stop_tui_launch_task(
368
+ running_process,
369
+ launch_task,
370
+ reason="primary_attach_shutdown",
371
+ )
317
372
  if connection_started:
318
373
  await self._connection.stop()
319
374
 
@@ -449,7 +504,45 @@ class PrimaryAttachLauncher:
449
504
  self._tui_scope_snapshot = snapshot
450
505
  record_scope(runtime_root, self._spawn_id, snapshot)
451
506
 
452
- async def _terminate_tui_scope(self) -> None:
507
+ async def _stop_tui_launch_task(
508
+ self,
509
+ running_process: RunningProcess,
510
+ launch_task: asyncio.Future[LaunchedProcess],
511
+ *,
512
+ reason: str,
513
+ ) -> None:
514
+ await self._terminate_tui_scope(reason=reason)
515
+ try:
516
+ await asyncio.wait_for(
517
+ asyncio.shield(launch_task),
518
+ timeout=_TUI_LAUNCH_DRAIN_TIMEOUT_SECONDS,
519
+ )
520
+ except TimeoutError:
521
+ logger.warning(
522
+ "primary_attach.tui_drain_timeout",
523
+ spawn_id=str(self._spawn_id),
524
+ )
525
+ running_process.terminate()
526
+ running_process.cancel_wait()
527
+ try:
528
+ await asyncio.wait_for(
529
+ asyncio.shield(launch_task),
530
+ timeout=_TUI_WAIT_CANCEL_TIMEOUT_SECONDS,
531
+ )
532
+ except TimeoutError:
533
+ logger.error(
534
+ "primary_attach.tui_wait_cancel_timeout",
535
+ spawn_id=str(self._spawn_id),
536
+ )
537
+ launch_task.cancel()
538
+ with suppress(asyncio.CancelledError):
539
+ await launch_task
540
+ except asyncio.CancelledError:
541
+ raise
542
+ except Exception:
543
+ pass
544
+
545
+ async def _terminate_tui_scope(self, *, reason: str) -> None:
453
546
  snapshot = self._tui_scope_snapshot
454
547
  if snapshot is None:
455
548
  return
@@ -457,7 +550,7 @@ class PrimaryAttachLauncher:
457
550
  terminate_scope_sync,
458
551
  snapshot,
459
552
  grace_seconds=5.0,
460
- reason="event_stream_closed",
553
+ reason=reason,
461
554
  )
462
555
 
463
556
  def _resolve_backend_port(self) -> int | None:
@@ -8,12 +8,13 @@ import struct
8
8
  import sys
9
9
  import threading
10
10
  from contextlib import ExitStack, suppress
11
+ from dataclasses import dataclass, field
11
12
  from pathlib import Path
12
13
  from typing import Any, BinaryIO, cast
13
14
 
14
15
  from meridian.lib.platform import IS_WINDOWS, fcntl, pty, select, termios, tty
15
16
 
16
- from .ports import ChildStartedHook, LaunchedProcess, ProcessLauncher
17
+ from .ports import LaunchedProcess, ProcessLauncher
17
18
 
18
19
 
19
20
  def can_use_pty() -> bool:
@@ -78,6 +79,7 @@ def _copy_primary_pty_output(
78
79
  child_pid: int,
79
80
  master_fd: int,
80
81
  output_log_path: Path | None,
82
+ wait_cancelled: threading.Event | None = None,
81
83
  ) -> int:
82
84
  stdin_fd = sys.stdin.fileno()
83
85
  stdout_fd = sys.stdout.fileno()
@@ -96,10 +98,12 @@ def _copy_primary_pty_output(
96
98
  output_handle = stack.enter_context(output_log_path.open("wb"))
97
99
 
98
100
  while True:
101
+ if wait_cancelled is not None and wait_cancelled.is_set():
102
+ return 130
99
103
  fds = [master_fd]
100
104
  if stdin_open:
101
105
  fds.append(stdin_fd)
102
- ready, _, _ = select.select(fds, [], [])
106
+ ready, _, _ = select.select(fds, [], [], 0.1)
103
107
 
104
108
  if master_fd in ready:
105
109
  try:
@@ -128,18 +132,45 @@ def _copy_primary_pty_output(
128
132
  return os.waitstatus_to_exitcode(status)
129
133
 
130
134
 
135
+ @dataclass
136
+ class _RunningPtyProcess:
137
+ pid: int
138
+ master_fd: int
139
+ output_log_path: Path | None
140
+ wait_cancelled: threading.Event = field(default_factory=threading.Event)
141
+
142
+ def wait(self) -> LaunchedProcess:
143
+ try:
144
+ exit_code = _copy_primary_pty_output(
145
+ child_pid=self.pid,
146
+ master_fd=self.master_fd,
147
+ output_log_path=self.output_log_path,
148
+ wait_cancelled=self.wait_cancelled,
149
+ )
150
+ return LaunchedProcess(exit_code=exit_code, pid=self.pid)
151
+ finally:
152
+ with suppress(OSError):
153
+ os.close(self.master_fd)
154
+
155
+ def terminate(self) -> None:
156
+ with suppress(ProcessLookupError):
157
+ os.kill(self.pid, signal.SIGTERM)
158
+
159
+ def cancel_wait(self) -> None:
160
+ self.wait_cancelled.set()
161
+
162
+
131
163
  class PtyProcessLauncher(ProcessLauncher):
132
164
  """Unix PTY launcher with optional output capture."""
133
165
 
134
- def launch(
166
+ def start(
135
167
  self,
136
168
  *,
137
169
  command: tuple[str, ...],
138
170
  cwd: Path,
139
171
  env: dict[str, str],
140
172
  output_log_path: Path | None,
141
- on_child_started: ChildStartedHook | None = None,
142
- ) -> LaunchedProcess:
173
+ ) -> _RunningPtyProcess:
143
174
  if IS_WINDOWS:
144
175
  raise RuntimeError("PTY launcher is not available on Windows")
145
176
 
@@ -159,25 +190,11 @@ class PtyProcessLauncher(ProcessLauncher):
159
190
  os._exit(1)
160
191
 
161
192
  os.close(slave_fd)
162
- try:
163
- if on_child_started is not None:
164
- try:
165
- on_child_started(child_pid)
166
- except Exception:
167
- with suppress(ProcessLookupError):
168
- os.kill(child_pid, signal.SIGTERM)
169
- with suppress(ChildProcessError):
170
- os.waitpid(child_pid, 0)
171
- raise
172
- exit_code = _copy_primary_pty_output(
173
- child_pid=child_pid,
174
- master_fd=master_fd,
175
- output_log_path=output_log_path,
176
- )
177
- return LaunchedProcess(exit_code=exit_code, pid=child_pid)
178
- finally:
179
- with suppress(OSError):
180
- os.close(master_fd)
193
+ return _RunningPtyProcess(
194
+ pid=child_pid,
195
+ master_fd=master_fd,
196
+ output_log_path=output_log_path,
197
+ )
181
198
 
182
199
 
183
200
  __all__ = [