meridian-cli 0.2.0__tar.gz → 0.2.2__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.
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/.gitignore +2 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/PKG-INFO +2 -2
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/pyproject.toml +2 -1
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/__init__.py +1 -1
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/app_tree.py +1 -1
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/bootstrap.py +1 -1
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/bootstrap_cmd.py +4 -1
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/chat_cmd.py +1 -1
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/main.py +4 -1
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/misc_commands.py +1 -1
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/startup/help.py +2 -2
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/catalog/model_aliases.py +0 -7
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/types.py +1 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/.context/CONTEXT.md +32 -3
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/AGENTS.md +3 -1
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/__init__.py +6 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/adapter.py +5 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/claude.py +6 -1
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/codex.py +7 -1
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/connections/.context/CONTEXT.md +6 -2
- meridian_cli-0.2.2/src/meridian/lib/harness/connections/cursor_subprocess.py +273 -0
- meridian_cli-0.2.2/src/meridian/lib/harness/cursor.py +206 -0
- meridian_cli-0.2.2/src/meridian/lib/harness/extractors/cursor.py +110 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/opencode.py +6 -1
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/.context/CONTEXT.md +40 -6
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/project_claude.py +1 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/project_codex_streaming.py +1 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/project_codex_subprocess.py +1 -0
- meridian_cli-0.2.2/src/meridian/lib/harness/projections/project_cursor.py +126 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/project_opencode_streaming.py +1 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/project_opencode_subprocess.py +1 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/project_pi_native_tui.py +1 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/project_pi_rpc.py +1 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/registry.py +2 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/semantics.py +21 -1
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/constants.py +9 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/launch_types.py +2 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/policies.py +0 -4
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/resolve.py +0 -20
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/safety/permissions.py +11 -15
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/streaming/spawn_manager.py +16 -2
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/LICENSE +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/README.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/ag_ui/__init__.pyi +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/ag_ui/core.pyi +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/__main__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/_cmd_utils.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/agent_help.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/argv_normalization.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/config_cmd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/doctor_cmd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/entrypoint.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/ext_cmd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/ext_registration.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/hooks_authority.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/hooks_commands.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/kg_cmd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/mars_passthrough.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/mermaid_cmd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/migrate_cmd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/models_cmd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/output.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/primary_launch.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/qi_cmd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/report_cmd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/session_cmd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/spawn.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/spawn_inject.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/startup/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/startup/catalog.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/startup/classify.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/startup/cyclopts_app.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/startup/lazy_dispatch.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/startup/policy.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/streaming_serve.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/sync_cmd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/telemetry_cmd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/utils.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/work_cmd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/cli/workspace_cmd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/dev/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/dev/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/dev/pytests.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/bootstrap/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/bootstrap/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/bootstrap/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/bootstrap/config.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/bootstrap/project_state.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/bootstrap/runtime_state.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/bootstrap/services.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/catalog/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/catalog/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/catalog/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/catalog/agent.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/catalog/bootstrap.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/catalog/catalog_session.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/catalog/models.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/catalog/skill.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/backend_acquisition.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/backend_handle.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/checkpoint.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/command_handler.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/command_invariants.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/commands.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/dev_frontend/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/dev_frontend/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/dev_frontend/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/dev_frontend/discovery.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/dev_frontend/launcher.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/dev_frontend/policy.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/dev_frontend/portless.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/dev_frontend/raw_vite.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/dev_frontend/supervisor.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/event_index.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/event_log.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/event_observer.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/event_pipeline.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/frontend.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/normalization/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/normalization/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/normalization/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/normalization/base.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/normalization/claude.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/normalization/codex.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/normalization/common.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/normalization/opencode.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/normalization/registry.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/normalization/synthetic.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/policy.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/protocol.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/recovery.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/replay.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/runtime.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/server.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/session_service.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/chat/ws_fanout.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/config/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/config/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/config/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/config/catalog.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/config/context_config.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/config/preserving_edit.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/config/project_config_state.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/config/project_paths.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/config/project_root.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/config/schema.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/config/settings.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/config/workspace.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/context/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/context/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/context/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/context/resolver.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/child_env.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/clock.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/codec.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/context.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/conversation.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/depth.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/domain.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/execution_policy.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/formatting.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/lifecycle.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/logging.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/overrides.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/process_cleanup.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/resolved_context.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/sink.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/spawn_lifecycle.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/spawn_service.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/spawn_start.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/telemetry.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/core/util.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/diagnostics.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/commands/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/commands/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/commands/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/commands/biomed.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/commands/mermaid.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/commands/sessions.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/commands/workbench.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/context.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/descriptors.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/dispatcher.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/first_party.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/observability.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/registry.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/extensions/types.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/bundle.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/claude_preflight.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/claude_utils.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/codex_rollout.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/common.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/connections/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/connections/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/connections/base.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/connections/claude_ws.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/connections/codex_ws.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/connections/errors.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/connections/opencode_http.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/connections/pi_lifecycle_file.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/connections/pi_rpc.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/control_action.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/cost.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/errors.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/extractor.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/extractors/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/extractors/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/extractors/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/extractors/base.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/extractors/claude.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/extractors/codex.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/extractors/opencode.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/extractors/pi.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/launch_spec.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/launch_types.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/opencode_storage.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/opencode_transcript.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/passthrough/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/passthrough/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/passthrough/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/passthrough/base.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/passthrough/claude.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/passthrough/codex.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/passthrough/opencode.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/passthrough/registry.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/permission_broker.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/pi.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/pi_lifecycle_events.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/pi_runtime_resolver.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/_guards.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/permission_flags.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/pi_extension_projection.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/project_codex_common.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/projections/projection_errors.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/session_detection.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/transcript.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/builtin/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/builtin/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/builtin/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/builtin/autosync_store.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/builtin/base.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/builtin/git_autosync.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/builtin_registry.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/config.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/dispatch.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/interval.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/registry.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/runner.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/hooks/types.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ignores.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/kg/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/kg/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/kg/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/kg/graph.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/kg/report.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/kg/serializer.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/kg/types.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/artifact_io.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/bundle_adapter.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/claude_session_access.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/command.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/compiler.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/composition.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/context.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/cwd.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/env.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/errors.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/extract.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/fork.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/materialize.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/permissions.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/plan.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/process/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/process/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/process/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/process/ports.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/process/primary_attach.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/process/pty_launcher.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/process/runner.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/process/session.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/process/subprocess_launcher.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/process/windows_launcher.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/prompt.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/reference.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/report.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/request.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/run_inputs.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/runner_helpers.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/session_scope.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/signals.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/streaming/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/streaming/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/streaming/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/streaming/heartbeat.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/streaming/terminal_arbitrator.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/streaming_runner.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/text_utils.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/types.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/workspace.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/workspace_projection.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/launch/written_files.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/markdown/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/markdown/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/markdown/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/markdown/extract.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/markdown/types.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/report.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/scanner.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/serializer.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/style/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/style/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/style/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/style/bare_end.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/style/fill_no_color.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/style/line_map.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/style/ox_edge.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/style/preprocess.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/style/suppression.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/style/types.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/mermaid/validator.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/observability/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/observability/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/observability/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/observability/debug_tracer.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/observability/trace_helpers.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/catalog.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/commands.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/config.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/config_surface.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/context.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/diag.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/hooks.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/init_ops.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/mars.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/migration.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/pruning.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/qi.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/reference.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/reference_recovery.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/report.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/runtime.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/session_export.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/session_log.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/session_read.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/session_render.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/session_repair.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/session_search.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/session_target.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/spawn/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/spawn/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/spawn/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/spawn/api.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/spawn/context_ref.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/spawn/execute.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/spawn/execute_bg.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/spawn/execute_init.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/spawn/execute_runner.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/spawn/execute_session.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/spawn/failure_policy.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/spawn/models.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/spawn/prepare.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/spawn/query.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/sync_conflicts.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/work_attachment.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/work_dashboard.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/work_lifecycle.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/workspace.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/worktree_format.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/worktree_lifecycle.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/ops/worktree_ops.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/platform/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/platform/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/platform/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/platform/locking.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/platform/process_scope/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/platform/process_scope/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/platform/process_scope/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/platform/process_scope/base.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/platform/process_scope/fallback.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/platform/process_scope/posix.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/platform/process_scope/windows_job.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/platform/terminate.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/platform/unix_modules.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/platform/windows_job.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/safety/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/safety/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/safety/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/safety/budget.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/safety/guardrails.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/safety/redaction.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/service_context.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/spawn/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/spawn/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/spawn/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/spawn/archive.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/artifact_store.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/atomic.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/event_store.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/history.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/launch_boundary.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/liveness.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/managed_primary.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/paths.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/primary_meta.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/process_scope_projection.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/reaper.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/session_store.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/spawn/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/spawn/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/spawn/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/spawn/model.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/spawn/repository.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/spawn/terminal_policy.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/spawn/transitions.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/spawn_store.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/user_paths.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/wordgen.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/wordlists.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/state/work_store.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/streaming/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/streaming/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/streaming/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/streaming/control_socket.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/streaming/drain_policy.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/streaming/event_observers.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/streaming/heartbeat.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/streaming/inject_lock.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/streaming/signal_canceller.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/streaming/types.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/bootstrap.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/correlation.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/events.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/init.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/local_jsonl.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/maintenance.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/observer.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/observers.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/query.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/reader.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/retention.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/router.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/sinks.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/telemetry/status.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/tools.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/utils/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/utils/time.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/pi_runtime/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/pi_runtime/README.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/pi_runtime/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/pi_runtime/extensions/managed-bash/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/pi_runtime/extensions/managed-bash/src/index.ts +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/pi_runtime/extensions/meridian-lifecycle/.context/CONTEXT.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/pi_runtime/extensions/meridian-lifecycle/src/index.ts +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/pi_runtime/extensions/shared/lifecycle_sidecar.ts +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/pi_runtime/extensions/types.ts +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/pi_runtime/package.json +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/pi_runtime/pnpm-lock.yaml +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/pi_runtime/pnpm-workspace.yaml +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/plugin_api/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/plugin_api/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/plugin_api/config.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/plugin_api/fs.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/plugin_api/git.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/plugin_api/state.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/plugin_api/types.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/py.typed +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/server/AGENTS.md +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/server/__init__.py +0 -0
- {meridian_cli-0.2.0 → meridian_cli-0.2.2}/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.2.
|
|
3
|
+
Version: 0.2.2
|
|
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.
|
|
27
|
+
Requires-Dist: mars-agents==0.7.0
|
|
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.
|
|
27
|
+
"mars-agents==0.7.0",
|
|
28
28
|
"mcp>=1.0",
|
|
29
29
|
"pathspec>=1.1.0",
|
|
30
30
|
"psutil>=7.2.2",
|
|
@@ -145,4 +145,5 @@ pythonpath = ["src"]
|
|
|
145
145
|
[dependency-groups]
|
|
146
146
|
dev = [
|
|
147
147
|
"pytest-xdist>=3.8.0",
|
|
148
|
+
"ruff>=0.15.11",
|
|
148
149
|
]
|
|
@@ -20,7 +20,7 @@ app = App(
|
|
|
20
20
|
" --fork preserves agent/model/skills identity. --fork-fresh allows\n"
|
|
21
21
|
" identity changes and may reduce prompt-cache locality. --from starts\n"
|
|
22
22
|
" fresh with prior context as reference material only.\n\n"
|
|
23
|
-
"Global harness selection: --harness (or prefix with claude/codex/opencode)\n\n"
|
|
23
|
+
"Global harness selection: --harness (or prefix with claude/codex/cursor/opencode)\n\n"
|
|
24
24
|
"Bundled package manager: meridian mars ARGS...\n\n"
|
|
25
25
|
'Run "meridian spawn -h" for subagent usage.\n'
|
|
26
26
|
),
|
|
@@ -56,7 +56,7 @@ _TOP_LEVEL_BOOL_FLAGS = frozenset(
|
|
|
56
56
|
"--no-dry-run",
|
|
57
57
|
}
|
|
58
58
|
)
|
|
59
|
-
HARNESS_SHORTCUT_NAMES = frozenset({"claude", "codex", "opencode", "pi"})
|
|
59
|
+
HARNESS_SHORTCUT_NAMES = frozenset({"claude", "codex", "cursor", "opencode", "pi"})
|
|
60
60
|
_CHAT_MANAGEMENT_SUBCOMMANDS = frozenset({"ls", "show", "log", "close"})
|
|
61
61
|
_TOP_LEVEL_COMMAND_TOKENS = frozenset(COMMAND_CATALOG.top_level_names()) | HARNESS_SHORTCUT_NAMES
|
|
62
62
|
|
|
@@ -36,7 +36,10 @@ def register_bootstrap_command(
|
|
|
36
36
|
] = "",
|
|
37
37
|
harness: Annotated[
|
|
38
38
|
str | None,
|
|
39
|
-
Parameter(
|
|
39
|
+
Parameter(
|
|
40
|
+
name="--harness",
|
|
41
|
+
help="Force harness id (claude, codex, cursor, opencode, or pi).",
|
|
42
|
+
),
|
|
40
43
|
] = None,
|
|
41
44
|
agent: Annotated[
|
|
42
45
|
str | None,
|
|
@@ -72,7 +72,7 @@ def _chat(
|
|
|
72
72
|
] = None,
|
|
73
73
|
harness: Annotated[
|
|
74
74
|
str | None,
|
|
75
|
-
Parameter(name="--harness", help="Harness id: claude, codex, or opencode."),
|
|
75
|
+
Parameter(name="--harness", help="Harness id: claude, codex, cursor, or opencode."),
|
|
76
76
|
] = None,
|
|
77
77
|
agent: Annotated[
|
|
78
78
|
str | None,
|
|
@@ -308,7 +308,10 @@ def root(
|
|
|
308
308
|
] = "",
|
|
309
309
|
harness: Annotated[
|
|
310
310
|
str | None,
|
|
311
|
-
Parameter(
|
|
311
|
+
Parameter(
|
|
312
|
+
name="--harness",
|
|
313
|
+
help="Force harness id (claude, codex, cursor, opencode, or pi).",
|
|
314
|
+
),
|
|
312
315
|
] = None,
|
|
313
316
|
agent: Annotated[
|
|
314
317
|
str | None,
|
|
@@ -88,7 +88,7 @@ def register_misc_commands(
|
|
|
88
88
|
] = "",
|
|
89
89
|
harness: Annotated[
|
|
90
90
|
str | None,
|
|
91
|
-
Parameter(name="--harness", help="Harness id: claude, codex, or opencode."),
|
|
91
|
+
Parameter(name="--harness", help="Harness id: claude, codex, cursor, or opencode."),
|
|
92
92
|
] = None,
|
|
93
93
|
model: Annotated[
|
|
94
94
|
str | None,
|
|
@@ -136,7 +136,7 @@ Options:
|
|
|
136
136
|
--json Emit command output as JSON.
|
|
137
137
|
--format TEXT Set output format: text or json.
|
|
138
138
|
--config TEXT Path to a user config TOML overlay.
|
|
139
|
-
--harness TEXT Force harness id (claude, codex, or
|
|
139
|
+
--harness TEXT Force harness id (claude, codex, cursor, opencode, or pi).
|
|
140
140
|
--model, -m TEXT Model id or alias for primary harness.
|
|
141
141
|
|
|
142
142
|
Commands:
|
|
@@ -160,7 +160,7 @@ Primary launch/resume:
|
|
|
160
160
|
identity changes and may reduce prompt-cache locality. --from starts
|
|
161
161
|
fresh with prior context as reference material only.
|
|
162
162
|
|
|
163
|
-
Global harness selection: --harness (or prefix with claude/codex/opencode)
|
|
163
|
+
Global harness selection: --harness (or prefix with claude/codex/cursor/opencode)
|
|
164
164
|
|
|
165
165
|
Bundled package manager: meridian mars ARGS...
|
|
166
166
|
|
|
@@ -63,13 +63,6 @@ class AliasEntry(BaseModel):
|
|
|
63
63
|
def mars_provided_harness(self) -> HarnessId | None:
|
|
64
64
|
return self.resolved_harness
|
|
65
65
|
|
|
66
|
-
def harness_model_id_for(self, harness: str) -> str | None:
|
|
67
|
-
"""Return the harness-specific model ID for a given harness, or None."""
|
|
68
|
-
for path in self.runnable_paths:
|
|
69
|
-
if path.harness == harness:
|
|
70
|
-
return path.harness_model_id
|
|
71
|
-
return None
|
|
72
|
-
|
|
73
66
|
def format_text(self, ctx: object | None = None) -> str:
|
|
74
67
|
_ = ctx
|
|
75
68
|
from meridian.lib.core.formatting import kv_block
|
|
@@ -40,7 +40,8 @@ Per-harness mapping:
|
|
|
40
40
|
- Claude connection: `claude -p --input-format stream-json --output-format stream-json --verbose` (stdin/stdout NDJSON, not WebSocket despite `claude_ws.py` name)
|
|
41
41
|
- Codex subprocess: `codex exec --json`; connection: `codex app-server` (real WebSocket, JSON-RPC 2.0)
|
|
42
42
|
- OpenCode subprocess: `opencode run`; connection: `opencode serve` (HTTP+SSE)
|
|
43
|
-
-
|
|
43
|
+
- Cursor subprocess: `cursor agent <prompt>` (stdout NDJSON, no connection path — subprocess-only)
|
|
44
|
+
- Pi subprocess/connection: `pi rpc --mode rpc` (JSON-RPC stdio); Pi has no subprocess-only path — the RPC mode is the connection
|
|
44
45
|
|
|
45
46
|
### Pi: Extension-Based Architecture
|
|
46
47
|
|
|
@@ -107,12 +108,18 @@ Every `SpawnParams` field must appear in each adapter's `consumed_fields` **or**
|
|
|
107
108
|
Currently ignored fields:
|
|
108
109
|
- Claude ignores `report_output_path`, `task_cwd`, `context_from_payload`, `reference_items`
|
|
109
110
|
- Codex ignores `skills`, `agent`, `task_cwd`, `context_from_payload`, `reference_items`
|
|
111
|
+
- Cursor ignores `skills`, `agent`, `adhoc_agent_payload`, `control_root`,
|
|
112
|
+
`appended_system_prompt`, `report_output_path`, `user_turn_content`,
|
|
113
|
+
`context_from_payload`, `reference_items`, `continue_harness_session_id`,
|
|
114
|
+
`continue_fork`, `effort`
|
|
110
115
|
|
|
111
|
-
`task_cwd` is ignored by harness adapters because the `control_root`/`task_cwd` split
|
|
116
|
+
`task_cwd` is ignored by most harness adapters because the `control_root`/`task_cwd` split
|
|
112
117
|
assigns different responsibilities to different layers: adapters consume `control_root`
|
|
113
118
|
for spawn directory resolution and `--add-dir` roots, while `task_cwd` is injected into
|
|
114
119
|
the agent's working context via system prompt in `bind_launch_context()` at the composition
|
|
115
|
-
layer. The harness command never needs the raw `task_cwd` value.
|
|
120
|
+
layer. The harness command never needs the raw `task_cwd` value. **Exception:** Cursor
|
|
121
|
+
consumes `task_cwd` directly and projects it as `--workspace` — Cursor uses it as the
|
|
122
|
+
working directory for the agent subprocess, not as a system-prompt injection.
|
|
116
123
|
|
|
117
124
|
### Projection Drift Guard
|
|
118
125
|
|
|
@@ -157,6 +164,8 @@ Key mappings:
|
|
|
157
164
|
- Claude: `result` event with `is_error=True` → failed; `subtype in ("", "success")` and `terminal_reason in ("", "completed")` → succeeded
|
|
158
165
|
- Codex: `turn/completed` → succeeded; `error/connectionClosed` → failed
|
|
159
166
|
- OpenCode: `session.idle` → succeeded; `session.error` → failed
|
|
167
|
+
- Cursor: `error/connectionClosed` → failed; no explicit success event — stdout EOF
|
|
168
|
+
+ process exit code 0 is the success boundary (see `CursorSubprocessConnection.events()`).
|
|
160
169
|
- Pi: `agent_end` → succeeded with quiescence check; `cancelled`/`error` → failed.
|
|
161
170
|
The `agent_end` → success mapping is conditional: the drain loop only breaks when
|
|
162
171
|
quiescence is also confirmed (no pending children/notifications). See `PiRpcQuiescenceDrainPolicy`.
|
|
@@ -209,6 +218,26 @@ was still initializing. The module only depends on `core.types` — it never dep
|
|
|
209
218
|
on harness internals. `opencode_http.py` now imports `OPENCODE_CONFIG_CONTENT_ENV`
|
|
210
219
|
from `meridian.lib.launch.workspace_projection`.
|
|
211
220
|
|
|
221
|
+
### Cursor: Subprocess-Only, Read-Only stdout
|
|
222
|
+
|
|
223
|
+
Cursor is a single-turn, subprocess-only harness. `cursor agent <prompt>` streams
|
|
224
|
+
NDJSON events to stdout then exits — there is no stdin injection, no session resume,
|
|
225
|
+
and no bidirectional transport. `CursorSubprocessConnection` is a connection adapter
|
|
226
|
+
in name only: it reads stdout until EOF and process exit, then reports done.
|
|
227
|
+
|
|
228
|
+
`task_cwd` is projected as `--workspace` rather than delegated to the system-prompt
|
|
229
|
+
composition layer. Cursor's agent subprocess needs the workspace path as a CLI flag
|
|
230
|
+
to set its working directory — system-prompt injection alone is insufficient.
|
|
231
|
+
|
|
232
|
+
`effort` appears in `_DELEGATED_FIELDS` because Mars resolves `model + effort` →
|
|
233
|
+
`harness_model` at bundle-build time. By the time `project_cursor_spec_to_cli_args()`
|
|
234
|
+
runs, `spec.model` already contains the effort-resolved model string; `effort` has
|
|
235
|
+
served its purpose and is not passed to the CLI.
|
|
236
|
+
|
|
237
|
+
MVP scope exclusions (enforced by `_assert_supported_for_mvp()`): per-spawn
|
|
238
|
+
`mcp_tools`, `continue_fork`, `continue_session_id`, and `interactive` all raise
|
|
239
|
+
`HarnessCapabilityMismatch` at projection time.
|
|
240
|
+
|
|
212
241
|
### Pi: Quiescence Instead of Process Exit
|
|
213
242
|
|
|
214
243
|
Pi spawned sessions don't exit when a task completes — they stay alive to track
|
|
@@ -39,6 +39,8 @@ Per-harness commands:
|
|
|
39
39
|
- Claude connection: stdin/stdout NDJSON (not WebSocket despite `claude_ws.py` name)
|
|
40
40
|
- Codex subprocess: `codex exec --json`; connection: `codex app-server` (real WebSocket, JSON-RPC 2.0)
|
|
41
41
|
- OpenCode subprocess: `opencode run`; connection: `opencode serve` (HTTP+SSE)
|
|
42
|
+
- Cursor subprocess: `cursor agent <prompt>` (stdout NDJSON, no connection path — subprocess-only)
|
|
43
|
+
- Pi subprocess/connection: `pi rpc --mode rpc` (JSON-RPC stdio; Pi has no subprocess-only path — the RPC mode is the connection)
|
|
42
44
|
|
|
43
45
|
## Bootstrap Sequence Is Load-Bearing
|
|
44
46
|
|
|
@@ -74,7 +76,7 @@ unique — always check `event.harness_id`. `turn/completed` is Codex; OpenCode
|
|
|
74
76
|
- `adapter.py` — `SpawnParams`, `HarnessAdapter`, `HarnessContract` and sub-models.
|
|
75
77
|
Source of truth for what every adapter must implement.
|
|
76
78
|
- `registry.py` — `HarnessRegistry`, `with_defaults()`. The global singleton.
|
|
77
|
-
- `claude.py` / `codex.py` / `opencode.py` — concrete adapter implementations.
|
|
79
|
+
- `claude.py` / `codex.py` / `opencode.py` / `cursor.py` — concrete adapter implementations.
|
|
78
80
|
- `__init__.py` — `HARNESS_EXTENSION_TOUCHPOINTS` and `ensure_bootstrap()`.
|
|
79
81
|
Read before adding a harness — lists every file that must be touched.
|
|
80
82
|
- `semantics.py` — `terminal_outcome()`, `activity_transition()`, `clears_signal()`.
|
|
@@ -66,10 +66,12 @@ def _run_bootstrap() -> None:
|
|
|
66
66
|
# 4) Cross-adapter SpawnParams accounting runs after all registrations.
|
|
67
67
|
from meridian.lib.harness import claude as _claude
|
|
68
68
|
from meridian.lib.harness import codex as _codex
|
|
69
|
+
from meridian.lib.harness import cursor as _cursor
|
|
69
70
|
from meridian.lib.harness import opencode as _opencode
|
|
70
71
|
from meridian.lib.harness import pi as _pi
|
|
71
72
|
|
|
72
73
|
from meridian.lib.harness.projections import project_claude as _project_claude
|
|
74
|
+
from meridian.lib.harness.projections import project_cursor as _project_cursor
|
|
73
75
|
from meridian.lib.harness.projections import (
|
|
74
76
|
project_codex_streaming as _project_codex_streaming,
|
|
75
77
|
)
|
|
@@ -86,6 +88,7 @@ def _run_bootstrap() -> None:
|
|
|
86
88
|
|
|
87
89
|
from meridian.lib.harness.extractors import claude as _claude_extractor
|
|
88
90
|
from meridian.lib.harness.extractors import codex as _codex_extractor
|
|
91
|
+
from meridian.lib.harness.extractors import cursor as _cursor_extractor
|
|
89
92
|
from meridian.lib.harness.extractors import opencode as _opencode_extractor
|
|
90
93
|
from meridian.lib.harness.extractors import pi as _pi_extractor
|
|
91
94
|
|
|
@@ -94,9 +97,11 @@ def _run_bootstrap() -> None:
|
|
|
94
97
|
_bootstrap_imports = (
|
|
95
98
|
_claude,
|
|
96
99
|
_codex,
|
|
100
|
+
_cursor,
|
|
97
101
|
_opencode,
|
|
98
102
|
_pi,
|
|
99
103
|
_project_claude,
|
|
104
|
+
_project_cursor,
|
|
100
105
|
_project_codex_subprocess,
|
|
101
106
|
_project_codex_streaming,
|
|
102
107
|
_project_opencode_subprocess,
|
|
@@ -104,6 +109,7 @@ def _run_bootstrap() -> None:
|
|
|
104
109
|
_project_pi_rpc,
|
|
105
110
|
_claude_extractor,
|
|
106
111
|
_codex_extractor,
|
|
112
|
+
_cursor_extractor,
|
|
107
113
|
_opencode_extractor,
|
|
108
114
|
_pi_extractor,
|
|
109
115
|
)
|
|
@@ -46,8 +46,13 @@ def _empty_env_overrides() -> dict[str, str]:
|
|
|
46
46
|
class ProjectionMode(StrEnum):
|
|
47
47
|
"""How one adapter projects semantic launch content onto harness channels."""
|
|
48
48
|
|
|
49
|
+
# Prompt is written to a temp prompt file and system instructions are
|
|
50
|
+
# appended into that file content before launch.
|
|
49
51
|
PROMPT_FILE_APPEND_SYSTEM = "prompt_file_append_system"
|
|
52
|
+
# Harness accepts structured system/user fields separately.
|
|
50
53
|
SYSTEM_FIELD_WITH_USER_TURN = "system_field_with_user_turn"
|
|
54
|
+
# Prompt is projected as one positional CLI argument.
|
|
55
|
+
POSITIONAL_PROMPT = "positional_prompt"
|
|
51
56
|
|
|
52
57
|
|
|
53
58
|
class RuntimeHitlMode(StrEnum):
|
|
@@ -268,7 +268,12 @@ class ClaudeAdapter(BaseHarnessAdapter[ResolvedLaunchSpec]):
|
|
|
268
268
|
}
|
|
269
269
|
)
|
|
270
270
|
_EXPLICITLY_IGNORED_FIELDS: ClassVar[frozenset[str]] = frozenset(
|
|
271
|
-
{
|
|
271
|
+
{
|
|
272
|
+
"report_output_path",
|
|
273
|
+
"context_from_payload",
|
|
274
|
+
"reference_items",
|
|
275
|
+
"task_cwd",
|
|
276
|
+
}
|
|
272
277
|
)
|
|
273
278
|
|
|
274
279
|
@property
|
|
@@ -279,7 +279,13 @@ class CodexAdapter(BaseHarnessAdapter[ResolvedLaunchSpec]):
|
|
|
279
279
|
}
|
|
280
280
|
)
|
|
281
281
|
_EXPLICITLY_IGNORED_FIELDS: ClassVar[frozenset[str]] = frozenset(
|
|
282
|
-
{
|
|
282
|
+
{
|
|
283
|
+
"skills",
|
|
284
|
+
"agent",
|
|
285
|
+
"context_from_payload",
|
|
286
|
+
"reference_items",
|
|
287
|
+
"task_cwd",
|
|
288
|
+
}
|
|
283
289
|
)
|
|
284
290
|
|
|
285
291
|
@property
|
{meridian_cli-0.2.0 → meridian_cli-0.2.2}/src/meridian/lib/harness/connections/.context/CONTEXT.md
RENAMED
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## Architecture
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Four concrete transports share the `HarnessConnection[SpecT]` ABC from `base.py`:
|
|
6
6
|
|
|
7
7
|
| File | Class | Transport | Protocol |
|
|
8
8
|
|---|---|---|---|
|
|
9
9
|
| `claude_ws.py` | `ClaudeConnection` | stdin/stdout NDJSON | stream-json |
|
|
10
10
|
| `codex_ws.py` | `CodexConnection` | WebSocket | JSON-RPC 2.0 |
|
|
11
11
|
| `opencode_http.py` | `OpenCodeConnection` | HTTP + SSE | REST + event stream |
|
|
12
|
+
| `cursor_subprocess.py` | `CursorSubprocessConnection` | stdout NDJSON (read-only) | stream-json |
|
|
12
13
|
| `pi_rpc.py` | `PiRpcConnection` | stdin/stdout JSONL | JSON-RPC (pi rpc mode) |
|
|
13
14
|
|
|
14
15
|
**`claude_ws.py` is not a WebSocket.** The filename is a historical artifact. The connection
|
|
@@ -72,7 +73,10 @@ event classification table.
|
|
|
72
73
|
Frozen dataclass declared as `_CAPABILITIES` on each concrete class. Set once at class
|
|
73
74
|
definition, not per-instance. Fields:
|
|
74
75
|
|
|
75
|
-
- `mid_turn_injection`: `"queue"` (Claude), `"interrupt_restart"` (Codex), `"http_post"` (OpenCode)
|
|
76
|
+
- `mid_turn_injection`: `"queue"` (Claude), `"interrupt_restart"` (Codex), `"http_post"` (OpenCode),
|
|
77
|
+
`"queue"` (Cursor — **but `send_user_message` always raises**; injection is not implemented
|
|
78
|
+
for MVP. The type does not have an "unsupported" literal, so `"queue"` is used as a
|
|
79
|
+
placeholder. Do not call `send_user_message` on a Cursor connection.)
|
|
76
80
|
- `supports_cancel`, `supports_steer`, `runtime_model_switch`, `structured_reasoning`
|
|
77
81
|
- `supports_primary_observer` — only Codex and OpenCode
|
|
78
82
|
- `supports_runtime_hitl` — runtime HITL through the connection; only Codex
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"""Cursor subprocess transport connection over stdout NDJSON."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import json
|
|
7
|
+
import logging
|
|
8
|
+
import os
|
|
9
|
+
from asyncio.subprocess import DEVNULL, PIPE, Process
|
|
10
|
+
from collections.abc import AsyncIterator
|
|
11
|
+
from contextlib import suppress
|
|
12
|
+
from io import BufferedWriter
|
|
13
|
+
from typing import Final, cast
|
|
14
|
+
|
|
15
|
+
from meridian.lib.core.types import HarnessId, SpawnId
|
|
16
|
+
from meridian.lib.harness.bundle import project_subprocess_spec
|
|
17
|
+
from meridian.lib.harness.connections.base import (
|
|
18
|
+
ConnectionCapabilities,
|
|
19
|
+
ConnectionConfig,
|
|
20
|
+
ConnectionState,
|
|
21
|
+
HarnessConnection,
|
|
22
|
+
HarnessEvent,
|
|
23
|
+
StopProgressCallback,
|
|
24
|
+
StopResult,
|
|
25
|
+
validate_prompt_size,
|
|
26
|
+
)
|
|
27
|
+
from meridian.lib.launch.constants import BASE_COMMAND_CURSOR_SUBPROCESS, BLOCKED_CHILD_ENV_VARS
|
|
28
|
+
from meridian.lib.launch.env import inherit_child_env
|
|
29
|
+
from meridian.lib.launch.launch_types import ResolvedLaunchSpec
|
|
30
|
+
from meridian.lib.state.paths import resolve_spawn_log_dir
|
|
31
|
+
|
|
32
|
+
logger = logging.getLogger(__name__)
|
|
33
|
+
|
|
34
|
+
_HARNESS_NAME: Final[str] = HarnessId.CURSOR.value
|
|
35
|
+
_PROCESS_STOP_TIMEOUT_SECONDS: Final[float] = 10.0
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class CursorSubprocessConnection(HarnessConnection[ResolvedLaunchSpec]):
|
|
39
|
+
"""Subprocess Cursor harness connection over stdout NDJSON."""
|
|
40
|
+
|
|
41
|
+
_CAPABILITIES = ConnectionCapabilities(
|
|
42
|
+
# Literal["queue"|"interrupt_restart"|"http_post"] has no "none"; Cursor is
|
|
43
|
+
# single-turn — send_user_message always raises, so injection is not usable.
|
|
44
|
+
mid_turn_injection="queue",
|
|
45
|
+
supports_steer=False,
|
|
46
|
+
supports_cancel=True,
|
|
47
|
+
runtime_model_switch=False,
|
|
48
|
+
structured_reasoning=False,
|
|
49
|
+
supports_primary_observer=False,
|
|
50
|
+
supports_runtime_hitl=False,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def __init__(self) -> None:
|
|
54
|
+
self._state: ConnectionState = "created"
|
|
55
|
+
self._spawn_id: SpawnId = SpawnId("")
|
|
56
|
+
self._process: Process | None = None
|
|
57
|
+
self._stderr_handle: BufferedWriter | None = None
|
|
58
|
+
self._event_stream_started = False
|
|
59
|
+
self._protocol_validated = False
|
|
60
|
+
self._stop_lock = asyncio.Lock()
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def state(self) -> ConnectionState:
|
|
64
|
+
return self._state
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def harness_id(self) -> HarnessId:
|
|
68
|
+
return HarnessId.CURSOR
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def spawn_id(self) -> SpawnId:
|
|
72
|
+
return self._spawn_id
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def capabilities(self) -> ConnectionCapabilities:
|
|
76
|
+
return self._CAPABILITIES
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def session_id(self) -> str | None:
|
|
80
|
+
return None
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def subprocess_pid(self) -> int | None:
|
|
84
|
+
process = self._process
|
|
85
|
+
if process is None:
|
|
86
|
+
return None
|
|
87
|
+
return process.pid
|
|
88
|
+
|
|
89
|
+
async def start(self, config: ConnectionConfig, spec: ResolvedLaunchSpec) -> None:
|
|
90
|
+
if self._state != "created":
|
|
91
|
+
raise RuntimeError(f"Cannot start Cursor connection from state '{self._state}'")
|
|
92
|
+
|
|
93
|
+
validate_prompt_size(config)
|
|
94
|
+
self._spawn_id = config.spawn_id
|
|
95
|
+
self._set_state("starting")
|
|
96
|
+
|
|
97
|
+
spawn_dir = resolve_spawn_log_dir(config.control_root, config.spawn_id)
|
|
98
|
+
spawn_dir.mkdir(parents=True, exist_ok=True)
|
|
99
|
+
self._stderr_handle = (spawn_dir / "stderr.log").open("ab")
|
|
100
|
+
|
|
101
|
+
command = project_subprocess_spec(
|
|
102
|
+
self.harness_id,
|
|
103
|
+
spec,
|
|
104
|
+
base_command=BASE_COMMAND_CURSOR_SUBPROCESS,
|
|
105
|
+
)
|
|
106
|
+
env = inherit_child_env(
|
|
107
|
+
os.environ,
|
|
108
|
+
config.env_overrides,
|
|
109
|
+
blocked=BLOCKED_CHILD_ENV_VARS,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
self._process = await asyncio.create_subprocess_exec(
|
|
114
|
+
*command,
|
|
115
|
+
cwd=str(config.control_root),
|
|
116
|
+
env=env,
|
|
117
|
+
stdin=DEVNULL,
|
|
118
|
+
stdout=PIPE,
|
|
119
|
+
stderr=self._stderr_handle,
|
|
120
|
+
)
|
|
121
|
+
self._set_state("connected")
|
|
122
|
+
except Exception:
|
|
123
|
+
self._set_state("failed")
|
|
124
|
+
await self._cleanup_resources(terminate_process=True)
|
|
125
|
+
raise
|
|
126
|
+
|
|
127
|
+
async def stop(
|
|
128
|
+
self,
|
|
129
|
+
*,
|
|
130
|
+
reason: str | None = None,
|
|
131
|
+
progress: StopProgressCallback | None = None,
|
|
132
|
+
) -> StopResult:
|
|
133
|
+
_ = reason, progress
|
|
134
|
+
async with self._stop_lock:
|
|
135
|
+
if self._state == "stopped":
|
|
136
|
+
return StopResult()
|
|
137
|
+
if self._state not in {"stopping", "failed"}:
|
|
138
|
+
self._set_state("stopping")
|
|
139
|
+
await self._cleanup_resources(terminate_process=True)
|
|
140
|
+
self._set_state("stopped")
|
|
141
|
+
return StopResult()
|
|
142
|
+
|
|
143
|
+
def health(self) -> bool:
|
|
144
|
+
return self._state == "connected"
|
|
145
|
+
|
|
146
|
+
async def send_user_message(self, text: str) -> None:
|
|
147
|
+
_ = text
|
|
148
|
+
raise RuntimeError(
|
|
149
|
+
"Cursor subprocess transport does not support live user-message injection"
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
async def send_cancel(self) -> None:
|
|
153
|
+
if self._state == "stopped":
|
|
154
|
+
return
|
|
155
|
+
if self._state != "failed":
|
|
156
|
+
self._set_state("stopping")
|
|
157
|
+
await self._terminate_process()
|
|
158
|
+
|
|
159
|
+
async def events(self) -> AsyncIterator[HarnessEvent]:
|
|
160
|
+
process = self._process
|
|
161
|
+
if process is None:
|
|
162
|
+
return
|
|
163
|
+
stdout = process.stdout
|
|
164
|
+
if stdout is None:
|
|
165
|
+
return
|
|
166
|
+
if self._event_stream_started:
|
|
167
|
+
raise RuntimeError("events() iterator already consumed")
|
|
168
|
+
self._event_stream_started = True
|
|
169
|
+
|
|
170
|
+
while True:
|
|
171
|
+
try:
|
|
172
|
+
line_bytes = await stdout.readline()
|
|
173
|
+
except Exception as exc:
|
|
174
|
+
if self._state not in {"stopping", "stopped"}:
|
|
175
|
+
detail = f"Failed to read Cursor stdout: {exc}"
|
|
176
|
+
self._set_state("failed")
|
|
177
|
+
yield self._error_event(detail)
|
|
178
|
+
return
|
|
179
|
+
|
|
180
|
+
if not line_bytes:
|
|
181
|
+
return_code = process.returncode
|
|
182
|
+
if return_code is None:
|
|
183
|
+
return_code = await process.wait()
|
|
184
|
+
if return_code != 0 and self._state not in {"stopping", "stopped"}:
|
|
185
|
+
detail = f"Cursor subprocess exited with code {return_code}."
|
|
186
|
+
self._set_state("failed")
|
|
187
|
+
yield self._error_event(detail)
|
|
188
|
+
return
|
|
189
|
+
|
|
190
|
+
raw_text = line_bytes.decode("utf-8", errors="replace").rstrip("\n")
|
|
191
|
+
if not raw_text.strip():
|
|
192
|
+
continue
|
|
193
|
+
event = self._parse_stdout_line(raw_text)
|
|
194
|
+
if event is None:
|
|
195
|
+
if self._protocol_validated:
|
|
196
|
+
continue
|
|
197
|
+
detail = (
|
|
198
|
+
"Cursor protocol mismatch: expected NDJSON object with non-empty string "
|
|
199
|
+
f"'type', got: {raw_text.strip()!r}"
|
|
200
|
+
)
|
|
201
|
+
self._set_state("failed")
|
|
202
|
+
yield self._error_event(detail, raw_text=raw_text)
|
|
203
|
+
return
|
|
204
|
+
|
|
205
|
+
self._protocol_validated = True
|
|
206
|
+
yield event
|
|
207
|
+
|
|
208
|
+
def _parse_stdout_line(self, raw_text: str) -> HarnessEvent | None:
|
|
209
|
+
payload_text = raw_text.strip()
|
|
210
|
+
if not payload_text:
|
|
211
|
+
return None
|
|
212
|
+
try:
|
|
213
|
+
payload_obj = json.loads(payload_text)
|
|
214
|
+
except json.JSONDecodeError:
|
|
215
|
+
logger.warning("Skipping malformed Cursor stdout line: %s", payload_text)
|
|
216
|
+
return None
|
|
217
|
+
if not isinstance(payload_obj, dict):
|
|
218
|
+
logger.warning("Skipping non-object Cursor stdout line: %s", payload_text)
|
|
219
|
+
return None
|
|
220
|
+
|
|
221
|
+
payload = cast("dict[str, object]", payload_obj)
|
|
222
|
+
raw_event_type = payload.get("type")
|
|
223
|
+
if not isinstance(raw_event_type, str) or not raw_event_type.strip():
|
|
224
|
+
logger.warning(
|
|
225
|
+
"Skipping Cursor stdout line without string 'type': %s",
|
|
226
|
+
payload_text,
|
|
227
|
+
)
|
|
228
|
+
return None
|
|
229
|
+
|
|
230
|
+
return HarnessEvent(
|
|
231
|
+
event_type=raw_event_type,
|
|
232
|
+
payload=payload,
|
|
233
|
+
harness_id=_HARNESS_NAME,
|
|
234
|
+
raw_text=raw_text,
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
def _set_state(self, next_state: ConnectionState) -> None:
|
|
238
|
+
if self._state == next_state:
|
|
239
|
+
return
|
|
240
|
+
self._state = next_state
|
|
241
|
+
|
|
242
|
+
async def _cleanup_resources(self, *, terminate_process: bool) -> None:
|
|
243
|
+
if terminate_process:
|
|
244
|
+
await self._terminate_process()
|
|
245
|
+
if self._stderr_handle is not None:
|
|
246
|
+
self._stderr_handle.close()
|
|
247
|
+
self._stderr_handle = None
|
|
248
|
+
|
|
249
|
+
async def _terminate_process(self) -> None:
|
|
250
|
+
process = self._process
|
|
251
|
+
if process is None:
|
|
252
|
+
return
|
|
253
|
+
if process.returncode is None:
|
|
254
|
+
with suppress(ProcessLookupError):
|
|
255
|
+
process.terminate()
|
|
256
|
+
try:
|
|
257
|
+
await asyncio.wait_for(process.wait(), timeout=_PROCESS_STOP_TIMEOUT_SECONDS)
|
|
258
|
+
except TimeoutError:
|
|
259
|
+
with suppress(ProcessLookupError):
|
|
260
|
+
process.kill()
|
|
261
|
+
await process.wait()
|
|
262
|
+
self._process = None
|
|
263
|
+
|
|
264
|
+
def _error_event(self, message: str, *, raw_text: str | None = None) -> HarnessEvent:
|
|
265
|
+
return HarnessEvent(
|
|
266
|
+
event_type="error/connectionClosed",
|
|
267
|
+
payload={"type": "error", "message": message},
|
|
268
|
+
harness_id=_HARNESS_NAME,
|
|
269
|
+
raw_text=raw_text,
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
__all__ = ["CursorSubprocessConnection"]
|