CORVO-AI commited on
Commit
1933b0a
·
verified ·
1 Parent(s): e9856a9

Update file-manager/app.py

Browse files
Files changed (1) hide show
  1. file-manager/app.py +21 -32
file-manager/app.py CHANGED
@@ -112,46 +112,35 @@ button{{background:#F46821;color:#fff;border:0;padding:8px 14px;border-radius:4p
112
  @app.route("/term")
113
  def term_page():
114
  body = """
115
- <div class="bar"><b>Live PTY terminal</b> — persistent bash. Full logs, prompts,
116
- and interactive input all work. Try: <code>python3</code> then <code>2+2</code>,
117
- or <code>python3 -c "n=input('name? '); print('hi',n)"</code>.</div>
118
- <pre id="out"></pre>
119
- <input type="text" id="line" style="width:82%" autofocus
120
- placeholder="type a command or input, then Enter">
121
- <button onclick="send()">Send</button>
122
- <button onclick="ctrlc()">Ctrl-C</button>
123
- <button onclick="reset()">Restart</button>
124
  <script>
125
- const out = document.getElementById('out');
126
- const line = document.getElementById('line');
127
- function append(t){ out.textContent += t; out.scrollTop = out.scrollHeight; }
 
 
 
128
 
129
- async function send(){
130
- const text = line.value;
131
- line.value = '';
132
- await fetch('/fm/term_in', {method:'POST',
133
  headers:{'Content-Type':'application/json'},
134
- body: JSON.stringify({data: text + "\\n"})});
135
- }
136
- async function ctrlc(){
137
- await fetch('/fm/term_in', {method:'POST',
138
- headers:{'Content-Type':'application/json'},
139
- body: JSON.stringify({data: "\\u0003"})}); // Ctrl-C
140
- }
141
- async function reset(){
142
- await fetch('/fm/term_reset', {method:'POST'});
143
- out.textContent = '';
144
- }
145
- // Poll for new output every 300ms — reliable through the proxy
146
  async function poll(){
147
  try{
148
  const r = await fetch('/fm/term_out');
149
- const d = await r.json();
150
- if(d.data) append(d.data);
151
  }catch(e){}
152
- setTimeout(poll, 300);
153
  }
154
- line.addEventListener('keydown', e => { if(e.key==='Enter'){ e.preventDefault(); send(); }});
155
  poll();
156
  </script>"""
157
  return Response(PAGE.format(body=body))
 
112
  @app.route("/term")
113
  def term_page():
114
  body = """
115
+ <div class="bar"><b>Live terminal (xterm.js)</b> — full color, progress bars, prompts.</div>
116
+ <div id="term" style="height:65vh;background:#000;border-radius:6px"></div>
117
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.css"/>
118
+ <script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.js"></script>
119
+ <script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.js"></script>
 
 
 
 
120
  <script>
121
+ const term = new Terminal({convertEol:false, cursorBlink:true, fontFamily:'monospace', fontSize:13});
122
+ const fit = new FitAddon.FitAddon();
123
+ term.loadAddon(fit);
124
+ term.open(document.getElementById('term'));
125
+ fit.fit();
126
+ window.addEventListener('resize', () => fit.fit());
127
 
128
+ // Send every keystroke straight to the PTY (real interactive terminal)
129
+ term.onData(d => {
130
+ fetch('/fm/term_in', {method:'POST',
 
131
  headers:{'Content-Type':'application/json'},
132
+ body: JSON.stringify({data: d})});
133
+ });
134
+
135
+ // Poll for new PTY output and write it raw — xterm.js renders the ANSI codes
 
 
 
 
 
 
 
 
136
  async function poll(){
137
  try{
138
  const r = await fetch('/fm/term_out');
139
+ const j = await r.json();
140
+ if(j.data) term.write(j.data);
141
  }catch(e){}
142
+ setTimeout(poll, 200);
143
  }
 
144
  poll();
145
  </script>"""
146
  return Response(PAGE.format(body=body))