Skip to content

[codex] add web terminal presets#4653

Merged
saddlepaddle merged 1 commit into
mainfrom
universal-cough
May 16, 2026
Merged

[codex] add web terminal presets#4653
saddlepaddle merged 1 commit into
mainfrom
universal-cough

Conversation

@saddlepaddle
Copy link
Copy Markdown
Collaborator

@saddlepaddle saddlepaddle commented May 16, 2026

Summary

  • Add a web terminal preset bar backed by host agent configs, including the shared preset SVG icons used by desktop.
  • Let web terminal creation pass an initial command so preset clicks launch the selected terminal agent.
  • Write NEXT_PUBLIC_RELAY_URL from the workspace setup script alongside RELAY_URL so browser host-service calls use the allocated relay port.

Validation

  • bun --filter @superset/web typecheck
  • bun run lint
  • npx -y react-doctor@latest . --verbose --diff (98/100; remaining warnings are existing metadata/useReducer/state-shape suggestions on the page)

Open in Stage

Summary by cubic

Adds a web terminal presets bar powered by host agent configs, letting users launch a preconfigured terminal in one click. Also enables browser host-service calls via NEXT_PUBLIC_RELAY_URL so the relay port is used correctly.

  • New Features

    • Presets bar with shared SVG icons, loading state, and disabled/running states.
    • Terminal creation accepts an initial command; clicking a preset builds the agent launch command and opens a terminal.
    • Host client: settings.agentConfigs.list to fetch presets and a helper to build the launch command; supports GET requests without input.
    • Adds svg.d.ts to allow importing preset SVGs.
  • Migration

    • Re-run the workspace setup to write NEXT_PUBLIC_RELAY_URL to the environment and restart the web app.

Written for commit f9d0e16. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • New Features

    • Added a terminal presets bar above the terminal area, allowing users to quickly launch predefined terminal configurations.
    • Terminal presets can now be executed with a single click, automatically creating new terminal sessions.
    • Improved terminal selection logic to better manage active terminal sessions.
  • Bug Fixes

    • Enhanced error handling and messaging during terminal operations.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bff90ecd-58f2-476d-84cb-6ced34af1e92

📥 Commits

Reviewing files that changed from the base of the PR and between 8dea9a6 and f9d0e16.

📒 Files selected for processing (6)
  • .superset/lib/setup/steps.sh
  • apps/web/src/app/workspaces/[workspaceId]/components/WebTerminalPresetsBar/WebTerminalPresetsBar.tsx
  • apps/web/src/app/workspaces/[workspaceId]/components/WebTerminalPresetsBar/index.ts
  • apps/web/src/app/workspaces/[workspaceId]/page.tsx
  • apps/web/src/trpc/host-client.ts
  • apps/web/src/types/svg.d.ts

📝 Walkthrough

Walkthrough

This PR adds host agent preset configuration and terminal launching. A new WebTerminalPresetsBar component displays available presets as clickable buttons. Users can click a preset to create and run a terminal with a preset-defined initial command. The workspace page now loads presets concurrently with terminal sessions and manages preset running state.

Changes

Preset terminal launcher integration

Layer / File(s) Summary
Host client preset APIs and terminal options
apps/web/src/trpc/host-client.ts
Adds HostAgentConfig interface and listHostAgentConfigs() to fetch presets. Updates createHostTerminal() to accept optional initialCommand via options. Adds buildHostAgentLaunchCommand() helper to construct shell-ready commands. Updates hostCall to conditionally serialize input when present. Updates HostTerminalSession to include title: string | null.
WebTerminalPresetsBar component
apps/web/src/types/svg.d.ts, apps/web/src/app/workspaces/[workspaceId]/components/WebTerminalPresetsBar/WebTerminalPresetsBar.tsx, apps/web/src/app/workspaces/[workspaceId]/components/WebTerminalPresetsBar/index.ts
New client component that renders preset buttons with icons and labels. Shows loading spinner while fetching, renders nothing if presets list is empty. Each button displays icon (or fallback Terminal icon), preset label, and runs the preset on click. Includes SVG module type declaration for proper icon importing.
Workspace page preset integration
apps/web/src/app/workspaces/[workspaceId]/page.tsx
Loads preset configs alongside terminal sessions using Promise.allSettled. Adds presets and runningPresetId state. Computes activeTerminalId to prefer selected non-exited terminals. Implements runPreset callback that creates a terminal with preset-derived initial command and tracks running state. Wires WebTerminalPresetsBar with loaded presets. Refactors error handling to use shared getErrorMessage helper across loading and creation flows.
Environment setup
.superset/lib/setup/steps.sh
Writes NEXT_PUBLIC_RELAY_URL=http://localhost:$RELAY_PORT during workspace .env generation.

