fix: prevent "Leave Site?" dialog on session pages (#47)

* fix: proxy ttyd through Next.js to fix "Leave Site?" dialog

Changes:
- Add Next.js rewrite to proxy /terminal-proxy/* to ttyd server
- Simplify Terminal component to use same-origin proxy URL
- Remove cross-origin fetch and error handling (no longer needed)

Why:
- Fixes "Leave Site?" confirmation dialog when navigating away from session pages
- Makes ttyd iframe same-origin with Next.js app (eliminates cross-origin restrictions)
- Simplifies architecture (no cross-origin complexity)

Note: This does NOT fix clipboard copying - that's a separate ttyd/xterm.js
limitation where clipboard operations don't work even on the raw ttyd page.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* docs: add development workflow section to CLAUDE.md

Explains:
- Build packages before running dev server (web depends on built core/plugins)
- Config file requirement (agent-orchestrator.yaml)
- Worktree-specific setup steps

This prevents the "Module not found: @composio/ao-core" error when starting
the dev server without building packages first.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: add sandbox attribute to terminal iframe to prevent "Leave Site?" dialog

Added sandbox="allow-scripts allow-same-origin allow-forms" to the terminal
iframe. This prevents the iframe's beforeunload handler from triggering a
"Leave Site?" confirmation dialog when navigating away from session pages.

The sandbox attribute restricts the iframe's ability to block navigation
while still allowing:
- Scripts (for xterm.js and WebSocket)
- Same-origin access (for terminal functionality)
- Forms (for terminal input)

Note: Clipboard copying behavior is inconsistent across sessions (works on
some but not others). This appears to be a ttyd/xterm.js limitation and is
tracked separately.

Fixes the "Leave Site?" popup reported in the issue.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore: remove unused proxy rewrite from next.config.js

The proxy approach was attempted but reverted in favor of the simpler
sandbox attribute solution.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: add allow-popups to sandbox for clipboard support

Some clipboard operations in browsers use popups internally. Adding
allow-popups to the sandbox attribute may help with clipboard copying.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore: minor formatting cleanup in SessionDetail.tsx

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
prateek 2026-02-15 19:39:53 +05:30 committed by GitHub
parent 7ce8dc3480
commit 2a3723be48
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 41 additions and 0 deletions

View File

@ -143,6 +143,45 @@ pnpm test # run tests
pnpm lint && pnpm typecheck
```
## Development Workflow
### Running the Dev Server
**IMPORTANT**: The web dashboard depends on built packages. Always build before running dev server.
```bash
# 1. Install dependencies (first time only)
pnpm install
# 2. Build all packages (required before dev server)
pnpm build
# 3. Ensure config exists
# Copy agent-orchestrator.yaml.example to agent-orchestrator.yaml and configure
cp agent-orchestrator.yaml.example agent-orchestrator.yaml
# 4. Run the dev server
cd packages/web
pnpm dev
```
**Why build first?** The web package imports from `@composio/ao-core` and plugin packages. These must be built (TypeScript compiled to JavaScript) before Next.js can resolve them.
**Config requirement**: The app expects `agent-orchestrator.yaml` in the working directory. Without it, all API routes will fail with "No agent-orchestrator.yaml found".
### Working with Worktrees
If using git worktrees (common for parallel agent work):
```bash
# After creating a worktree
cd /path/to/worktree
pnpm install # Install deps
pnpm build # Build packages
cp /path/to/main/agent-orchestrator.yaml . # Copy config
cd packages/web && pnpm dev # Start server
```
## Common Mistakes to Avoid
- Using `exec` instead of `execFile` — security vulnerability

View File

@ -235,6 +235,7 @@ export function SessionDetail({ session }: SessionDetailProps) {
<h3 className="mb-3 text-[13px] font-semibold uppercase tracking-widest text-[var(--color-text-muted)]">
Terminal
</h3>
<Terminal sessionId={session.id} />
</div>
</div>

View File

@ -80,6 +80,7 @@ export function Terminal({ sessionId }: TerminalProps) {
className="h-full w-full border-0"
title={`Terminal: ${sessionId}`}
allow="clipboard-read; clipboard-write"
sandbox="allow-scripts allow-same-origin allow-forms allow-popups"
/>
) : (
<div className="flex h-full items-center justify-center text-sm text-[var(--color-text-muted)]">