mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 05:11:49 +01:00
Bound initial computer home uploads and exclude runtime state
Stream initial personal files through bounded chunks into private staging and atomically publish without replacing an existing home. Keep the home-level runtime directory out of instruction enumeration and seeding while preserving nested user content. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
421f7f0600
commit
cebfa8b09f
8 files changed
+204
-32
No files matched your search
@@ -687,9 +687,33 @@ finally:
|
||||
base64: bytes.toString("base64"),
|
||||
expectedSha256,
|
||||
});
|
||||
const seedFiles = async (chunks: AsyncIterable<{ path: string; offset: number; bytes: Buffer }>): Promise<{ seeded: boolean }> => {
|
||||
const seedId = randomUUID();
|
||||
const started = await remote({ action: "seed-begin", seedId });
|
||||
if (!started.started) return { seeded: false };
|
||||
try {
|
||||
for await (const chunk of chunks) {
|
||||
if (chunk.bytes.length > 1024 * 1024) throw new ComputerError("invalid", "Initial home chunk exceeds its size limit");
|
||||
await remote({ action: "seed-chunk", seedId, path: chunk.path, offset: chunk.offset, base64: chunk.bytes.toString("base64") });
|
||||
}
|
||||
return await remote({ action: "seed-commit", seedId });
|
||||
} catch (error) {
|
||||
await remote({ action: "seed-abort", seedId }).catch(() => undefined);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
const seedBytes = async (files: Record<string, Buffer>): Promise<{ seeded: boolean }> => seedFiles((async function* () {
|
||||
for (const [path, bytes] of Object.entries(files)) {
|
||||
for (let offset = 0; offset < Math.max(1, bytes.length); offset += 1024 * 1024) {
|
||||
yield { path, offset, bytes: bytes.subarray(offset, offset + 1024 * 1024) };
|
||||
}
|
||||
}
|
||||
})());
|
||||
return {
|
||||
root,
|
||||
readBytes,
|
||||
seedFiles,
|
||||
seedBytes,
|
||||
writeBytes,
|
||||
async read(path: string) {
|
||||
const value = await readBytes(path);
|
||||
@@ -729,29 +753,8 @@ finally:
|
||||
): Promise<{ sha256: string }> {
|
||||
return remote({ action: "move", path: from, to, expectedSha256 });
|
||||
},
|
||||
async seedBytes(
|
||||
files: Record<string, Buffer>,
|
||||
): Promise<{ seeded: boolean }> {
|
||||
return remote({
|
||||
action: "seed",
|
||||
files: Object.fromEntries(
|
||||
Object.entries(files).map(([key, value]) => [
|
||||
key,
|
||||
value.toString("base64"),
|
||||
]),
|
||||
),
|
||||
});
|
||||
},
|
||||
async seed(files: Record<string, string>): Promise<{ seeded: boolean }> {
|
||||
return remote({
|
||||
action: "seed",
|
||||
files: Object.fromEntries(
|
||||
Object.entries(files).map(([key, value]) => [
|
||||
key,
|
||||
Buffer.from(value).toString("base64"),
|
||||
]),
|
||||
),
|
||||
});
|
||||
return seedBytes(Object.fromEntries(Object.entries(files).map(([path, content]) => [path, Buffer.from(content)])));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user