Sequence Diagrams

sequenceDiagram
  participant WorkspacePage
  participant listHostAgentConfigs
  participant WebTerminalPresetsBar
  participant runPreset
  participant createHostTerminal
  WorkspacePage->>listHostAgentConfigs: Fetch presets on mount
  listHostAgentConfigs-->>WorkspacePage: HostAgentConfig[]
  WorkspacePage->>WebTerminalPresetsBar: Render with presets, runningPresetId
  WebTerminalPresetsBar-->>WorkspacePage: onRunPreset(preset)
  WorkspacePage->>runPreset: User clicks preset button
  runPreset->>runPreset: buildHostAgentLaunchCommand(preset)
  runPreset->>createHostTerminal: Create terminal with initialCommand
  createHostTerminal-->>runPreset: HostTerminalSession
  runPreset->>WorkspacePage: Update activeTerminalId, clear runningPresetId
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • superset-sh/superset#4647: Establishes the relay host-client and WebSocket setup that this PR extends with preset configs and terminal launching capabilities.

Poem

🐰 A rabbit hops through preset-driven dreams,
Commands launch where terminal sessions gleam,
With buttons clicking, spinners take their turn,
Presets spring to life as workers learn. ✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch universal-cough

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@stage-review
Copy link
Copy Markdown

stage-review Bot commented May 16, 2026

Ready to review this PR? Stage has broken it down into 4 individual chapters for you:

Title
1 Configure environment and type definitions
2 Extend host client for terminal presets
3 Implement WebTerminalPresetsBar component
4 Integrate presets into workspace terminal page
Open in Stage

Chapters generated by Stage for commit f9d0e16 on May 16, 2026 11:55pm UTC.

@saddlepaddle saddlepaddle marked this pull request as ready for review May 16, 2026 23:55
@saddlepaddle saddlepaddle merged commit da7ab94 into main May 16, 2026
10 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 16, 2026

🚀 Preview Deployment

🔗 Preview Links

Service Status Link
Neon Database (Neon) View Branch
Vercel API (Vercel) Open Preview
Vercel Web (Vercel) Open Preview
Vercel Marketing (Vercel) Open Preview
Vercel Admin (Vercel) Open Preview
Vercel Docs (Vercel) Open Preview

Preview updates automatically with new commits

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 6 files

Re-trigger cubic

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 16, 2026

Greptile Summary

This PR adds a web terminal presets bar that fetches host agent configs and lets users launch a preconfigured terminal session in one click. It also fixes the relay URL for browser-side host calls by writing NEXT_PUBLIC_RELAY_URL during workspace setup, and replaces the useEffect-driven terminal selection with a cleaner derived activeTerminalId.

  • Presets bar: WebTerminalPresetsBar renders preset buttons with SVG icons, per-button loading spinners, and a loading skeleton while configs are fetched; presets and terminals are loaded concurrently via Promise.allSettled.
  • Shell command builder: buildHostAgentLaunchCommand single-quotes argv and overlays env vars, but does not incorporate promptArgs/promptTransport from the config — clarify whether those fields are intentionally out of scope for the initial launch.
  • Settings button: The "Manage presets" gear icon button in the bar renders as interactive but has no onClick handler attached.

Confidence Score: 4/5

Safe to merge; the shell-quoting helpers and state management changes are correct, with two areas that need clarification or a quick follow-up.

The core plumbing — relay URL, parallel preset/terminal loading, derived active terminal, and per-preset launch — is sound. Two items warrant attention: the Settings gear button is visually interactive but wired to nothing, and buildHostAgentLaunchCommand silently ignores promptArgs/promptTransport, which may be intentional but could also mean presets launch the agent binary without the expected initial prompt.

