Skip to content

[TASK] Finish sandbox-terminal deduplication and settle panel ownership #119

Description

@vutuanlinh2k2

Summary

The shared sandbox-terminal transport is already in place. agent-app owns the same-origin connection, runtime-proxy, WebSocket-upgrade, terminal-token, connection-hook, per-tab connection-id, and terminal-panel mechanisms. Creative Agent and GTM Agent both use the shared transport.

The remaining work is narrower:

  1. retire the duplicated per-tab connection-id helpers in both apps; and
  2. settle whether the full terminal panel is shared shell UI or product-owned chrome.

This is a standalone sandbox-terminal cleanup. It is not part of the chat/vault vertical.

Current state

Complete

  • tabTerminalConnectionId is exported from @tangle-network/agent-app/web-react.
  • WorkspaceTerminalPanel is exported from the sandbox-specific @tangle-network/agent-app/web-react/terminal entrypoint.
  • Creative Agent uses the shared connection handler, runtime proxy, WebSocket-upgrade handler, and useSandboxTerminalConnection.
  • GTM Agent migrated from browser-direct sidecar access to the shared same-origin terminal seam in tangle-network/gtm-agent#347.
  • GTM passes a stable per-tab connectionId, so the original normal-browser multi-tab eviction bug is fixed.

Still duplicated

Creative Agent and GTM Agent each still define their own:

  • tabTerminalConnectionId
  • lazy TerminalView wiring
  • WorkspaceTerminalPanel UI

The local connection-id helpers also have a weaker fallback: if sessionStorage is unavailable, they derive a deterministic ID from the sandbox ID. Separate clients can therefore still collide in that edge case. The shared helper returns a unique ephemeral ID instead.

Remaining work

1. Adopt the shared connection-id helper

  • Creative Agent imports tabTerminalConnectionId instead of defining it locally.

  • GTM Agent imports tabTerminalConnectionId instead of defining it locally.

  • Both apps preserve per-sandbox reload behavior by supplying a sandbox-specific storage key, for example:

    tabTerminalConnectionId(`terminal-conn:${sandboxId}`)
  • Existing same-tab reload persistence and cross-tab/client isolation remain covered.

2. Decide and implement the terminal-panel ownership boundary

The current shared WorkspaceTerminalPanel is not a behavior-preserving drop-in for either app:

  • Creative Agent has product-specific icon, badge, button, connected-state actions, empty-state copy, and full-bleed container treatment.
  • GTM Agent additionally uses its product-owned WorkspacePageHeader.
  • The shared panel has a fixed internal header and empty state. headerExtra can append content, but cannot replace those regions.

Choose one direction:

A. Shared shell panel

Make the shared terminal surface adoptable without forcing product UI changes. Prefer a narrow mechanism boundary or additive render/slot seams for product-owned header, empty state, actions, and container chrome. Then migrate both apps and delete their duplicated terminal mechanics.

B. Product-owned panel chrome

Keep each app's header, empty state, and surrounding layout local. Document the boundary explicitly: agent-app owns terminal connection/session mechanism, while products own panel presentation. In this direction, do not require consumers to adopt the full shared panel merely for deduplication.

Whichever direction is chosen:

  • Creative Agent preserves its current terminal behavior and presentation.
  • GTM Agent preserves WorkspacePageHeader and its current terminal behavior.
  • Shared mechanism is not reimplemented in either product.
  • The chosen ownership boundary is documented in agent-app.

Non-goals

  • A combined createWorkspaceSandboxTerminal(deps) factory. The three existing handlers already share the important mechanism, while the apps have different provisioning/credential seams and GTM has additional WebSocket-subprotocol response handling.
  • Changes to sandbox provisioning, SandboxRuntimeConfig, auth trusted origins, tool installation, or product-specific layout mounting.
  • Changes to terminal transport or token architecture; those migrations are complete.

References

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status
Not Started 🕧

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions