@schoolai/shipyard 3.24.0 → 3.25.0
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/dist/capability-detector-worker.js +3 -3
- package/dist/{chunk-NG355H2L.js → chunk-BBKZIEKF.js} +68 -1
- package/dist/chunk-BBKZIEKF.js.map +1 -0
- package/dist/{chunk-BGJ6QJNS.js → chunk-FC3HWVYQ.js} +46 -1
- package/dist/{chunk-BGJ6QJNS.js.map → chunk-FC3HWVYQ.js.map} +1 -1
- package/dist/{chunk-JZTUQVHQ.js → chunk-IRS6HYMU.js} +2 -2
- package/dist/{chunk-UK3IMOSP.js → chunk-VQCBF7X5.js} +71 -7
- package/dist/chunk-VQCBF7X5.js.map +1 -0
- package/dist/{chunk-TU3MSY2I.js → chunk-X4IWMBWY.js} +2 -2
- package/dist/{chunk-DDC5OQOC.js → chunk-XNH6FVIX.js} +3 -3
- package/dist/{chunk-BN54GQR3.js → chunk-YTYPMVS4.js} +3 -53
- package/dist/chunk-YTYPMVS4.js.map +1 -0
- package/dist/cursor-runner.js +8 -4
- package/dist/cursor-runner.js.map +1 -1
- package/dist/electron-utility.js +2 -2
- package/dist/index.js +3 -3
- package/dist/{plan-backfill-XYOUK2DY.js → plan-backfill-SDYNTKUX.js} +3 -3
- package/dist/{serve-RWFBSQIE.js → serve-HTQMCHRP.js} +334 -188
- package/dist/{serve-RWFBSQIE.js.map → serve-HTQMCHRP.js.map} +1 -1
- package/dist/{start-ZV22UPMC.js → start-HOICUTYV.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-BN54GQR3.js.map +0 -1
- package/dist/chunk-NG355H2L.js.map +0 -1
- package/dist/chunk-UK3IMOSP.js.map +0 -1
- /package/dist/{chunk-JZTUQVHQ.js.map → chunk-IRS6HYMU.js.map} +0 -0
- /package/dist/{chunk-TU3MSY2I.js.map → chunk-X4IWMBWY.js.map} +0 -0
- /package/dist/{chunk-DDC5OQOC.js.map → chunk-XNH6FVIX.js.map} +0 -0
- /package/dist/{plan-backfill-XYOUK2DY.js.map → plan-backfill-SDYNTKUX.js.map} +0 -0
- /package/dist/{start-ZV22UPMC.js.map → start-HOICUTYV.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
getDaemonVersion
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-XNH6FVIX.js";
|
|
5
5
|
import {
|
|
6
6
|
WorkerCommandCodec,
|
|
7
7
|
WorkerReplyCodec
|
|
@@ -1116,4 +1116,4 @@ export {
|
|
|
1116
1116
|
shutdownFileWatcherGuard,
|
|
1117
1117
|
guardedSubscribe
|
|
1118
1118
|
};
|
|
1119
|
-
//# sourceMappingURL=chunk-
|
|
1119
|
+
//# sourceMappingURL=chunk-IRS6HYMU.js.map
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
parseShipyardDeliverableUrl,
|
|
32
32
|
planEditorSerializer,
|
|
33
33
|
toTaskIndexEntry
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-FC3HWVYQ.js";
|
|
35
35
|
import {
|
|
36
36
|
assertNever
|
|
37
37
|
} from "./chunk-X3MULCV5.js";
|
|
@@ -7360,6 +7360,13 @@ var StorageAdapter = class extends Adapter {
|
|
|
7360
7360
|
// src/shared/file-storage-adapter.ts
|
|
7361
7361
|
import { access, mkdir, open, readdir, readFile, rename, unlink } from "fs/promises";
|
|
7362
7362
|
import { dirname, join, sep } from "path";
|
|
7363
|
+
function errnoOf(err) {
|
|
7364
|
+
if (err !== null && typeof err === "object" && "code" in err) {
|
|
7365
|
+
const code = Reflect.get(err, "code");
|
|
7366
|
+
if (typeof code === "string") return code;
|
|
7367
|
+
}
|
|
7368
|
+
return "UNKNOWN";
|
|
7369
|
+
}
|
|
7363
7370
|
var FileStorageAdapter = class _FileStorageAdapter extends StorageAdapter {
|
|
7364
7371
|
#dataDir;
|
|
7365
7372
|
/**
|
|
@@ -7490,6 +7497,12 @@ var FileStorageAdapter = class _FileStorageAdapter extends StorageAdapter {
|
|
|
7490
7497
|
* Returns true if the directory for the given docId exists on disk.
|
|
7491
7498
|
* Uses a single fs.access call — avoids loading any Loro data.
|
|
7492
7499
|
* docId is the first key segment (e.g. "canvas:<taskId>:<epoch>").
|
|
7500
|
+
*
|
|
7501
|
+
* A truthy result means ONLY that the directory exists. `#saveAtomic` mkdir's
|
|
7502
|
+
* the chunk directory before the first `rename` lands, compaction can remove
|
|
7503
|
+
* every chunk under a directory it leaves in place, and a directory the
|
|
7504
|
+
* filesystem refuses to list still passes `access`. Callers asking "does real
|
|
7505
|
+
* data exist here?" must use {@link probeDocChunks} instead — see #5266.
|
|
7493
7506
|
*/
|
|
7494
7507
|
async hasDoc(docId) {
|
|
7495
7508
|
const dirPath = join(this.#dataDir, encodeURIComponent(docId));
|
|
@@ -7500,6 +7513,54 @@ var FileStorageAdapter = class _FileStorageAdapter extends StorageAdapter {
|
|
|
7500
7513
|
return false;
|
|
7501
7514
|
}
|
|
7502
7515
|
}
|
|
7516
|
+
/**
|
|
7517
|
+
* What is ACTUALLY on disk for a docId: how many non-`.tmp` chunk files the
|
|
7518
|
+
* directory holds, or the errno if the filesystem refused to list it. Still
|
|
7519
|
+
* cheap — `readdir` only, no chunk bytes are read and no Loro import runs.
|
|
7520
|
+
*
|
|
7521
|
+
* Exists because `hasDoc`'s boolean cannot distinguish an empty directory from
|
|
7522
|
+
* one holding real chunks, nor either from an EACCES/EIO refusal, and a caller
|
|
7523
|
+
* that infers "dir exists therefore chunks exist therefore an empty read must be
|
|
7524
|
+
* a transient load failure" misdiagnoses a genuinely-empty doc (#5266).
|
|
7525
|
+
*/
|
|
7526
|
+
async probeDocChunks(docId) {
|
|
7527
|
+
const dirPath = join(this.#dataDir, encodeURIComponent(docId));
|
|
7528
|
+
try {
|
|
7529
|
+
const chunkCount = await this.#countChunkFiles(dirPath);
|
|
7530
|
+
return chunkCount === 0 ? { kind: "absent" } : { kind: "chunks", chunkCount, path: dirPath };
|
|
7531
|
+
} catch (err) {
|
|
7532
|
+
const code = errnoOf(err);
|
|
7533
|
+
if (code === "ENOENT") return { kind: "absent" };
|
|
7534
|
+
return {
|
|
7535
|
+
kind: "unreadable",
|
|
7536
|
+
path: dirPath,
|
|
7537
|
+
code,
|
|
7538
|
+
message: err instanceof Error ? err.message : String(err)
|
|
7539
|
+
};
|
|
7540
|
+
}
|
|
7541
|
+
}
|
|
7542
|
+
/**
|
|
7543
|
+
* Chunk files under `dir`, recursively. A directory that does not exist — the
|
|
7544
|
+
* doc has never been written, or compaction removed a subtree mid-walk — counts
|
|
7545
|
+
* as zero, so the caller reports `absent`. Any OTHER errno propagates, so a
|
|
7546
|
+
* directory we were refused (EACCES/EIO/EMFILE) is reported as `unreadable`
|
|
7547
|
+
* rather than silently under-counted as an empty doc.
|
|
7548
|
+
*/
|
|
7549
|
+
async #countChunkFiles(dir) {
|
|
7550
|
+
let entries;
|
|
7551
|
+
try {
|
|
7552
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
7553
|
+
} catch (err) {
|
|
7554
|
+
if (errnoOf(err) === "ENOENT") return 0;
|
|
7555
|
+
throw err;
|
|
7556
|
+
}
|
|
7557
|
+
let count = 0;
|
|
7558
|
+
for (const entry of entries) {
|
|
7559
|
+
if (entry.isDirectory()) count += await this.#countChunkFiles(join(dir, entry.name));
|
|
7560
|
+
else if (entry.isFile() && !entry.name.endsWith(".tmp")) count += 1;
|
|
7561
|
+
}
|
|
7562
|
+
return count;
|
|
7563
|
+
}
|
|
7503
7564
|
async removeRange(keyPrefix) {
|
|
7504
7565
|
if (isWholeDocumentKey(keyPrefix)) return;
|
|
7505
7566
|
const chunks = await this.#collectChunks(keyPrefix);
|
|
@@ -33518,9 +33579,12 @@ function replay(planRepo, taskId, versions) {
|
|
|
33518
33579
|
});
|
|
33519
33580
|
}
|
|
33520
33581
|
}
|
|
33521
|
-
function resolveFileFallback(taskId, sources) {
|
|
33522
|
-
if (sources.planVersions.length > 0 || !sources.planFilePath) return
|
|
33523
|
-
|
|
33582
|
+
async function resolveFileFallback(taskId, sources, bookmarks) {
|
|
33583
|
+
if (sources.planVersions.length > 0 || !sources.planFilePath) return null;
|
|
33584
|
+
const version = await readPlanFileFallback(sources.planFilePath, taskId);
|
|
33585
|
+
if (!version) return null;
|
|
33586
|
+
if (bookmarks?.hasVersionBookmark(taskId, version.timestamp, version.toolUseId)) return null;
|
|
33587
|
+
return version;
|
|
33524
33588
|
}
|
|
33525
33589
|
|
|
33526
33590
|
// src/services/plan-backfill/plan-backfill-executor.ts
|
|
@@ -33660,7 +33724,7 @@ async function processDryRunTask(ctx, docId, isResident) {
|
|
|
33660
33724
|
ctx.deps.shipyardHome
|
|
33661
33725
|
);
|
|
33662
33726
|
const hasOnDiskPlanDoc = await ctx.adapter.hasDoc(docId);
|
|
33663
|
-
const fileFallback = await resolveFileFallback(ctx.taskId, sources);
|
|
33727
|
+
const fileFallback = await resolveFileFallback(ctx.taskId, sources, null);
|
|
33664
33728
|
return planBackfill({
|
|
33665
33729
|
taskId: ctx.taskId,
|
|
33666
33730
|
docHasContent: hasOnDiskPlanDoc,
|
|
@@ -33683,7 +33747,7 @@ async function processWriteTask(ctx, iso, docId, isResident) {
|
|
|
33683
33747
|
);
|
|
33684
33748
|
const hasOnDiskPlanDoc = await ctx.adapter.hasDoc(docId);
|
|
33685
33749
|
const docHasContent = await checkContent(iso, ctx.taskId, hasOnDiskPlanDoc, isResident);
|
|
33686
|
-
const fileFallback = await resolveFileFallback(ctx.taskId, sources);
|
|
33750
|
+
const fileFallback = await resolveFileFallback(ctx.taskId, sources, iso.planRepo);
|
|
33687
33751
|
const action = planBackfill({
|
|
33688
33752
|
taskId: ctx.taskId,
|
|
33689
33753
|
docHasContent,
|
|
@@ -34783,4 +34847,4 @@ export {
|
|
|
34783
34847
|
runPlanBackfill,
|
|
34784
34848
|
buildTaskStateStore
|
|
34785
34849
|
};
|
|
34786
|
-
//# sourceMappingURL=chunk-
|
|
34850
|
+
//# sourceMappingURL=chunk-VQCBF7X5.js.map
|