feat(v3): agent preview terminal — read-only xterm.js tracking agent activity
This commit is contained in:
parent
975f03e75d
commit
90c1fb94e2
4 changed files with 245 additions and 9 deletions
|
|
@ -74,7 +74,7 @@
|
|||
</div>
|
||||
|
||||
<div class="project-terminal-area">
|
||||
<TerminalTabs {project} />
|
||||
<TerminalTabs {project} agentSessionId={mainSessionId} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@
|
|||
type TerminalTab,
|
||||
} from '../../stores/workspace.svelte';
|
||||
import TerminalPane from '../Terminal/TerminalPane.svelte';
|
||||
import AgentPreviewPane from '../Terminal/AgentPreviewPane.svelte';
|
||||
|
||||
interface Props {
|
||||
project: ProjectConfig;
|
||||
agentSessionId?: string | null;
|
||||
}
|
||||
|
||||
let { project }: Props = $props();
|
||||
let { project, agentSessionId }: Props = $props();
|
||||
|
||||
let tabs = $derived(getTerminalTabs(project.id));
|
||||
let activeTabId = $state<string | null>(null);
|
||||
|
|
@ -38,6 +40,26 @@
|
|||
activeTabId = id;
|
||||
}
|
||||
|
||||
function addAgentPreviewTab() {
|
||||
if (!agentSessionId) return;
|
||||
// Don't create duplicate — check if one already exists for this session
|
||||
const existing = tabs.find(
|
||||
t => t.type === 'agent-preview' && t.agentSessionId === agentSessionId,
|
||||
);
|
||||
if (existing) {
|
||||
activeTabId = existing.id;
|
||||
return;
|
||||
}
|
||||
const id = crypto.randomUUID();
|
||||
addTerminalTab(project.id, {
|
||||
id,
|
||||
title: 'Agent Preview',
|
||||
type: 'agent-preview',
|
||||
agentSessionId,
|
||||
});
|
||||
activeTabId = id;
|
||||
}
|
||||
|
||||
function closeTab(tabId: string) {
|
||||
removeTerminalTab(project.id, tabId);
|
||||
}
|
||||
|
|
@ -66,18 +88,29 @@
|
|||
>×</button>
|
||||
</div>
|
||||
{/each}
|
||||
<button class="tab-add" onclick={addShellTab} title="New shell (Ctrl+N)">+</button>
|
||||
<button class="tab-add" onclick={addShellTab} title="New shell">+</button>
|
||||
{#if agentSessionId}
|
||||
<button
|
||||
class="tab-add tab-agent-preview"
|
||||
onclick={addAgentPreviewTab}
|
||||
title="Watch agent activity"
|
||||
>👁</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="tab-content">
|
||||
{#each tabs as tab (tab.id)}
|
||||
<div class="tab-pane" class:visible={activeTabId === tab.id}>
|
||||
{#if activeTabId === tab.id}
|
||||
<TerminalPane
|
||||
cwd={project.cwd}
|
||||
shell={tab.type === 'ssh' ? '/usr/bin/ssh' : undefined}
|
||||
onExit={() => handleTabExit(tab.id)}
|
||||
/>
|
||||
{#if tab.type === 'agent-preview' && tab.agentSessionId}
|
||||
<AgentPreviewPane sessionId={tab.agentSessionId} />
|
||||
{:else}
|
||||
<TerminalPane
|
||||
cwd={project.cwd}
|
||||
shell={tab.type === 'ssh' ? '/usr/bin/ssh' : undefined}
|
||||
onExit={() => handleTabExit(tab.id)}
|
||||
/>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
|
|
@ -171,6 +204,10 @@
|
|||
background: var(--ctp-surface0);
|
||||
}
|
||||
|
||||
.tab-agent-preview {
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue