fix(commands): keep tasks local-only remotely
This commit is contained in:
@@ -2354,7 +2354,15 @@ def create_default_command_registry(
|
||||
registry.register(SlashCommand("upgrade", "Show upgrade instructions", _upgrade_handler))
|
||||
registry.register(SlashCommand("agents", "List or inspect agent and teammate tasks", _agents_handler))
|
||||
registry.register(SlashCommand("subagents", "Show subagent usage and inspect worker tasks", _agents_handler))
|
||||
registry.register(SlashCommand("tasks", "Manage background tasks", _tasks_handler))
|
||||
registry.register(
|
||||
SlashCommand(
|
||||
"tasks",
|
||||
"Manage background tasks",
|
||||
_tasks_handler,
|
||||
remote_invocable=False,
|
||||
remote_admin_opt_in=True,
|
||||
)
|
||||
)
|
||||
registry.register(SlashCommand("autopilot", "Manage repo autopilot intake and context", _autopilot_handler))
|
||||
registry.register(
|
||||
SlashCommand(
|
||||
|
||||
@@ -161,6 +161,23 @@ async def test_bridge_command_supports_explicit_remote_admin_opt_in(tmp_path: Pa
|
||||
assert getattr(command, "remote_admin_opt_in", False) is True
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_tasks_command_is_marked_local_only(tmp_path: Path, monkeypatch):
|
||||
monkeypatch.setenv("OPENHARNESS_CONFIG_DIR", str(tmp_path / "config"))
|
||||
registry = create_default_command_registry()
|
||||
command, _ = registry.lookup("/tasks run id")
|
||||
assert command is not None
|
||||
assert command.remote_invocable is False
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_tasks_command_supports_explicit_remote_admin_opt_in(tmp_path: Path, monkeypatch):
|
||||
monkeypatch.setenv("OPENHARNESS_CONFIG_DIR", str(tmp_path / "config"))
|
||||
registry = create_default_command_registry()
|
||||
command, _ = registry.lookup("/tasks run id")
|
||||
assert command is not None
|
||||
assert getattr(command, "remote_admin_opt_in", False) is True
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_sensitive_control_plane_commands_are_local_only(tmp_path: Path, monkeypatch):
|
||||
|
||||
@@ -28,6 +28,7 @@ from openharness.engine.stream_events import (
|
||||
from openharness.memory import add_memory_entry as add_project_memory_entry
|
||||
from openharness.memory import list_memory_files as list_project_memory_files
|
||||
from openharness.permissions import PermissionChecker, PermissionMode
|
||||
from openharness.tasks.manager import get_task_manager
|
||||
from openharness.tools.base import ToolExecutionContext, ToolRegistry
|
||||
|
||||
from ohmo.gateway.bridge import OhmoGatewayBridge, _format_gateway_error
|
||||
@@ -754,6 +755,61 @@ async def test_runtime_pool_blocks_registered_bridge_spawn_without_shelling_out(
|
||||
assert marker.exists() is False
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_runtime_pool_blocks_registered_tasks_run_without_shelling_out(tmp_path, monkeypatch):
|
||||
workspace = tmp_path / ".ohmo-home"
|
||||
initialize_workspace(workspace)
|
||||
marker = tmp_path / "remote-tasks-marker.txt"
|
||||
payload = f"/tasks run printf REMOTE_TASKS_EXEC > {marker}"
|
||||
registry = create_default_command_registry()
|
||||
command, _ = registry.lookup(payload)
|
||||
existing_tasks = {task.id for task in get_task_manager().list_tasks()}
|
||||
|
||||
assert command is not None
|
||||
assert command.name == "tasks"
|
||||
assert command.remote_invocable is False
|
||||
|
||||
async def fake_build_runtime(**kwargs):
|
||||
class FakeEngine:
|
||||
messages = []
|
||||
total_usage = UsageSnapshot()
|
||||
|
||||
def set_system_prompt(self, prompt):
|
||||
return None
|
||||
|
||||
return SimpleNamespace(
|
||||
engine=FakeEngine(),
|
||||
cwd=str(tmp_path),
|
||||
session_id="sess123",
|
||||
current_settings=lambda: SimpleNamespace(model="gpt-5.4"),
|
||||
commands=registry,
|
||||
tool_registry=None,
|
||||
app_state=None,
|
||||
session_backend=None,
|
||||
extra_skill_dirs=(),
|
||||
extra_plugin_roots=(),
|
||||
hook_summary=lambda: "",
|
||||
mcp_summary=lambda: "",
|
||||
plugin_summary=lambda: "",
|
||||
)
|
||||
|
||||
async def fake_start_runtime(bundle):
|
||||
return None
|
||||
|
||||
monkeypatch.setenv("OPENHARNESS_CONFIG_DIR", str(tmp_path / "config"))
|
||||
monkeypatch.setenv("OPENHARNESS_DATA_DIR", str(tmp_path / "data"))
|
||||
monkeypatch.setattr("ohmo.gateway.runtime.build_runtime", fake_build_runtime)
|
||||
monkeypatch.setattr("ohmo.gateway.runtime.start_runtime", fake_start_runtime)
|
||||
|
||||
pool = OhmoSessionRuntimePool(cwd=tmp_path, workspace=workspace, provider_profile="codex")
|
||||
message = InboundMessage(channel="feishu", sender_id="u1", chat_id="c1", content=payload)
|
||||
updates = [u async for u in pool.stream_message(message, "feishu:c1")]
|
||||
|
||||
assert updates[-1].kind == "final"
|
||||
assert updates[-1].text == "/tasks is only available in the local OpenHarness UI."
|
||||
assert {task.id for task in get_task_manager().list_tasks()} == existing_tasks
|
||||
assert marker.exists() is False
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_runtime_pool_blocks_registered_config_show_without_leaking_secrets(tmp_path, monkeypatch):
|
||||
|
||||
Reference in New Issue
Block a user