feat(cli,host-service): single-host reads with explicit host targeting

Merged
SA
4mo ago
+732-817

What

Local-first follow-up (supersedes the planned "fan out automations + CLI project reads" work): instead of adding org-wide fan-out to the CLI, projects and workspaces are treated as strictly host-owned. Every CLI read targets exactly one host — --host <id> when given, else this machine — and every write requires an explicit host or derives it from the targeted resource. The desktop remains the cross-host view.

Changes

host-service

  • workspace.list joins in projectName, so consumers never stitch project names from a second query. Rows for orphaned projectIds serve null.

CLI — reads

  • projects list / workspaces list are now plain single-host tRPC queries (HOST/HOSTS columns dropped; --project filter matches the row's id or host-served name).
  • workspaces get/open look up the id on the target host and error with a --host hint instead of searching the org.

CLI — writes

  • projects setup now requires --host/--local (previously a silent this-machine default), matching projects create / workspaces create.
  • resolveHostTarget.requestedHostId is now required — the hidden "undefined means local" fallback is gone; every caller states its host.
  • workspaces update/delete, agents create, terminals create take --host (default: this machine).

CLI — automations

  • automations create/update resolve targetHostId + v2ProjectId through a single resolveAutomationTarget: the --workspace/--project must exist on the target host or the command throws. The CLI always writes a concrete targetHostId, so cloud dispatch's "owner's most recent online host" fallback is legacy-rows-only now.
  • "Pin" terminology is removed from the CLI.

Behavior changes to be aware of

  • Unscoped workspaces list / projects list now show this machine only (previously merged all reachable org hosts).
  • Workspace-id commands no longer locate the workspace across the org — pass --host for remote hosts.
  • workspaces list --project <unknown-name> returns an empty list instead of erroring.

Follow-ups (not in this PR)

  • @superset/sdk (resources/host-workspaces.ts) still has its own org-wide fan-out; per the SDK-mirrors-CLI rule it should adopt the same single-host semantics — breaking public API change, needs its own PR. Same for MCP-v2.
  • Cloud side: make automations.targetHostId required in the mutation schema and retire the dispatch-time host fallback; purge "pin" language from dispatch.ts/desktop.
  • automations update <id> --host X alone still repoints without validating the automation's existing project/workspace exists on X.

Testing

  • bun run lint clean, tsc --noEmit clean for packages/cli and packages/host-service
  • bun test in packages/cli: 35/35 (workspaces get suite updated for the new single-host contract)

https://claude.ai/code/session_01XvFLHZHLKBKCo1tKgZFUqd


Summary by cubic

Make projects and workspaces single-host across the CLI, @superset/sdk, and mcp-v2. All reads target one host (CLI defaults to this machine); all writes require an explicit host or derive it from the resource. Docs and samples updated; tool descriptions tightened.

  • New Features

    • host-service: workspace.list now includes projectName (or null if orphaned).
    • CLI: projects list and workspaces list query a single host with simplified columns; --project accepts id or host-served name. workspaces get/open/update/delete, agents create, and terminals create take --host (default: this machine). projects setup requires --host/--local. resolveHostTarget now requires a concrete host id. automations create/update persist concrete targetHostId + v2ProjectId via resolveAutomationTarget; the target resource must exist on that host; “pin” terminology removed. Added hosts start --org.
    • @superset/sdk: host-explicit APIs. projects.list({ hostId }) reads a host’s project.list; workspaces.list({ hostId }), workspaces.update(id, …, { hostId }), workspaces.delete(id, { hostId }), agents.create({ hostId, … }), and terminals.create({ hostId, … }) all target a specific host. Workspace rows include projectName. Samples now guard empty host lists.
    • mcp-v2: tools call the named host directly. projects_list({ hostId })/workspaces_list({ hostId }) read from that host; agents_create, terminals_create, workspaces_update, and workspaces_delete require hostId and mutate the host. workspaces_update now requires name. Tool docs tightened (e.g., tasks_delete is soft delete).
  • Migration

    • CLI reads show only the target host; pass --host <id> for remote hosts.
    • Workspace-id commands no longer locate across the org; pass --host.
    • projects setup requires --host/--local.
    • workspaces list --project <unknown-name> returns an empty list instead of erroring.
    • @superset/sdk: pass a hostId to projects.list, workspaces.list/update/delete, agents.create, and terminals.create. The host-workspaces fan-out helpers are removed.
    • mcp-v2: pass hostId to projects_list, workspaces_list, agents_create, terminals_create, and workspaces_update/delete; workspaces_update requires name.

Summary by CodeRabbit

  • New Features
    • Added/expanded --host support across workspace, agent-session, terminal, automation, and project CLI commands; host-scoped defaults now target this machine.
    • SDK/MCP operations now require an explicit hostId input for host-owned actions (workspace/agents/terminals/projects tools).
  • Bug Fixes
    • Improved host-specific “not found” errors and stricter automation target validation, including clearer guidance when no active organization exists.
  • Documentation
    • Updated CLI/SDK/MCP docs to reflect host-scoped listing/output changes (e.g., projects list and workspaces list schemas/filters) and revised MCP tool descriptions.