apps/web/src/trpc/host-client.ts (promptArgs unused) and apps/web/src/app/workspaces/[workspaceId]/components/WebTerminalPresetsBar/WebTerminalPresetsBar.tsx (Settings button no-op)

Important Files Changed

Filename Overview
apps/web/src/trpc/host-client.ts Adds listHostAgentConfigs, extends createHostTerminal with initialCommand, and introduces shell-quoting helpers. The env key in envOverlayPrefix is unvalidated, and promptArgs/promptTransport go unused in buildHostAgentLaunchCommand.
apps/web/src/app/workspaces/[workspaceId]/page.tsx Adds preset loading alongside terminals via Promise.allSettled, runPreset callback, and replaces the useEffect-driven selectedTerminalId with a derived activeTerminalId. Logic is sound with proper error handling.
apps/web/src/app/workspaces/[workspaceId]/components/WebTerminalPresetsBar/WebTerminalPresetsBar.tsx New preset bar component with loading state, per-preset spinner, and icon rendering. The Manage Presets Settings button has no onClick handler and silently does nothing.
.superset/lib/setup/steps.sh Adds NEXT_PUBLIC_RELAY_URL alongside existing RELAY_URL so the web app can reach the relay from the browser.
apps/web/src/types/svg.d.ts Adds a module declaration for SVG imports, returning a string (URL), enabling preset icons to be imported.

Sequence Diagram

sequenceDiagram
    participant Page as WorkspaceTerminalPage
    participant HC as host-client.ts
    participant Relay as Relay / Host Service
    participant Bar as WebTerminalPresetsBar

    Page->>HC: listHostAgentConfigs(key) [parallel]
    Page->>HC: listHostTerminals(key, workspaceId) [parallel]
    HC->>Relay: "GET /hosts/{key}/trpc/settings.agentConfigs.list"
    HC->>Relay: "GET /hosts/{key}/trpc/terminal.listSessions"
    Relay-->>HC: HostAgentConfig[]
    Relay-->>HC: HostTerminalSession[]
    HC-->>Page: presets / terminals
    Page->>Bar: render(presets, runningPresetId)

    Bar->>Page: onRunPreset(preset)
    Page->>HC: buildHostAgentLaunchCommand(preset)
    HC-->>Page: shell string (env + argv)
    Page->>HC: "createHostTerminal(key, workspaceId, {initialCommand})"
    HC->>Relay: "POST /hosts/{key}/trpc/terminal.createSession"
    Relay-->>HC: "{terminalId, status}"
    HC-->>Page: created terminal
    Page->>Page: setSelectedTerminalId(created.terminalId)
    Page->>Bar: "runningPresetId = null"
Loading
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
apps/web/src/app/workspaces/[workspaceId]/components/WebTerminalPresetsBar/WebTerminalPresetsBar.tsx:45-52
**Settings button is a no-op** — the "Manage presets" button renders with hover styling and an `aria-label`, giving users the impression it's actionable, but it has no `onClick` handler attached. Clicking it silently does nothing, which is confusing UX. Either wire it up to a handler or render it as `disabled` / remove it until the feature is ready.

### Issue 2 of 3
apps/web/src/trpc/host-client.ts:113-118
**Env variable keys are not shell-safe**`envOverlayPrefix` interpolates the key directly into the shell assignment string (`${key}=…`) without quoting or validation. A key containing a space, `=`, or other shell metacharacter (e.g. `"FOO=BAR BAZ"`) would silently corrupt the generated command or, if the config data were ever untrusted, allow injection of additional assignments or arguments. Standard env-var names (letters, digits, underscore) are safe in practice, but an explicit validation (`/^[A-Za-z_][A-Za-z0-9_]*$/`) would make this defensive and prevent silent breakage from unexpected config values.

### Issue 3 of 3
apps/web/src/trpc/host-client.ts:120-129
**`promptArgs` and `promptTransport` are never used in the launch command**`HostAgentConfig` exposes `promptTransport: "argv" | "stdin"` and `promptArgs: string[]`, but `buildHostAgentLaunchCommand` only concatenates `command` + `args` + `env`. If the host agent needs an initial prompt injected (e.g. via `promptArgs` appended when `promptTransport === "argv"`), the preset will launch the agent binary but not pass it any prompt, leaving it waiting for user input rather than executing a preset task.

