Файли
Deng Liuтаdengliu af19880390 feat(plugins): PTY session bridge for plugin web views (#2038)
A plugin web view can open interactive PTY sessions (spawn, input, resize, kill, streamed output and exit). Spawning requires the exact granted `process:<program>` and its pinned executable, with no PATH re-resolution or fallback shell; the cwd is the trusted project, arguments, environment (append-only) and sizes are validated, and at most eight sessions run per plugin. A frame can only drive the sessions it opened; output is acknowledged chunk by chunk and input/output are bounded. Sessions end on permission change, reload, disable, uninstall, frame teardown or window close. Requires API ^1.3; adds a web-pty test fixture. Verified on macOS; Windows/Linux not run.

Co-authored-by: dengliu <[email protected]>
2026-11-08 03:29:36 +08:00

28 рядки
2.1 KiB
HTML
Неформатований Постійне посилання Анотація Історія

Цей файл містить неоднозначні символи Юнікоду
Цей файл містить символи Юнікоду, які можна сплутати з іншими символами. Якщо ви вважаєте, що це зроблено навмисно, можете сміливо ігнорувати це попередження. Щоб показати їх, скористайтеся кнопкою Escape.
<!doctype html>
<html><head><meta charset="utf-8"><title>PTY Probe</title>
<style>
body { background: var(--openidea-bg); color: var(--openidea-fg); font-family: var(--openidea-font-mono, monospace); font-size: var(--openidea-font-size, 13px); padding: 12px; }
button, input { font: inherit; padding: 6px; } pre { white-space: pre-wrap; overflow-wrap: anywhere; } form { display: flex; gap: 4px; } input { flex: 1; min-width: 0; }
</style></head><body>
<h2>Web PTY Probe</h2><p id="isolation"></p>
<button id="start">Start bash</button> <button id="stop">Stop</button> <button id="resize">Resize to 100 × 30</button>
<pre id="output" aria-live="polite"></pre>
<form id="input"><input id="command" aria-label="Terminal input" placeholder="Type a shell command"><button>Send</button></form>
<script>
const output = document.querySelector('#output');
const send = (op, args = {}) => openidea.postMessage(JSON.stringify({ op, sessionId: 'probe', ...args }));
document.querySelector('#isolation').textContent = `IPC globals: ${typeof window.__TAURI_INTERNALS__}; parent access: ` + (() => { try { return parent.document.title; } catch { return 'blocked'; } })();
openidea.onMessage(text => {
let m; try { m = JSON.parse(text); } catch { return; }
if (m.op === 'pty-data') {
output.textContent = (output.textContent + m.data).slice(-65536);
send('pty-ack', { sequence: m.sequence });
} else if (m.op === 'pty-error') output.textContent += '\nERROR: ' + m.error + '\n';
else if (m.op === 'pty-exit') output.textContent += '\nEXIT: ' + m.exitCode + '\n';
});
document.querySelector('#start').onclick = () => send('pty-spawn', { program: 'bash', args: ['--noprofile', '--norc', '-i'], cols: 100, rows: 30 });
document.querySelector('#stop').onclick = () => send('pty-kill');
document.querySelector('#resize').onclick = () => send('pty-resize', { cols: 100, rows: 30 });
document.querySelector('#input').onsubmit = e => { e.preventDefault(); send('pty-input', { data: document.querySelector('#command').value + '\r' }); document.querySelector('#command').value = ''; };
</script></body></html>