mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-08 08:52:12 +00:00
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]>
28 lines
2.1 KiB
HTML
28 lines
2.1 KiB
HTML
<!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>
|