sealkeep 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/src/errors.d.ts +1 -1
- package/dist/src/offload.js +13 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
Notable changes, by published version. Sealkeep is pre-1.0: minor versions
|
|
4
4
|
may change behavior, and say so here when they do.
|
|
5
5
|
|
|
6
|
+
## 0.6.1 — 2026-08-19
|
|
7
|
+
|
|
8
|
+
- Reading an offloaded archive now checks for free space first. An index build
|
|
9
|
+
reads each archive in full, and on a machine already short of space that
|
|
10
|
+
filled the disk and died mid-build — the failure this product exists to
|
|
11
|
+
prevent. It refuses in words that name the archive and the shortfall, keeps a
|
|
12
|
+
512 MB reserve, and lets the build carry on with the rest.
|
|
13
|
+
|
|
6
14
|
## 0.6.0 — 2026-08-19
|
|
7
15
|
|
|
8
16
|
**A second machine no longer wipes your search index.** The content index is
|
package/dist/src/errors.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* between releases; these codes are a contract for the CLI, local API, and MCP.
|
|
4
4
|
* Details are operational only: never place plaintext, phrases, or keys here.
|
|
5
5
|
*/
|
|
6
|
-
export type VaultlineErrorCode = "invalid_argument" | "vault_not_initialized" | "vault_already_initialized" | "config_unsupported_version" | "recovery_phrase_missing" | "recovery_phrase_mismatch" | "archive_not_found" | "source_unreadable" | "destination_exists" | "destination_unwritable" | "path_not_permitted" | "native_restore_unavailable" | "ciphertext_integrity_failed" | "plaintext_integrity_failed" | "hook_payload_invalid" | "queue_job_not_found" | "queue_lease_invalid" | "queue_lease_expired" | "queue_job_exhausted" | "storage_not_configured" | "provider_unsupported" | "signer_not_configured" | "lease_expired" | "unauthorized" | "forbidden" | "internal";
|
|
6
|
+
export type VaultlineErrorCode = "invalid_argument" | "vault_not_initialized" | "vault_already_initialized" | "config_unsupported_version" | "recovery_phrase_missing" | "recovery_phrase_mismatch" | "archive_not_found" | "source_unreadable" | "destination_exists" | "destination_unwritable" | "insufficient_disk_space" | "path_not_permitted" | "native_restore_unavailable" | "ciphertext_integrity_failed" | "plaintext_integrity_failed" | "hook_payload_invalid" | "queue_job_not_found" | "queue_lease_invalid" | "queue_lease_expired" | "queue_job_exhausted" | "storage_not_configured" | "provider_unsupported" | "signer_not_configured" | "lease_expired" | "unauthorized" | "forbidden" | "internal";
|
|
7
7
|
export declare class VaultlineError extends Error {
|
|
8
8
|
readonly code: VaultlineErrorCode;
|
|
9
9
|
readonly details: Record<string, unknown>;
|
package/dist/src/offload.js
CHANGED
|
@@ -320,6 +320,19 @@ export async function checkRemoteCopyMany(dataDir, ids, client) {
|
|
|
320
320
|
export async function materialiseArchive(dataDir, record, client) {
|
|
321
321
|
if (!isV2(record) || !record.offloaded)
|
|
322
322
|
return { path: record.objectPath, release: async () => { } };
|
|
323
|
+
// Reading an offloaded archive means writing it back to disk in full, and
|
|
324
|
+
// this runs in a loop during an index build. On a machine that offloaded
|
|
325
|
+
// BECAUSE it was short of space, that filled the disk and died on ENOSPC
|
|
326
|
+
// mid-build — the exact failure this product exists to prevent. Ask first,
|
|
327
|
+
// and refuse in words that name the archive and the shortfall.
|
|
328
|
+
const { freeBytes } = await import("./disk.js");
|
|
329
|
+
const free = await freeBytes(tmpdir());
|
|
330
|
+
const needed = record.cipher.storedBytes ?? record.remote?.bytes ?? 0;
|
|
331
|
+
const RESERVE = 512 * 1024 * 1024;
|
|
332
|
+
if (free !== undefined && needed > 0 && free < needed + RESERVE) {
|
|
333
|
+
const gb = (n) => `${(n / 1024 ** 3).toFixed(1)} GB`;
|
|
334
|
+
fail("insufficient_disk_space", `Reading archive ${record.id.slice(0, 8)} needs about ${gb(needed)} of temporary space and this machine has ${gb(free)} free. Nothing was written. Free some space, or reclaim what is already archived, and try again.`, { archiveId: record.id, free, needed });
|
|
335
|
+
}
|
|
323
336
|
const ciphertext = await fetchCiphertext(dataDir, record, client);
|
|
324
337
|
if (sha256(ciphertext) !== record.cipher.ciphertextSha256) {
|
|
325
338
|
fail("ciphertext_integrity_failed", `The copy of archive ${record.id} in ${record.offloaded.bucket} is not the archive that was stored there`, { archiveId: record.id });
|
package/package.json
CHANGED