wiki-graph-sdk 0.9.0 → 0.9.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.
Files changed (51) hide show
  1. package/dist/archives.cjs +306 -135
  2. package/dist/archives.cjs.map +1 -1
  3. package/dist/archives.js +315 -140
  4. package/dist/archives.js.map +1 -1
  5. package/dist/conversions.cjs +268 -99
  6. package/dist/conversions.cjs.map +1 -1
  7. package/dist/conversions.js +274 -103
  8. package/dist/conversions.js.map +1 -1
  9. package/dist/default-worker.cjs +258 -101
  10. package/dist/default-worker.cjs.map +1 -1
  11. package/dist/default-worker.js +264 -105
  12. package/dist/default-worker.js.map +1 -1
  13. package/dist/embedding.cjs +214 -54
  14. package/dist/embedding.cjs.map +1 -1
  15. package/dist/embedding.js +214 -54
  16. package/dist/embedding.js.map +1 -1
  17. package/dist/gc.cjs +214 -54
  18. package/dist/gc.cjs.map +1 -1
  19. package/dist/gc.js +214 -54
  20. package/dist/gc.js.map +1 -1
  21. package/dist/index.cjs +343 -165
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +357 -174
  25. package/dist/index.js.map +1 -1
  26. package/dist/local-config.cjs +214 -54
  27. package/dist/local-config.cjs.map +1 -1
  28. package/dist/local-config.js +214 -54
  29. package/dist/local-config.js.map +1 -1
  30. package/dist/maintenance.cjs +264 -97
  31. package/dist/maintenance.cjs.map +1 -1
  32. package/dist/maintenance.js +270 -101
  33. package/dist/maintenance.js.map +1 -1
  34. package/dist/node-platform.cjs +214 -54
  35. package/dist/node-platform.cjs.map +1 -1
  36. package/dist/node-platform.d.ts +2 -0
  37. package/dist/node-platform.js +214 -54
  38. package/dist/node-platform.js.map +1 -1
  39. package/dist/runtime-config.cjs +214 -54
  40. package/dist/runtime-config.cjs.map +1 -1
  41. package/dist/runtime-config.js +214 -54
  42. package/dist/runtime-config.js.map +1 -1
  43. package/dist/stage.cjs +214 -54
  44. package/dist/stage.cjs.map +1 -1
  45. package/dist/stage.js +214 -54
  46. package/dist/stage.js.map +1 -1
  47. package/dist/worker.cjs +257 -96
  48. package/dist/worker.cjs.map +1 -1
  49. package/dist/worker.js +263 -100
  50. package/dist/worker.js.map +1 -1
  51. package/package.json +2 -2
