feat(workspace): no double resume, server-picked tabs, terminal a11y
- A resume of a session a live pane already holds is refused (409 ESESSIONLIVE with error.run_id) and the client opens that pane, pasting any typed message there; catalog tools refuse resumeSessionId (EUNSUPPORTED) instead of silently starting fresh. - POST /api/lanes/:id/start takes slot: "auto": the server picks the free tab under the lane lock (components/lanes/startSession.ts on the client, kept out of WorkspaceHome so the sidebar does not pull react-markdown into the main bundle). - Unsaved whole-file edits are guarded on every exit (Back, another file, tab switch, close, lane/session change, beforeunload). - Closing an AI tab asks first; hiding a pane has its own icon. Tabs and pane headers show the session name, a state dot, rename by double-click. - Terminal: Ctrl+M toggles Tab-moves-focus (no keyboard trap), Cmd+F / Ctrl+Shift+F find bar, clickable links (noopener), a write-only OSC 52 clipboard, a Reconnecting overlay, debounced resizes, optional screen reader mode. Alt+1-4 / Alt+\ / Alt+W focus, split and hide panes. - Changes panel: draggable splitter, wrapping git bar, history paging, disarming discard/undo/abort, inline diff comments pasted only into a visible pane; drag MIME guard on sidebar rows; IME-safe Enter; Show more in the sidebar and Recents; idle dots readable with sr-only text. - Adds @xterm/addon-clipboard, @xterm/addon-search, @xterm/addon-web-links.
This commit is contained in:
@@ -74,7 +74,7 @@
|
||||
"changes.commentOn": "Comment {{at}} — dán vào pane bạn dùng gần nhất; chưa gửi gì cho tới khi bạn nhấn Enter ở đó",
|
||||
"changes.commentSend": "Dán vào pane",
|
||||
"changes.commentCancel": "Huỷ",
|
||||
"changes.commentNoPane": "Workspace này chưa mở pane nào — hãy mở session trước",
|
||||
"changes.commentNoPane": "Chưa có terminal nào của workspace này đang hiện — hãy mở session (hoặc thu hẹp khung Changes) trước",
|
||||
"changes.layout.split": "Hai cột",
|
||||
"changes.layout.unified": "Một cột",
|
||||
"changes.loading": "Đang đọc working copy…",
|
||||
@@ -390,7 +390,7 @@
|
||||
"panes.split.bottom": "Tách xuống dưới",
|
||||
"panes.full": "Một workspace hiện tối đa 4 pane",
|
||||
"panes.newTerminal": "Terminal mới",
|
||||
"panes.close": "Đóng pane (session vẫn chạy dưới dạng tab)",
|
||||
"panes.close": "Ẩn pane (session vẫn chạy dưới dạng tab)",
|
||||
"panes.resize": "Đổi kích thước pane",
|
||||
"tabs.home": "Trang chủ workspace",
|
||||
"sessionMenu.open": "Mở",
|
||||
@@ -401,9 +401,47 @@
|
||||
"panes.show": "Hiện {{name}} ở đây",
|
||||
"panes.splitNew.right": "Chia sang phải với terminal mới",
|
||||
"panes.splitNew.bottom": "Chia xuống dưới với terminal mới",
|
||||
"panes.closeShort": "Đóng pane",
|
||||
"panes.closeShort": "Ẩn pane",
|
||||
"changes.copyPath": "Sao chép đường dẫn tương đối",
|
||||
"changes.viewCommit": "Xem commit",
|
||||
"changes.copySha": "Sao chép SHA của commit",
|
||||
"changes.copySubject": "Sao chép commit message"
|
||||
"changes.copySubject": "Sao chép commit message",
|
||||
"replay.live": "Session này đang mở trong một tab — hãy tiếp tục ở đó.",
|
||||
"replay.noResume": "{{tool}} không thể tiếp tục (resume) một session theo id, nên hội thoại này chỉ để đọc.",
|
||||
"replay.newSession": "Bắt đầu session mới",
|
||||
"tabs.state.awaiting": "Đang chờ bạn",
|
||||
"tabs.state.error": "Lỗi",
|
||||
"tabs.state.running": "Đang chạy",
|
||||
"tabs.renameHint": "Nhấp đúp để đổi tên",
|
||||
"tabs.stopTitle": "Dừng “{{name}}”?",
|
||||
"tabs.stopBody": "Đóng tab sẽ dừng phiên của nó, kể cả khi đang chạy dở. Bạn có thể tiếp tục (resume) sau từ mục Gần đây.",
|
||||
"tabs.stopConfirm": "Dừng phiên",
|
||||
"changes.loadMore": "Tải thêm commit",
|
||||
"changes.commentPasted": "Đã dán vào tab {{tab}} — nhấn Enter ở đó để gửi",
|
||||
"changes.splitter": "Đổi độ rộng khung thay đổi",
|
||||
"tree.archiveLiveTitle": "Lưu trữ một session đang chạy?",
|
||||
"tree.archiveLiveBody": "Tab của nó vẫn chạy; lưu trữ chỉ ẩn nó khỏi danh sách này. Bỏ lưu trữ trong mục đã lưu trữ.",
|
||||
"tree.state.awaiting": "đang chờ bạn",
|
||||
"tree.state.error": "lỗi",
|
||||
"tree.state.live": "đang chạy",
|
||||
"tree.state.idle": "đã kết thúc",
|
||||
"tree.showMore_one": "Hiện thêm {{count}}",
|
||||
"tree.showMore_other": "Hiện thêm {{count}}",
|
||||
"home.contextPanel": "Ngữ cảnh workspace",
|
||||
"row.state.needsYou": "cần bạn",
|
||||
"row.state.error": "lỗi",
|
||||
"row.state.running": "đang chạy",
|
||||
"row.state.active": "đang hoạt động",
|
||||
"row.state.idle": "nghỉ",
|
||||
"menu.stopTitle_one": "Dừng phiên đang chạy?",
|
||||
"menu.stopTitle_other": "Dừng {{count}} phiên đang chạy?",
|
||||
"menu.stopBody": "Mọi tab của workspace này sẽ dừng, kể cả khi đang chạy dở. Có thể tiếp tục các phiên sau từ mục Gần đây.",
|
||||
"gitBar.done.fetch": "Đã fetch",
|
||||
"gitBar.done.pull": "Đã pull",
|
||||
"gitBar.done.push": "Đã push",
|
||||
"gitBar.done.publish": "Đã publish",
|
||||
"runtime.listening": "đang lắng nghe",
|
||||
"runtime.notListening": "không lắng nghe",
|
||||
"replay.pasted": "Session đó đã mở trong một tab — tin nhắn đã được dán vào đó; nhấn Enter để gửi.",
|
||||
"replay.notPasted": "Session đó đang mở trong một tab nhưng không dán được tin nhắn vào đó: {{text}}"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user