fix: go to file in big non-git folders; linear reply handling
build-deb / Lint, test, package (push) Successful in 3m0s
build-deb / Deploy to CT 126 (push) Successful in 3s
build-deb / Notify on failure (push) Skipped

- find/git producers piped into head tolerate SIGPIPE, so hitting a cap no
  longer fails the command (and lets ttyd truncate its reply).
- fs-find outside git skips build/cache folders and caps at 10000.
- runCommand checks completion on the stream's tail instead of re-decoding
  the whole reply on every frame.

Refs #37

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 01:50:50 -04:00
co-authored by Claude Opus 5.5
parent e345bf4640
commit dee1843986
5 changed files with 41 additions and 10 deletions
+9 -1
View File
@@ -152,13 +152,21 @@ async function runCommandNow(args, timeoutMs) {
clearTimeout(timer);
resolve(new TextDecoder().decode(concat(chunks)));
};
const decoder = new TextDecoder();
let head = '';
let tail = '';
socket.onmessage = (event) => {
const { type, payload } = decodeServer(event.data);
if (type !== Server.OUTPUT) return;
chunks.push(payload.slice());
const piece = decoder.decode(payload, { stream: true });
if (head.length < 4096) head += piece;
tail = (tail + piece).slice(-64);
// Hang up as soon as the answer is complete: devdesk waits for that
// before exiting, so ttyd can't drop its last output (devdesk#35).
if (isComplete(new TextDecoder().decode(concat(chunks)))) {
// Replies are one JSON line (or a devdesk: error), so only a chunk that
// ends a line with "}" is worth a full parse; big replies stay linear.
if (/^devdesk: .*\n/m.test(head) || (/\}\s*\n\s*$/.test(tail) && isComplete(new TextDecoder().decode(concat(chunks))))) {
finish();
socket.close();
}
+1 -1
View File
@@ -406,7 +406,7 @@ export class FilesPane {
async loadFileList() {
if (this.fileList && Date.now() - this.fileList.at < 60000 && this.fileList.session === this.session) return this.fileList.items;
const list = parseListOutput(await runCommand(['--fs-find', this.session], 20000));
const list = parseListOutput(await runCommand(['--fs-find', this.session], 45000));
const items = list.files.map((path) => {
const name = base(path);
const [icon] = iconFor(name);