diff --git a/v2/package-lock.json b/v2/package-lock.json index 4fffde1..67511e8 100644 --- a/v2/package-lock.json +++ b/v2/package-lock.json @@ -1,12 +1,18 @@ { - "name": "v2", - "version": "0.0.0", + "name": "bterminal-v2", + "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "v2", - "version": "0.0.0", + "name": "bterminal-v2", + "version": "0.1.0", + "dependencies": { + "@tauri-apps/api": "^2.10.1", + "@xterm/addon-canvas": "^0.7.0", + "@xterm/addon-fit": "^0.11.0", + "@xterm/xterm": "^6.0.0" + }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^6.2.1", "@tsconfig/svelte": "^5.0.6", @@ -908,6 +914,16 @@ "vite": "^6.3.0 || ^7.0.0" } }, + "node_modules/@tauri-apps/api": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.10.1.tgz", + "integrity": "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, "node_modules/@tsconfig/svelte": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-5.0.8.tgz", @@ -939,6 +955,30 @@ "dev": true, "license": "MIT" }, + "node_modules/@xterm/addon-canvas": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@xterm/addon-canvas/-/addon-canvas-0.7.0.tgz", + "integrity": "sha512-LF5LYcfvefJuJ7QotNRdRSPc9YASAVDeoT5uyXS/nZshZXjYplGXRECBGiznwvhNL2I8bq1Lf5MzRwstsYQ2Iw==", + "license": "MIT", + "peerDependencies": { + "@xterm/xterm": "^5.0.0" + } + }, + "node_modules/@xterm/addon-fit": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.11.0.tgz", + "integrity": "sha512-jYcgT6xtVYhnhgxh3QgYDnnNMYTcf8ElbxxFzX0IZo+vabQqSPAjC3c1wJrKB5E19VwQei89QCiZZP86DCPF7g==", + "license": "MIT" + }, + "node_modules/@xterm/xterm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-6.0.0.tgz", + "integrity": "sha512-TQwDdQGtwwDt+2cgKDLn0IRaSxYu1tSUjgKarSDkUM0ZNiSRXFpjxEsvc/Zgc5kq5omJ+V0a8/kIM2WD3sMOYg==", + "license": "MIT", + "workspaces": [ + "addons/*" + ] + }, "node_modules/acorn": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", diff --git a/v2/package.json b/v2/package.json index 38b9255..c08bc5e 100644 --- a/v2/package.json +++ b/v2/package.json @@ -20,5 +20,11 @@ "svelte-check": "^4.3.4", "typescript": "~5.9.3", "vite": "^7.3.1" + }, + "dependencies": { + "@tauri-apps/api": "^2.10.1", + "@xterm/addon-canvas": "^0.7.0", + "@xterm/addon-fit": "^0.11.0", + "@xterm/xterm": "^6.0.0" } } diff --git a/v2/src/lib/adapters/pty-bridge.ts b/v2/src/lib/adapters/pty-bridge.ts index 5f64450..2888919 100644 --- a/v2/src/lib/adapters/pty-bridge.ts +++ b/v2/src/lib/adapters/pty-bridge.ts @@ -1,30 +1,38 @@ -// PTY Bridge — IPC wrapper for Rust PTY backend -// Phase 2: terminal spawn, resize, input/output streaming +import { invoke } from '@tauri-apps/api/core'; +import { listen, type UnlistenFn } from '@tauri-apps/api/event'; export interface PtyOptions { shell?: string; cwd?: string; - env?: Record; + args?: string[]; cols?: number; rows?: number; } -/** - * Spawn a new PTY session via Tauri IPC. - * Phase 2: implement with @tauri-apps/api invoke - */ -export async function spawnPty(_options: PtyOptions): Promise { - throw new Error('Not implemented — Phase 2'); +export async function spawnPty(options: PtyOptions): Promise { + return invoke('pty_spawn', { options }); } -export async function writePty(_id: string, _data: string): Promise { - throw new Error('Not implemented — Phase 2'); +export async function writePty(id: string, data: string): Promise { + return invoke('pty_write', { id, data }); } -export async function resizePty(_id: string, _cols: number, _rows: number): Promise { - throw new Error('Not implemented — Phase 2'); +export async function resizePty(id: string, cols: number, rows: number): Promise { + return invoke('pty_resize', { id, cols, rows }); } -export async function killPty(_id: string): Promise { - throw new Error('Not implemented — Phase 2'); +export async function killPty(id: string): Promise { + return invoke('pty_kill', { id }); +} + +export async function onPtyData(id: string, callback: (data: string) => void): Promise { + return listen(`pty-data-${id}`, (event) => { + callback(event.payload); + }); +} + +export async function onPtyExit(id: string, callback: () => void): Promise { + return listen(`pty-exit-${id}`, () => { + callback(); + }); } diff --git a/v2/src/lib/components/Terminal/TerminalPane.svelte b/v2/src/lib/components/Terminal/TerminalPane.svelte new file mode 100644 index 0000000..79155ee --- /dev/null +++ b/v2/src/lib/components/Terminal/TerminalPane.svelte @@ -0,0 +1,134 @@ + + +
+ +