Reviews (1): Last reviewed commit: "add web terminal presets" | Re-trigger Greptile

Comment on lines +45 to +52
<button
type="button"
title="Manage presets"
aria-label="Manage presets"
className="flex size-6 shrink-0 items-center justify-center rounded-md text-[#8f8983] transition-colors hover:bg-[#211d1b] hover:text-[#f3f0ed]"
>
<Settings className="size-4" />
</button>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Settings button is a no-op — the "Manage presets" button renders with hover styling and an aria-label, giving users the impression it's actionable, but it has no onClick handler attached. Clicking it silently does nothing, which is confusing UX. Either wire it up to a handler or render it as disabled / remove it until the feature is ready.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/src/app/workspaces/[workspaceId]/components/WebTerminalPresetsBar/WebTerminalPresetsBar.tsx
Line: 45-52

Comment:
**Settings button is a no-op** — the "Manage presets" button renders with hover styling and an `aria-label`, giving users the impression it's actionable, but it has no `onClick` handler attached. Clicking it silently does nothing, which is confusing UX. Either wire it up to a handler or render it as `disabled` / remove it until the feature is ready.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +113 to +118
function envOverlayPrefix(env: Record<string, string>): string {
const assignments = Object.entries(env).map(
([key, value]) => `${key}=${quoteSingleShell(value)}`,
);
return assignments.length > 0 ? `${assignments.join(" ")} ` : "";
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Env variable keys are not shell-safeenvOverlayPrefix interpolates the key directly into the shell assignment string (${key}=…) without quoting or validation. A key containing a space, =, or other shell metacharacter (e.g. "FOO=BAR BAZ") would silently corrupt the generated command or, if the config data were ever untrusted, allow injection of additional assignments or arguments. Standard env-var names (letters, digits, underscore) are safe in practice, but an explicit validation (/^[A-Za-z_][A-Za-z0-9_]*$/) would make this defensive and prevent silent breakage from unexpected config values.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/src/trpc/host-client.ts
Line: 113-118

Comment:
**Env variable keys are not shell-safe**`envOverlayPrefix` interpolates the key directly into the shell assignment string (`${key}=…`) without quoting or validation. A key containing a space, `=`, or other shell metacharacter (e.g. `"FOO=BAR BAZ"`) would silently corrupt the generated command or, if the config data were ever untrusted, allow injection of additional assignments or arguments. Standard env-var names (letters, digits, underscore) are safe in practice, but an explicit validation (`/^[A-Za-z_][A-Za-z0-9_]*$/`) would make this defensive and prevent silent breakage from unexpected config values.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +120 to +129
export function buildHostAgentLaunchCommand(config: {
command: string;
args: string[];
env: Record<string, string>;
}) {
return `${envOverlayPrefix(config.env)}${buildArgvCommand([
config.command,
...config.args,
])}`;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 promptArgs and promptTransport are never used in the launch commandHostAgentConfig exposes promptTransport: "argv" | "stdin" and promptArgs: string[], but buildHostAgentLaunchCommand only concatenates command + args + env. If the host agent needs an initial prompt injected (e.g. via promptArgs appended when promptTransport === "argv"), the preset will launch the agent binary but not pass it any prompt, leaving it waiting for user input rather than executing a preset task. Is the intent for presets to only launch the agent binary (and let the user type the prompt), or should the preset also inject the promptArgs? If the latter, promptArgs/promptTransport need to be wired into buildHostAgentLaunchCommand.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/src/trpc/host-client.ts
Line: 120-129

Comment:
**`promptArgs` and `promptTransport` are never used in the launch command**`HostAgentConfig` exposes `promptTransport: "argv" | "stdin"` and `promptArgs: string[]`, but `buildHostAgentLaunchCommand` only concatenates `command` + `args` + `env`. If the host agent needs an initial prompt injected (e.g. via `promptArgs` appended when `promptTransport === "argv"`), the preset will launch the agent binary but not pass it any prompt, leaving it waiting for user input rather than executing a preset task. Is the intent for presets to only launch the agent binary (and let the user type the prompt), or should the preset also inject the promptArgs? If the latter, promptArgs/promptTransport need to be wired into buildHostAgentLaunchCommand.

How can I resolve this? If you propose a fix, please make it concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant