diff --git a/web/src/components/Shell.jsx b/web/src/components/Shell.jsx
index 9c6462b..206dce6 100644
--- a/web/src/components/Shell.jsx
+++ b/web/src/components/Shell.jsx
@@ -6,21 +6,18 @@ import { WebglAddon } from '@xterm/addon-webgl'
import { SearchAddon } from '@xterm/addon-search'
import { Unicode11Addon } from '@xterm/addon-unicode11'
import { ImageAddon } from '@xterm/addon-image'
-import { Plus, X, Monitor, Globe, ChevronDown, Pencil, Trash2, Search, Copy, Send, Eye, Bot, Columns, Rows, Maximize2 } from 'lucide-react'
+import { Plus, X, Monitor, Globe, ChevronDown, Pencil, Trash2, Search, Copy, Send, Eye, Bot } from 'lucide-react'
import '@xterm/xterm/css/xterm.css'
import { useI18n } from '../i18n'
import mermaid from 'mermaid'
-import FileEditor from './FileEditor'
mermaid.initialize({ startOnLoad: false, theme: 'dark', securityLevel: 'loose', fontFamily: 'var(--font-mono)' })
const AI_TAB_ID = 0
const MAX_TABS = 7
-const MAX_PANES = 4
const SHELL_MAX_TOKENS = 100000
const SHELL_AI_COMMANDS = ['/clear', '/help', '/model', '/model change']
const TABS_STORAGE_KEY = 'muyue_shell_tabs'
-const LAYOUT_STORAGE_KEY = 'muyue_shell_layout'
const TERMINAL_BUFFER_KEY = 'muyue_terminal_buffers'
function renderContent(text) {
@@ -480,107 +477,6 @@ export default function Shell({ api, isSudo }) {
const _streamRafRef = useRef(null)
const _streamPendingRef = useRef(null)
- const [splitLayout, setSplitLayout] = useState(() => {
- try {
- const raw = localStorage.getItem(LAYOUT_STORAGE_KEY)
- if (raw) return JSON.parse(raw)
- } catch {}
- return null
- })
- const [editingFile, setEditingFile] = useState(null)
- const [agentSessions, setAgentSessions] = useState([])
-
- const paneCount = useMemo(() => {
- const count = (node) => {
- if (!node) return 1
- if (node.type === 'leaf') return 1
- return count(node.children?.[0]) + count(node.children?.[1])
- }
- return count(splitLayout)
- }, [splitLayout])
-
- const splitPane = useCallback((direction) => {
- if (paneCount >= MAX_PANES) return
- const activeId = activeTabRef.current
- setSplitLayout(prev => {
- if (!prev) {
- return { type: 'split', direction, ratio: 0.5, activePane: activeId, children: [
- { type: 'leaf', tabId: activeId },
- { type: 'leaf', tabId: null },
- ]}
- }
- const clone = JSON.parse(JSON.stringify(prev))
- const findAndSplit = (node) => {
- if (node.type === 'leaf' && node.tabId === activeId) {
- return { type: 'split', direction, ratio: 0.5, activePane: activeId, children: [
- { type: 'leaf', tabId: activeId },
- { type: 'leaf', tabId: null },
- ]}
- }
- if (node.children) {
- return { ...node, children: node.children.map(findAndSplit) }
- }
- return node
- }
- return findAndSplit(clone)
- })
- }, [paneCount])
-
- const removePane = useCallback((tabId) => {
- setSplitLayout(prev => {
- if (!prev) return null
- if (prev.type === 'leaf') return null
- const clone = JSON.parse(JSON.stringify(prev))
- const removeFromTree = (node) => {
- if (node.type !== 'split') return node
- const left = node.children[0]
- const right = node.children[1]
- const leftIsTarget = left.type === 'leaf' && left.tabId === tabId
- const rightIsTarget = right.type === 'leaf' && right.tabId === tabId
- if (leftIsTarget) return removeFromTree(right)
- if (rightIsTarget) return removeFromTree(left)
- return { ...node, children: [removeFromTree(left), removeFromTree(right)] }
- }
- const result = removeFromTree(clone)
- if (result.type === 'leaf' && result.tabId === null) return null
- if (result.type === 'split' && (!result.children || result.children.length < 2)) return result.children?.[0] || null
- return result
- })
- }, [])
-
- const assignPaneTab = useCallback((paneLeaf, tabId) => {
- setSplitLayout(prev => {
- if (!prev) return prev
- const clone = JSON.parse(JSON.stringify(prev))
- const assign = (node) => {
- if (node === paneLeaf) return { ...node, tabId }
- if (node.children) return { ...node, children: node.children.map(assign) }
- return node
- }
- return assign(clone)
- })
- }, [])
-
- useEffect(() => {
- if (splitLayout) {
- localStorage.setItem(LAYOUT_STORAGE_KEY, JSON.stringify(splitLayout))
- } else {
- localStorage.removeItem(LAYOUT_STORAGE_KEY)
- }
- }, [splitLayout])
-
- useEffect(() => {
- api.getAgentSessions?.().then(d => {
- setAgentSessions(d?.sessions || [])
- }).catch(() => {})
- const iv = setInterval(() => {
- api.getAgentSessions?.().then(d => {
- setAgentSessions(d?.sessions || [])
- }).catch(() => {})
- }, 5000)
- return () => clearInterval(iv)
- }, [])
-
const _flushStreamUpdate = useCallback(() => {
_streamRafRef.current = null
const pending = _streamPendingRef.current
@@ -922,22 +818,6 @@ export default function Shell({ api, isSudo }) {
return
}
- if (ctrl && e.shiftKey && e.key === 'D') {
- const shellTab = document.querySelector('.shell-layout')
- if (!shellTab || shellTab.closest('.tab-hidden')) return
- e.preventDefault()
- splitPane('vertical')
- return
- }
-
- if (ctrl && e.shiftKey && e.key === 'H') {
- const shellTab = document.querySelector('.shell-layout')
- if (!shellTab || shellTab.closest('.tab-hidden')) return
- e.preventDefault()
- splitPane('horizontal')
- return
- }
-
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return
if (!e.altKey && !(e.key === 'Tab' && e.shiftKey)) return
@@ -1438,27 +1318,6 @@ Sois concret : cite les vraies versions, les vrais chemins, les vrais nombres. L
{zoomLevel > 0 ? '+' : ''}{zoomLevel > 0 ? zoomLevel * 2 : zoomLevel * 2}px
)}
- {paneCount < MAX_PANES && (
- <>
-
-
- >
- )}
- {splitLayout && (
-
- )}
- {agentSessions.length > 0 && (
-
-