Something went wrong. Try again.
Monorepo for the nibling.run platform
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102// Adapts the runtime's host fs (async RPC to the kernel's pid-0 process) to bashkit's// `HostFileSystem`, so bash sees the same VFS the booted app's own `node` processes do.
// readDir reports symlinks as themselves; stat follows them, so it only ever sees// "file" or "dir".const kind = (k) => (k === "dir" ? "directory" : k === "symlink" ? "symlink" : "file");
// The host's rejections already carry a Node `code` (ENOENT, EEXIST, ...), but they cross// a worker postMessage boundary on the way here; rewrap as a plain Error so bashkit's own// `code` check — and the bash message it prints for that code — sees what it expects.function wrapError(e) { const err = new Error(e.message); err.code = e.code ?? "EIO"; return err;}
/** * @param {import("../../src/host/index").Kernel} runtime * @returns {import("@everruns/bashkit-wasm").HostFileSystem} */export function hostFs(runtime) { const fs = runtime.fs; return { async read(path) { try { return await fs.readFile(path); } catch (e) { throw wrapError(e); } }, async write(path, content) { try { await fs.writeFile(path, content); } catch (e) { throw wrapError(e); } }, async mkdir(path, recursive) { try { await fs.mkdir(path, { recursive }); } catch (e) { throw wrapError(e); } }, // A directory rmdirs (recursively, when asked); a file unlinks. async remove(path, recursive) { try { const st = await fs.stat(path); if (st.kind === "dir") await fs.rm(path, { recursive }); else await fs.unlink(path); } catch (e) { throw wrapError(e); } }, async stat(path) { try { const st = await fs.stat(path); return { type: kind(st.kind), size: st.size, mode: st.mode, mtimeMs: st.mtimeMs }; } catch (e) { throw wrapError(e); } }, async readDir(path) { try { const entries = await fs.readdir(path); return Promise.all(entries.map(async (d) => { const full = `${path === "/" ? "" : path}/${d.name}`; const st = await fs.stat(full).catch(() => null); return { name: d.name, type: kind(d.kind), size: st?.size, mode: st?.mode, mtimeMs: st?.mtimeMs }; })); } catch (e) { throw wrapError(e); } }, // Must not throw for a plain miss. async exists(path) { return fs.stat(path).then(() => true, () => false); }, async rename(from, to) { try { await fs.rename(from, to); } catch (e) { throw wrapError(e); } }, async symlink(target, link) { try { await fs.symlink(target, link); } catch (e) { throw wrapError(e); } }, async readLink(path) { try { return await fs.readlink(path); } catch (e) { throw wrapError(e); } }, };}