package/dist/index.cjs CHANGED
@@ -61,6 +61,7 @@ __export(src_exports, {
61
61
  WikiGraphLibraryManager: () => WikiGraphLibraryManager,
62
62
  WikiGraphMaintenanceManager: () => WikiGraphMaintenanceManager,
63
63
  WikiGraphSDK: () => WikiGraphSDK,
64
+ WikiGraphSchemaVersionError: () => import_wiki_graph_core19.WikiGraphSchemaVersionError,
64
65
  buildSearchIndexEmbeddingProvider: () => buildSearchIndexEmbeddingProvider,
65
66
  buildWikiGraphLLMOptions: () => buildWikiGraphLLMOptions,
66
67
  clearLocalConfigSection: () => clearLocalConfigSection,
@@ -103,6 +104,7 @@ __export(src_exports, {
103
104
  isSourceLocatorScopeUri: () => import_wiki_graph_core19.isSourceLocatorScopeUri,
104
105
  isWikiGraphJobUri: () => import_wiki_graph_core19.isWikiGraphJobUri,
105
106
  isWikiGraphLibraryUri: () => import_wiki_graph_core19.isWikiGraphLibraryUri,
107
+ isWikiGraphSchemaVersionError: () => import_wiki_graph_core19.isWikiGraphSchemaVersionError,
106
108
  isWikiGraphUri: () => import_wiki_graph_core19.isWikiGraphUri,
107
109
  iterateItems: () => iterateItems,
108
110
  iteratePages: () => iteratePages,
@@ -255,6 +257,15 @@ var NodeFile = class {
255
257
  this.name = name;
256
258
  }
257
259
  path;
260
+ async getPhysicalIdentity() {
261
+ const value = await fsPromises.stat(this.path).catch((error) => {
262
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
263
+ return void 0;
264
+ throw error;
265
+ });
266
+ if (value === void 0) return void 0;
267
+ return `${value.dev}:${value.ino}`;
268
+ }
258
269
  kind = "file";
259
270
  [NODE_RESOURCE_KIND] = "file";
260
271
  identity;
@@ -379,6 +390,15 @@ var NodeDirectory = class _NodeDirectory {
379
390
  this.name = pathModule.basename(path);
380
391
  }
381
392
  path;
393
+ async getPhysicalIdentity() {
394
+ const value = await fsPromises.stat(this.path).catch((error) => {
395
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
396
+ return void 0;
397
+ throw error;
398
+ });
399
+ if (value === void 0) return void 0;
400
+ return `${value.dev}:${value.ino}`;
401
+ }
382
402
  kind = "directory";
383
403
  [NODE_RESOURCE_KIND] = "directory";
384
404
  identity;
@@ -388,8 +408,10 @@ var NodeDirectory = class _NodeDirectory {
388
408
  const file = new NodeFile(pathModule.join(this.path, name));
389
409
  try {
390
410
  return (await fsPromises.stat(file.path)).isFile() ? file : void 0;
391
- } catch {
392
- return void 0;
411
+ } catch (error) {
412
+ if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
413
+ return void 0;
414
+ throw error;
393
415
  }
394
416
  }
395
417
  async getLastModified() {
@@ -407,8 +429,10 @@ var NodeDirectory = class _NodeDirectory {
407
429
  const directory = new _NodeDirectory(pathModule.join(this.path, name));
408
430
  try {
409
431
  return (await fsPromises.stat(directory.path)).isDirectory() ? directory : void 0;
410
- } catch {
411
- return void 0;
432
+ } catch (error) {
433
+ if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
434
+ return void 0;
435
+ throw error;
412
436
  }
413
437
  }
414
438
  async list() {
@@ -532,14 +556,23 @@ async function openNativeNodeDatabase(file, flags) {
532
556
  });
533
557
  });
534
558
  }
535
- async function openNodeZip(file) {
559
+ async function openNodeZip(file, options = {}) {
536
560
  const path = getBrandedNodeResourcePath(file, "file");
537
561
  if (path === void 0) {
538
562
  throw new TypeError("The Node ZIP adapter requires a NodeFile");
539
563
  }
540
- const zipFile = await new Promise((resolve4, reject) => {
541
- yauzl.open(
542
- path,
564
+ const handle = await fsPromises.open(path, "r");
565
+ let size;
566
+ try {
567
+ size = (await handle.stat()).size;
568
+ } catch (error) {
569
+ await handle.close();
570
+ throw error;
571
+ }
572
+ const open2 = () => new Promise((resolve4, reject) => {
573
+ yauzl.fromRandomAccessReader(
574
+ new NodeZipSource(handle),
575
+ size,
543
576
  { autoClose: false, lazyEntries: true },
544
577
  (error, opened) => {
545
578
  if (error || opened === void 0)
@@ -548,63 +581,192 @@ async function openNodeZip(file) {
548
581
  }
549
582
  );
550
583
  });
551
- const entries = await new Promise(
552
- (resolve4, reject) => {
553
- const discovered = /* @__PURE__ */ new Map();
554
- const rejectAndClose = (error) => {
555
- zipFile.close();
556
- reject(
557
- error instanceof Error ? error : new Error("Cannot scan ZIP central directory")
558
- );
559
- };
560
- const resolveEntries = () => {
561
- zipFile.off("error", rejectAndClose);
562
- resolve4(discovered);
563
- };
564
- zipFile.on("entry", (entry) => {
565
- if (!entry.fileName.endsWith("/")) {
566
- discovered.set(entry.fileName, entry);
567
- }
568
- zipFile.readEntry();
569
- });
570
- zipFile.once("error", rejectAndClose);
571
- zipFile.once("end", resolveEntries);
572
- zipFile.readEntry();
573
- }
574
- );
584
+ try {
585
+ (await open2()).close();
586
+ } catch (error) {
587
+ await handle.close();
588
+ throw error;
589
+ }
575
590
  let closed = false;
591
+ let pending = Promise.resolve();
592
+ let closing;
593
+ const run = (operation) => {
594
+ if (closed)
595
+ return Promise.reject(new Error("Cannot read a closed ZIP archive"));
596
+ const result = pending.then(async () => {
597
+ const zip = await open2();
598
+ try {
599
+ return await operation(zip);
600
+ } finally {
601
+ zip.close();
602
+ }
603
+ });
604
+ pending = result.then(
605
+ () => void 0,
606
+ () => void 0
607
+ );
608
+ return result;
609
+ };
610
+ const withEntry = (name, operation) => run(async (zip) => {
611
+ let exact;
612
+ let alias;
613
+ let aliasCollision = false;
614
+ await scanNodeZip(zip, (entry) => {
615
+ if (entry.fileName === name) exact = entry;
616
+ if (normalizeNodeZipName(entry.fileName) === name) {
617
+ if (alias !== void 0 && alias.fileName !== entry.fileName)
618
+ aliasCollision = true;
619
+ alias = entry;
620
+ }
621
+ });
622
+ if ((exact === void 0 || options.entryNameMode === "normalized") && aliasCollision) {
623
+ let bestPosition = -1;
624
+ const candidates = await open2();
625
+ try {
626
+ await scanNodeZip(candidates, async (entry) => {
627
+ if (normalizeNodeZipName(entry.fileName) !== name) return;
628
+ const probe = await open2();
629
+ let position = 0;
630
+ try {
631
+ await scanNodeZip(probe, (candidate) => {
632
+ if (candidate.fileName === entry.fileName) return false;
633
+ position++;
634
+ });
635
+ } finally {
636
+ probe.close();
637
+ }
638
+ if (position >= bestPosition) {
639
+ bestPosition = position;
640
+ alias = entry;
641
+ }
642
+ });
643
+ return await operation(candidates, alias);
644
+ } finally {
645
+ candidates.close();
646
+ }
647
+ }
648
+ return await operation(
649
+ zip,
650
+ options.entryNameMode === "normalized" ? alias : exact ?? alias
651
+ );
652
+ });
576
653
  return {
577
654
  close: () => {
578
- if (!closed) zipFile.close();
579
655
  closed = true;
580
- return Promise.resolve();
656
+ closing ??= pending.then(() => handle.close());
657
+ return closing;
581
658
  },
582
- copyEntry: async (name, target) => {
583
- if (closed) throw new Error("Cannot read a closed ZIP archive");
584
- const entry = entries.get(name);
659
+ copyEntry: (name, target) => withEntry(name, async (zip, entry) => {
585
660
  if (entry === void 0) return false;
586
- await copyNodeZipEntry(zipFile, entry, target);
661
+ await copyNodeZipEntry(zip, entry, target);
587
662
  return true;
588
- },
589
- getEntrySize: (name) => {
590
- if (closed) throw new Error("Cannot read a closed ZIP archive");
591
- return Promise.resolve(entries.get(name)?.uncompressedSize);
592
- },
593
- listEntries: () => Promise.resolve([...entries.keys()]),
594
- readEntryRange: async (name, offset, length) => {
595
- if (closed) throw new Error("Cannot read a closed ZIP archive");
596
- const entry = entries.get(name);
663
+ }),
664
+ getEntrySize: (name) => withEntry(
665
+ name,
666
+ (_zip, entry) => Promise.resolve(entry?.uncompressedSize)
667
+ ),
668
+ listEntries: () => run(async (zip) => {
669
+ const names = /* @__PURE__ */ new Set();
670
+ await scanNodeZip(zip, (entry) => {
671
+ names.add(entry.fileName);
672
+ });
673
+ return [...names];
674
+ }),
675
+ readEntryRange: (name, offset, length) => withEntry(name, async (zip, entry) => {
597
676
  if (entry === void 0) return void 0;
598
- return await readNodeZipEntryRange(zipFile, entry, offset, length);
599
- },
600
- readEntry: async (name) => {
601
- if (closed) throw new Error("Cannot read a closed ZIP archive");
602
- const entry = entries.get(name);
677
+ return await readNodeZipEntryRange(zip, entry, offset, length);
678
+ }),
679
+ readEntry: (name) => withEntry(name, async (zip, entry) => {
603
680
  if (entry === void 0) return void 0;
604
- return await readNodeZipEntry(zipFile, entry);
605
- }
681
+ return await readNodeZipEntry(zip, entry);
682
+ })
606
683
  };
607
684
  }
685
+ var NodeZipSource = class extends yauzl.RandomAccessReader {
686
+ constructor(handle) {
687
+ super();
688
+ this.handle = handle;
689
+ }
690
+ handle;
691
+ read(buffer, offset, length, position, callback) {
692
+ const read2 = (written) => {
693
+ if (written === length) {
694
+ callback(null);
695
+ return;
696
+ }
697
+ fs.read(
698
+ this.handle.fd,
699
+ buffer,
700
+ offset + written,
701
+ length - written,
702
+ position + written,
703
+ (error, bytesRead) => {
704
+ if (error) callback(error);
705
+ else if (bytesRead === 0)
706
+ callback(new Error("Unexpected end of ZIP file"));
707
+ else read2(written + bytesRead);
708
+ }
709
+ );
710
+ };
711
+ read2(0);
712
+ }
713
+ _readStreamForRange(start, end) {
714
+ const handle = this.handle;
715
+ return import_node_stream.Readable.from(
716
+ (async function* () {
717
+ for (let position = start; position < end; ) {
718
+ const buffer = Buffer.allocUnsafe(
719
+ Math.min(64 * 1024, end - position)
720
+ );
721
+ const { bytesRead } = await handle.read(
722
+ buffer,
723
+ 0,
724
+ buffer.length,
725
+ position
726
+ );
727
+ if (bytesRead === 0) return;
728
+ position += bytesRead;
729
+ yield buffer.subarray(0, bytesRead);
730
+ }
731
+ })()
732
+ );
733
+ }
734
+ };
735
+ function normalizeNodeZipName(name) {
736
+ const normalized = name.replaceAll("\\", "/").trim().split("/").filter((part) => part !== "" && part !== ".").join("/");
737
+ return normalized.split("/").includes("..") ? void 0 : normalized;
738
+ }
739
+ async function scanNodeZip(zip, visit) {
740
+ await new Promise((resolve4, reject) => {
741
+ const cleanup = () => {
742
+ zip.off("entry", onEntry);
743
+ zip.off("end", onEnd);
744
+ zip.off("error", onError);
745
+ };
746
+ const onError = (error) => {
747
+ cleanup();
748
+ reject(error);
749
+ };
750
+ const onEnd = () => {
751
+ cleanup();
752
+ resolve4();
753
+ };
754
+ const onEntry = (entry) => {
755
+ void Promise.resolve().then(() => entry.fileName.endsWith("/") ? void 0 : visit(entry)).then((keepReading) => {
756
+ if (keepReading === false) onEnd();
757
+ else zip.readEntry();
758
+ }).catch(
759
+ (error) => onError(
760
+ error instanceof Error ? error : new Error("Cannot scan ZIP", { cause: error })
761
+ )
762
+ );
763
+ };
764
+ zip.on("entry", onEntry);
765
+ zip.once("end", onEnd);
766
+ zip.once("error", onError);
767
+ zip.readEntry();
768
+ });
769
+ }
608
770
  async function copyNodeZipEntry(zipFile, entry, target) {
609
771
  const writer = await target.openWriter();
610
772
  try {
@@ -1505,6 +1667,16 @@ function resolveWikiGraphRuntimePath(path) {
1505
1667
  var import_promises3 = require("fs/promises");
1506
1668
  var import_path3 = require("path");
1507
1669
  var import_wiki_graph_core2 = require("wiki-graph-core");
1670
+ function rethrowArchiveSchemaError(error, target) {
1671
+ if ((0, import_wiki_graph_core2.isWikiGraphSchemaVersionError)(error) && error.target.kind === "archive") {
1672
+ throw new import_wiki_graph_core2.WikiGraphSchemaVersionError(
1673
+ target.kind === "standalone" ? { kind: "archive", path: resolveWikiGraphRuntimePath(target.path) } : { kind: "library", uri: target.uri.split("/arc/")[0] },
1674
+ error.actualVersion,
1675
+ error.supportedVersion
1676
+ );
1677
+ }
1678
+ throw error;
1679
+ }
1508
1680
  function requireWikiGraphArchiveFile(location) {
1509
1681
  return location.archiveFile;
1510
1682
  }
@@ -1525,12 +1697,7 @@ async function assertStandaloneWikiGraphArchivePath(inputPath) {
1525
1697
  const path = resolveWikiGraphRuntimePath(inputPath);
1526
1698
  const candidate = await canonicalPath(path);
1527
1699
  const candidateIdentity = await readFileIdentity(path);
1528
- const libraries = await (0, import_wiki_graph_core2.listWikiGraphLibraries)();
1529
- const matches = await findMatchingMembers(
1530
- libraries,
1531
- candidate,
1532
- candidateIdentity
1533
- );
1700
+ const matches = await findMatchingMembers(candidate, candidateIdentity);
1534
1701
  if (matches.length > 0) {
1535
1702
  const match = requireUnambiguousManagedMatch(path, matches);
1536
1703
  throw new WikiGraphArchiveOwnershipError(
@@ -1539,15 +1706,26 @@ async function assertStandaloneWikiGraphArchivePath(inputPath) {
1539
1706
  )}: ${path}. Use the library UUID URI ${match.archive.uri} instead.`
1540
1707
  );
1541
1708
  }
1542
- for (const library of libraries) {
1543
- const rootPath = getNodeResourcePath(library.folder);
1544
- const root = await canonicalPath(rootPath);
1545
- if (!isWithin(root, candidate)) continue;
1546
- throw new WikiGraphArchiveOwnershipError(
1547
- `Standalone archive path belongs to registered library ${(0, import_wiki_graph_core2.formatWikiGraphLibraryUri)(
1548
- library.isDefault ? void 0 : library.publicId
1549
- )}: ${path}. Scan the library, then address the archive by its library UUID URI.`
1709
+ const ancestors = /* @__PURE__ */ new Set();
1710
+ for (const start of [candidate, (0, import_path3.resolve)(path)]) {
1711
+ for (let parent = (0, import_path3.dirname)(start); ; parent = (0, import_path3.dirname)(parent)) {
1712
+ ancestors.add(parent);
1713
+ if ((0, import_path3.dirname)(parent) === parent) break;
1714
+ }
1715
+ }
1716
+ for (const parent of ancestors) {
1717
+ const identity = await readFileIdentity(parent);
1718
+ const library = await (0, import_wiki_graph_core2.findWikiGraphLibraryByPhysicalIdentity)(
1719
+ identity,
1720
+ new NodeDirectory(parent).identity
1550
1721
  );
1722
+ if (library !== void 0) {
1723
+ throw new WikiGraphArchiveOwnershipError(
1724
+ `Standalone archive path belongs to registered library ${(0, import_wiki_graph_core2.formatWikiGraphLibraryUri)(
1725
+ library.isDefault ? void 0 : library.publicId
1726
+ )}: ${path}. Scan the library, then address the archive by its library UUID URI.`
1727
+ );
1728
+ }
1551
1729
  }
1552
1730
  return path;
1553
1731
  }
@@ -1565,11 +1743,7 @@ async function resolveWikiGraphArchiveTarget(file) {
1565
1743
  const path = getNodeResourcePath(file);
1566
1744
  const candidate = await canonicalPath(path);
1567
1745
  const candidateIdentity = await readFileIdentity(path);
1568
- const matches = await findMatchingMembers(
1569
- await (0, import_wiki_graph_core2.listWikiGraphLibraries)(),
1570
- candidate,
1571
- candidateIdentity
1572
- );
1746
+ const matches = await findMatchingMembers(candidate, candidateIdentity);
1573
1747
  if (matches.length > 0) {
1574
1748
  const match = requireUnambiguousManagedMatch(path, matches);
1575
1749
  return { kind: "library", uri: match.archive.uri };
@@ -1635,48 +1809,35 @@ function withObjectUri(archiveLocator, objectUri) {
1635
1809
  async function canonicalPath(path) {
1636
1810
  try {
1637
1811
  return await (0, import_promises3.realpath)(path);
1638
- } catch {
1812
+ } catch (error) {
1813
+ if (!(typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR")))
1814
+ throw error;
1639
1815
  const absolute = (0, import_path3.resolve)(path);
1640
1816
  const parent = (0, import_path3.dirname)(absolute);
1641
1817
  return parent === absolute ? absolute : (0, import_path3.join)(await canonicalPath(parent), (0, import_path3.basename)(absolute));
1642
1818
  }
1643
1819
  }
1644
- function isWithin(root, candidate) {
1645
- const child = (0, import_path3.relative)(root, candidate);
1646
- return child === "" || !child.startsWith("..") && !(0, import_path3.isAbsolute)(child);
1647
- }
1648
- async function findMatchingMembers(libraries, candidate, candidateIdentity) {
1820
+ async function findMatchingMembers(candidate, candidateIdentity) {
1821
+ if (candidateIdentity === void 0) return [];
1822
+ const archives = await (0, import_wiki_graph_core2.findWikiGraphLibraryArchivePhysicalAliases)(candidateIdentity);
1649
1823
  const members = [];
1650
- for (const library of libraries) {
1651
- const archives = await (0, import_wiki_graph_core2.listWikiGraphLibraryArchives)({
1652
- isDefault: library.isDefault,
1653
- kind: "scope",
1654
- ...library.isDefault ? {} : { publicId: library.publicId }
1655
- });
1656
- for (const archive of archives) {
1657
- const physical = archive.file ?? archive.directory;
1658
- if (physical === void 0) continue;
1824
+ for (const archive of archives) {
1825
+ const parsed = (0, import_wiki_graph_core2.parseWikiGraphLibraryUri)(archive.libraryUri);
1826
+ const library = await (0, import_wiki_graph_core2.resolveWikiGraphLibrary)(parsed);
1827
+ const physical = archive.file ?? archive.directory;
1828
+ if (library !== void 0 && physical !== void 0)
1659
1829
  members.push({
1660
1830
  archive,
1661
1831
  library,
1662
1832
  memberPath: getNodeResourcePath(physical)
1663
1833
  });
1664
- }
1665
1834
  }
1666
1835
  const exact = [];
1667
1836
  for (const member of members) {
1668
- if (await canonicalPath(member.memberPath) === candidate) {
1837
+ if (await canonicalPath(member.memberPath) === candidate)
1669
1838
  exact.push(member);
1670
- }
1671
1839
  }
1672
- if (exact.length > 0 || candidateIdentity === void 0) return exact;
1673
- const identityMatches = [];
1674
- for (const member of members) {
1675
- if (await readFileIdentity(member.memberPath) === candidateIdentity) {
1676
- identityMatches.push(member);
1677
- }
1678
- }
1679
- return identityMatches;
1840
+ return exact.length > 0 ? exact : members;
1680
1841
  }
1681
1842
  function requireUnambiguousManagedMatch(path, matches) {
1682
1843
  if (matches.length === 1) return matches[0];
@@ -1688,8 +1849,10 @@ async function readFileIdentity(path) {
1688
1849
  try {
1689
1850
  const value = await (0, import_promises3.stat)(path);
1690
1851
  return `${value.dev}:${value.ino}`;
1691
- } catch {
1692
- return void 0;
1852
+ } catch (error) {
1853
+ if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
1854
+ return void 0;
1855
+ throw error;
1693
1856
  }
1694
1857
  }
1695
1858
 
@@ -1751,11 +1914,15 @@ var WikiGraphConversionManager = class {
1751
1914
  if (!("path" in options.input)) {
1752
1915
  throw new Error("wikg input requires a file path.");
1753
1916
  }
1917
+ const inputPath = options.input.path;
1754
1918
  await app.openSession(
1755
- new NodeFile(
1756
- await assertStandaloneWikiGraphArchivePath(options.input.path)
1757
- ),
1919
+ new NodeFile(await assertStandaloneWikiGraphArchivePath(inputPath)),
1758
1920
  write
1921
+ ).catch(
1922
+ (error) => rethrowArchiveSchemaError(error, {
1923
+ kind: "standalone",
1924
+ path: inputPath
1925
+ })
1759
1926
  );
1760
1927
  } else if ("stream" in options.input) {
1761
1928
  await app.digestTextStreamSession(
@@ -2171,6 +2338,12 @@ var import_wiki_graph_core6 = require("wiki-graph-core");
2171
2338
  async function writeWikiGraphArchiveLocation(location, operation, options = {}) {
2172
2339
  const cacheOnly = options.searchIndexWritebackPolicy === "cache";
2173
2340
  const write = async (archiveFile = location.archiveFile) => {
2341
+ if (cacheOnly) {
2342
+ return await new import_wiki_graph_core6.WikiGraphArchiveFile(archiveFile).readDocument(
2343
+ operation,
2344
+ { searchIndexWritebackPolicy: "cache" }
2345
+ );
2346
+ }
2174
2347
  const writeOptions = {
2175
2348
  ...cacheOnly ? {} : { derivedStateKeys: [location.archiveKey, location.archivePath] },
2176
2349
  ...options.invalidateContinuationCursors === void 0 ? {} : {
@@ -2546,10 +2719,15 @@ var WikiGraphArchiveManager = class {
2546
2719
  }, options.signal);
2547
2720
  }
2548
2721
  async open(target, options = {}) {
2549
- const location = await this.#runtime.run(
2550
- async () => await resolveWikiGraphArchiveLocation(target),
2551
- options.signal
2552
- );
2722
+ const location = await this.#runtime.run(async () => {
2723
+ const location2 = await resolveWikiGraphArchiveLocation(target);
2724
+ try {
2725
+ await (0, import_wiki_graph_core7.ensureWikiGraphArchiveSchemaCurrent)(location2.archiveFile);
2726
+ } catch (error) {
2727
+ rethrowArchiveSchemaError(error, target);
2728
+ }
2729
+ return location2;
2730
+ }, options.signal);
2553
2731
  return new WikiGraphArchiveHandle(this.#runtime, location);
2554
2732
  }
2555
2733
  };
@@ -2600,15 +2778,11 @@ var WikiGraphArchiveHandle = class {
2600
2778
  options.queryMode,
2601
2779
  options.signal
2602
2780
  );
2603
- const result = await this.#writeDocument(
2781
+ const result = await this.#readDocument(
2604
2782
  async (document) => {
2605
2783
  const chapters = await this.#resolveQueryChapters(document, options, {
2606
2784
  embeddingProvider
2607
2785
  });
2608
- await ensureArchiveSearchIndex(document, {
2609
- ...chapters === void 0 ? {} : { chapters },
2610
- ...embeddingProvider === void 0 ? {} : { embeddingProvider }
2611
- });
2612
2786
  return await (0, import_wiki_graph_core7.findArchiveObjects)(document, query, {
2613
2787
  ...withoutOperationAndScope(options),
2614
2788
  archiveKey: this.archiveKey,
@@ -2617,7 +2791,6 @@ var WikiGraphArchiveHandle = class {
2617
2791
  });
2618
2792
  },
2619
2793
  {
2620
- searchIndexWritebackPolicy: "cache",
2621
2794
  ...options.signal === void 0 ? {} : { signal: options.signal }
2622
2795
  }
2623
2796
  );
@@ -2722,6 +2895,7 @@ var WikiGraphArchiveHandle = class {
2722
2895
  async (document) => {
2723
2896
  const chapters = await this.#resolveScope(document, options);
2724
2897
  await ensureArchiveSearchIndex(document, {
2898
+ rebuild: true,
2725
2899
  ...chapters === void 0 ? {} : { chapters },
2726
2900
  ...embeddingProvider === void 0 ? {} : { embeddingProvider }
2727
2901
  });
@@ -3011,15 +3185,11 @@ var WikiGraphArchiveHandle = class {
3011
3185
  options.queryMode,
3012
3186
  options.signal
3013
3187
  );
3014
- const result = await this.#writeDocument(
3188
+ const result = await this.#readDocument(
3015
3189
  async (document) => {
3016
3190
  const chapters = await this.#resolveQueryChapters(document, options, {
3017
3191
  embeddingProvider
3018
3192
  });
3019
- await ensureArchiveSearchIndex(document, {
3020
- ...chapters === void 0 ? {} : { chapters },
3021
- ...embeddingProvider === void 0 ? {} : { embeddingProvider }
3022
- });
3023
3193
  return await (0, import_wiki_graph_core7.listRelatedArchiveObjects)(document, objectUri, {
3024
3194
  ...withoutOperation(options),
3025
3195
  ...embeddingProvider === void 0 ? {} : { embeddingProvider },
@@ -3027,7 +3197,6 @@ var WikiGraphArchiveHandle = class {
3027
3197
  });
3028
3198
  },
3029
3199
  {
3030
- searchIndexWritebackPolicy: "cache",
3031
3200
  ...options.signal === void 0 ? {} : { signal: options.signal }
3032
3201
  }
3033
3202
  );
@@ -3071,15 +3240,11 @@ var WikiGraphArchiveHandle = class {
3071
3240
  options.queryMode,
3072
3241
  options.signal
3073
3242
  );
3074
- const result = await this.#writeDocument(
3243
+ const result = await this.#readDocument(
3075
3244
  async (document) => {
3076
3245
  const chapters = await this.#resolveQueryChapters(document, options, {
3077
3246
  embeddingProvider
3078
3247
  });
3079
- await ensureArchiveSearchIndex(document, {
3080
- ...chapters === void 0 ? {} : { chapters },
3081
- ...embeddingProvider === void 0 ? {} : { embeddingProvider }
3082
- });
3083
3248
  return await (0, import_wiki_graph_core7.listArchiveEvidence)(document, objectUri, {
3084
3249
  ...withoutOperation(options),
3085
3250
  ...embeddingProvider === void 0 ? {} : { embeddingProvider },
@@ -3087,7 +3252,6 @@ var WikiGraphArchiveHandle = class {
3087
3252
  });
3088
3253
  },
3089
3254
  {
3090
- searchIndexWritebackPolicy: "cache",
3091
3255
  ...options.signal === void 0 ? {} : { signal: options.signal }
3092
3256
  }
3093
3257
  );
@@ -3204,6 +3368,8 @@ var WikiGraphArchiveHandle = class {
3204
3368
  this.#location.archiveFile
3205
3369
  ).readDocument(operation),
3206
3370
  options.signal
3371
+ ).catch(
3372
+ (error) => rethrowArchiveSchemaError(error, this.#location.target)
3207
3373
  );
3208
3374
  }
3209
3375
  async #writeDocument(operation, options = {}) {
@@ -3215,33 +3381,32 @@ var WikiGraphArchiveHandle = class {
3215
3381
  searchIndexWritebackPolicy: options.searchIndexWritebackPolicy
3216
3382
  }
3217
3383
  });
3218
- }, options.signal);
3384
+ }, options.signal).catch(
3385
+ (error) => rethrowArchiveSchemaError(error, this.#location.target)
3386
+ );
3219
3387
  }
3220
3388
  async #resolveScope(document, options) {
3221
3389
  if (options.chapters !== void 0) return options.chapters;
3222
3390
  return (await resolveArchiveScope(document, this.objectUri, options.depth))?.chapterIds;
3223
3391
  }
3224
3392
  async #resolveQueryChapters(document, options, capabilities) {
3225
- const chapters = await this.#resolveScope(document, options);
3393
+ const parsed = parseChapterScopePath(this.objectUri);
3394
+ const chapters = options.chapters ?? (parsed === void 0 || parsed.kind === "collection" && options.depth === void 0 ? void 0 : await (0, import_wiki_graph_core7.resolveIndexedArchiveChapterScope)(
3395
+ document,
3396
+ parsed.kind === "chapter" ? parsed.chapterPath : void 0,
3397
+ options.depth
3398
+ ));
3226
3399
  const coverageOptions = {
3227
3400
  ...chapters === void 0 ? {} : { chapters },
3228
3401
  ...capabilities.embeddingProvider === void 0 ? {} : { embeddingProvider: capabilities.embeddingProvider },
3229
3402
  requireEmbeddingProvider: true,
3230
3403
  ...options.queryMode === void 0 ? {} : { queryMode: options.queryMode }
3231
3404
  };
3232
- if (options.skipUnindexed !== true) {
3233
- await (0, import_wiki_graph_core7.assertArchiveIndexArtifactsReady)(document, coverageOptions);
3234
- return chapters;
3235
- }
3236
- const queryable = await (0, import_wiki_graph_core7.listArchiveQueryableChapterIds)(document, {
3237
- ...coverageOptions
3405
+ await (0, import_wiki_graph_core7.assertArchiveQueryReady)(document, {
3406
+ ...coverageOptions,
3407
+ ...options.skipUnindexed === void 0 ? {} : { skipUnindexed: options.skipUnindexed }
3238
3408
  });
3239
- if (queryable.length === 0) {
3240
- throw new Error(
3241
- "Wiki Graph query is not ready. No chapters in this scope have a current FTS artifact or source embedding artifact."
3242
- );
3243
- }
3244
- return queryable;
3409
+ return chapters;
3245
3410
  }
3246
3411
  async #resolveQueryEmbeddingProvider(queryMode, signal) {
3247
3412
  if (queryMode === "fts") return void 0;
@@ -3260,6 +3425,10 @@ var WikiGraphArchiveHandle = class {
3260
3425
  async function ensureArchiveSearchIndex(document, options = {}) {
3261
3426
  const scope = options.chapters === void 0 ? {} : { chapters: options.chapters };
3262
3427
  if (await (0, import_wiki_graph_core7.isArchiveSearchIndexCurrent)(document, scope)) return;
3428
+ if (options.rebuild !== true)
3429
+ throw new Error(
3430
+ "Archive search index is missing or dirty. Run `wg <archive-uri>/index sync` explicitly before querying."
3431
+ );
3263
3432
  await (0, import_wiki_graph_core7.rebuildArchiveSearchIndex)(document, void 0, {
3264
3433
  ...scope,
3265
3434
  ...options.embeddingProvider === void 0 ? {} : { embeddingProvider: options.embeddingProvider }
@@ -3639,7 +3808,7 @@ async function continueArchiveCursor(cursor, limit) {
3639
3808
  const location = await resolveWikiGraphArchiveLocation(
3640
3809
  archiveTargetFromLogicalLocator(getCursorArchivePath(cursor))
3641
3810
  );
3642
- const read = async (document) => {
3811
+ const read2 = async (document) => {
3643
3812
  switch (cursor.kind) {
3644
3813
  case "source-locators":
3645
3814
  return await (0, import_wiki_graph_core9.listArchiveSourceLocators)(document, cursor.targetUri, {
@@ -3685,7 +3854,9 @@ async function continueArchiveCursor(cursor, limit) {
3685
3854
  });
3686
3855
  }
3687
3856
  };
3688
- return location.archiveFile.kind === "directory" ? await new import_wiki_graph_core9.WikiGraphDirectoryFile(location.archiveFile).readDocument(read) : await new import_wiki_graph_core9.WikiGraphArchiveFile(location.archiveFile).readDocument(read);
3857
+ return await (location.archiveFile.kind === "directory" ? new import_wiki_graph_core9.WikiGraphDirectoryFile(location.archiveFile).readDocument(read2) : new import_wiki_graph_core9.WikiGraphArchiveFile(location.archiveFile).readDocument(read2)).catch(
3858
+ (error) => rethrowArchiveSchemaError(error, location.target)
3859
+ );
3689
3860
  }
3690
3861
  async function continueLibraryCursor(cursor, limit) {
3691
3862
  const embeddingProvider = cursor.kind === "evidence" || cursor.kind === "related" ? await resolveCursorEmbeddingProvider(cursor) : void 0;
@@ -5124,20 +5295,27 @@ var WikiGraphLibraryManager = class {
5124
5295
  throwIfAborted(options.signal);
5125
5296
  const archive = await (0, import_wiki_graph_core16.getWikiGraphLibraryArchive)(parsedTarget);
5126
5297
  const source = requireReadableLibraryArchiveFile(archive);
5298
+ await (0, import_wiki_graph_core16.ensureWikiGraphArchiveSchemaCurrent)(source).catch(
5299
+ (error) => rethrowArchiveSchemaError(error, {
5300
+ kind: "library",
5301
+ uri: archive.uri
5302
+ })
5303
+ );
5127
5304
  let temporaryDirectory;
5128
- const file = source.kind === "directory" ? await (async () => {
5129
- temporaryDirectory = await (0, import_promises6.mkdtemp)(
5130
- (0, import_path6.join)((0, import_os4.tmpdir)(), "wikigraph-library-read-")
5131
- );
5132
- const output = new NodeFile(
5133
- (0, import_path6.join)(temporaryDirectory, "archive.wikg")
5134
- );
5135
- await (0, import_wiki_graph_core16.writeWikgArchive)(source, output);
5136
- return output;
5137
- })() : source;
5138
- const reader = await file.openReader();
5305
+ let reader;
5139
5306
  let active = true;
5140
5307
  try {
5308
+ const file = source.kind === "directory" ? await (async () => {
5309
+ temporaryDirectory = await (0, import_promises6.mkdtemp)(
5310
+ (0, import_path6.join)((0, import_os4.tmpdir)(), "wikigraph-library-read-")
5311
+ );
5312
+ const output = new NodeFile(
5313
+ (0, import_path6.join)(temporaryDirectory, "archive.wikg")
5314
+ );
5315
+ await (0, import_wiki_graph_core16.writeWikgArchive)(source, output);
5316
+ return output;
5317
+ })() : source;
5318
+ reader = await file.openReader();
5141
5319
  const content = {
5142
5320
  mediaType: "application/vnd.wiki-graph.archive",
5143
5321
  size: reader.size,
@@ -5154,9 +5332,12 @@ var WikiGraphLibraryManager = class {
5154
5332
  );
5155
5333
  } finally {
5156
5334
  active = false;
5157
- await reader.close();
5158
- if (temporaryDirectory !== void 0)
5159
- await (0, import_promises6.rm)(temporaryDirectory, { force: true, recursive: true });
5335
+ try {
5336
+ await reader?.close();
5337
+ } finally {
5338
+ if (temporaryDirectory !== void 0)
5339
+ await (0, import_promises6.rm)(temporaryDirectory, { force: true, recursive: true });
5340
+ }
5160
5341
  }
5161
5342
  },
5162
5343
  options.signal === void 0 ? {} : { signal: options.signal }
@@ -5657,7 +5838,9 @@ var WikiGraphMaintenanceManager = class {
5657
5838
  return await (0, import_wiki_graph_core17.upgradeWikiGraphMaintenanceTarget)({
5658
5839
  file: new NodeFile(path),
5659
5840
  kind: "archive"
5660
- });
5841
+ }).catch(
5842
+ (error) => rethrowArchiveSchemaError(error, { kind: "standalone", path })
5843
+ );
5661
5844
  },
5662
5845
  void 0,
5663
5846
  { skipHomeBootstrap: target.kind === "home" }
@@ -5686,7 +5869,6 @@ function defaultWikgOutputPath(inputPath) {
5686
5869
  var import_wiki_graph_core18 = require("wiki-graph-core");
5687
5870
  var WikiGraphSDK = class {
5688
5871
  #context;
5689
- #homeReady;
5690
5872
  archives;
5691
5873
  conversions;
5692
5874
  config;
@@ -5717,13 +5899,7 @@ var WikiGraphSDK = class {
5717
5899
  throwIfAborted2(signal);
5718
5900
  const runWithContext = async () => await withWikiGraphSDKRuntimeContext(this.#context, async () => {
5719
5901
  if (options.skipHomeBootstrap !== true) {
5720
- this.#homeReady ??= (0, import_wiki_graph_core18.ensureWikiGraphHomeSchemaCurrent)().catch(
5721
- (error) => {
5722
- this.#homeReady = void 0;
5723
- throw error;
5724
- }
5725
- );
5726
- await this.#homeReady;
5902
+ await (0, import_wiki_graph_core18.ensureWikiGraphHomeSchemaCurrent)();
5727
5903
  }
5728
5904
  return await operation();
5729
5905
  });
@@ -5783,6 +5959,7 @@ var import_wiki_graph_core19 = require("wiki-graph-core");
5783
5959
  WikiGraphLibraryManager,
5784
5960
  WikiGraphMaintenanceManager,
5785
5961
  WikiGraphSDK,
5962
+ WikiGraphSchemaVersionError,
5786
5963
  buildSearchIndexEmbeddingProvider,
5787
5964
  buildWikiGraphLLMOptions,
5788
5965
  clearLocalConfigSection,
@@ -5825,6 +6002,7 @@ var import_wiki_graph_core19 = require("wiki-graph-core");
5825
6002
  isSourceLocatorScopeUri,
5826
6003
  isWikiGraphJobUri,
5827
6004
  isWikiGraphLibraryUri,
6005
+ isWikiGraphSchemaVersionError,
5828
6006
  isWikiGraphUri,
5829
6007
  iterateItems,
5830
6008
  iteratePages,