create-windy 0.6.9 → 0.6.10

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 (59) hide show
  1. package/README.md +4 -1
  2. package/dist/cli.js +860 -305
  3. package/package.json +1 -1
  4. package/template/.windy-template.json +3 -3
  5. package/template/README.md +4 -0
  6. package/template/apps/agent-server/src/southwind_agent_server/contracts.py +2 -0
  7. package/template/apps/agent-server/tests/test_multimodal.py +30 -0
  8. package/template/apps/agent-server/tests/test_postgres_store.py +1 -0
  9. package/template/apps/agent-server/tests/test_sqlite_store.py +1 -0
  10. package/template/apps/server/src/agent/remote-runtime.test.ts +1 -0
  11. package/template/apps/server/src/agent/run-audit.ts +1 -0
  12. package/template/apps/server/src/agent/run-contracts.ts +1 -0
  13. package/template/apps/server/src/agent/run-facade.ts +2 -2
  14. package/template/apps/server/src/agent/run-operation-registry.ts +7 -0
  15. package/template/apps/server/src/agent/run-output-schema.ts +15 -0
  16. package/template/apps/server/src/agent/run-release.ts +11 -0
  17. package/template/apps/server/src/agent/supervisor-output-schema.test.ts +95 -0
  18. package/template/apps/server/src/agent/vision-input.ts +37 -2
  19. package/template/apps/server/src/license/pairing-http.ts +138 -0
  20. package/template/apps/server/src/license/pairing-routes.test.ts +282 -0
  21. package/template/apps/server/src/license/pairing-routes.ts +257 -0
  22. package/template/apps/server/src/license/pairing-service.test.ts +320 -0
  23. package/template/apps/server/src/license/pairing-service.ts +321 -0
  24. package/template/apps/server/src/license/restriction.test.ts +11 -0
  25. package/template/apps/server/src/license/restriction.ts +5 -0
  26. package/template/apps/server/src/license/routes.ts +8 -1
  27. package/template/apps/server/src/license/runtime-service.ts +20 -0
  28. package/template/apps/web/package.json +6 -4
  29. package/template/apps/web/src/components/license/LicensePairingCard.vue +177 -0
  30. package/template/apps/web/src/components/license/LicensePairingCard.webtest.ts +113 -0
  31. package/template/apps/web/src/composables/useLicensePairing.ts +168 -0
  32. package/template/apps/web/src/composables/useLicenseRuntime.ts +11 -0
  33. package/template/apps/web/src/pages/license/LicensePage.vue +8 -0
  34. package/template/apps/web/src/services/license-api.ts +60 -0
  35. package/template/apps/web/src/style.webtest.ts +5 -6
  36. package/template/docs/architecture/ai-runtime.md +5 -0
  37. package/template/docs/license/license-pairing-activation.md +67 -0
  38. package/template/docs/operations/incremental-delivery.md +6 -6
  39. package/template/docs/platform/agent-supervisor-output-contract.md +80 -0
  40. package/template/packages/ai-client/package.json +1 -1
  41. package/template/packages/ai-client/src/agent/contracts/final-answer.test.ts +67 -0
  42. package/template/packages/ai-client/src/agent/contracts/final-answer.ts +53 -0
  43. package/template/packages/ai-client/src/agent/contracts/index.ts +1 -0
  44. package/template/packages/modules/index.ts +1 -0
  45. package/template/packages/modules/package.json +1 -1
  46. package/template/packages/modules/src/system-admin-ui-catalog.ts +5 -1
  47. package/template/packages/modules/src/system-agent-supervisor.test.ts +48 -0
  48. package/template/packages/modules/src/system-agent-supervisor.ts +101 -0
  49. package/template/packages/modules/src/system-api-control-plane.ts +37 -0
  50. package/template/packages/modules/src/system-license-pairing.test.ts +44 -0
  51. package/template/packages/modules/src/system-module-catalog.ts +8 -18
  52. package/template/packages/modules/src/system-module-menu-selection.ts +15 -0
  53. package/template/packages/modules/src/system-module-schema-catalog.ts +14 -0
  54. package/template/packages/modules/src/system-modules.ts +2 -0
  55. package/template/packages/server-sdk/index.ts +5 -0
  56. package/template/packages/server-sdk/package.json +3 -1
  57. package/template/packages/server-sdk/src/ai-operation-registration.ts +4 -0
  58. package/template/packages/server-sdk/src/system-agent-supervisor.test.ts +87 -0
  59. package/template/packages/server-sdk/src/system-agent-supervisor.ts +89 -0
package/dist/cli.js CHANGED
@@ -388,6 +388,7 @@ var optionalModuleManifests = [
388
388
  "docs/platform/agent-run-attestation.md",
389
389
  "docs/platform/agent-runtime.md",
390
390
  "docs/platform/agent-runtime-observability.md",
391
+ "docs/platform/agent-supervisor-output-contract.md",
391
392
  "docs/platform/agent-tools.md",
392
393
  "docs/platform/agent-tool-approval.md",
393
394
  "docs/platform/agent-tool-sandbox.md",
@@ -653,7 +654,17 @@ var platformModules = [
653
654
  {
654
655
  sourceName: "@southwind-ai/license",
655
656
  name: "@southwind-ai/license",
656
- version: "^0.1.4"
657
+ version: "^0.1.9"
658
+ },
659
+ {
660
+ sourceName: "qrcode",
661
+ name: "qrcode",
662
+ version: "^1.5.4"
663
+ },
664
+ {
665
+ sourceName: "@types/qrcode",
666
+ name: "@types/qrcode",
667
+ version: "^1.5.6"
657
668
  }
658
669
  ],
659
670
  fileRoots: [
@@ -663,11 +674,16 @@ var platformModules = [
663
674
  "apps/web/src/composables/useLicenseReminderRefresh.ts",
664
675
  "apps/web/src/composables/useLicenseReminderRefresh.webtest.ts",
665
676
  "apps/web/src/composables/useLicenseRuntime.ts",
677
+ "apps/web/src/composables/useLicensePairing.ts",
666
678
  "apps/web/src/services/license-api.ts",
667
679
  "apps/web/src/pages/dashboard/dashboard-presenter.webtest.ts",
668
- "apps/web/src/router/index.webtest.ts"
680
+ "apps/web/src/router/index.webtest.ts",
681
+ "packages/modules/src/system-license-pairing.test.ts"
682
+ ],
683
+ documentation: [
684
+ "docs/license/license-offline-activation-code.md",
685
+ "docs/license/license-pairing-activation.md"
669
686
  ],
670
- documentation: ["docs/license/license-offline-activation-code.md"],
671
687
  schemaFiles: [
672
688
  "packages/database/src/schema/license-legacy.ts",
673
689
  "packages/database/src/schema/license-v1.ts"
@@ -1309,11 +1325,11 @@ import {
1309
1325
  rm as rm4,
1310
1326
  writeFile as writeFile9
1311
1327
  } from "fs/promises";
1312
- import { basename as basename5, extname as extname3, join as join11 } from "path";
1328
+ import { basename as basename6, extname as extname3, join as join12 } from "path";
1313
1329
 
1314
1330
  // src/customer-docker.ts
1315
1331
  import { readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
1316
- import { join as join4 } from "path";
1332
+ import { join as join5 } from "path";
1317
1333
 
1318
1334
  // src/managed-files.ts
1319
1335
  import { createHash } from "crypto";
@@ -1533,37 +1549,38 @@ function matchesRoot(path, roots) {
1533
1549
  }
1534
1550
 
1535
1551
  // src/update/transaction-paths.ts
1536
- import { constants as constants3, closeSync as closeSync4 } from "fs";
1552
+ import { constants as constants4, closeSync as closeSync5 } from "fs";
1537
1553
  import { realpath, stat } from "fs/promises";
1538
- import { dirname as dirname2, resolve as resolve3 } from "path";
1554
+ import { dirname as dirname3, resolve as resolve3 } from "path";
1539
1555
 
1540
1556
  // src/update/transaction-native.ts
1541
1557
  import {
1542
- constants,
1543
- closeSync,
1558
+ constants as constants2,
1559
+ closeSync as closeSync2,
1544
1560
  fchmodSync,
1545
- fstatSync,
1561
+ fstatSync as fstatSync2,
1546
1562
  fsyncSync as fsyncSync2,
1547
1563
  readFileSync,
1548
1564
  writeSync
1549
1565
  } from "fs";
1550
- import { open as open2 } from "fs/promises";
1566
+ import { open as open3 } from "fs/promises";
1551
1567
  import {
1552
- basename as basename2,
1553
- dirname,
1568
+ basename as basename3,
1569
+ dirname as dirname2,
1554
1570
  isAbsolute,
1555
- relative as relative2,
1571
+ relative as relative3,
1556
1572
  resolve as resolve2,
1557
1573
  sep as sep2
1558
1574
  } from "path";
1559
- import { dlopen, FFIType, ptr, read } from "bun:ffi";
1575
+ import { dlopen as dlopen2, FFIType as FFIType2, ptr as ptr2, read } from "bun:ffi";
1560
1576
 
1561
1577
  // src/update/transaction-native-durability.ts
1562
1578
  import { fsyncSync } from "fs";
1563
1579
  var observer;
1564
1580
  function syncMutatedDirectory(operation, directoryFd) {
1565
1581
  observer?.({ operation, phase: "mutation", directoryFd });
1566
- fsyncSync(directoryFd);
1582
+ if (process.platform !== "win32")
1583
+ fsyncSync(directoryFd);
1567
1584
  observer?.({ operation, phase: "directory-fsync", directoryFd });
1568
1585
  }
1569
1586
 
@@ -1624,38 +1641,305 @@ function libcCandidates() {
1624
1641
  ];
1625
1642
  }
1626
1643
 
1644
+ // src/update/transaction-native-windows.ts
1645
+ import {
1646
+ closeSync,
1647
+ constants,
1648
+ fstatSync,
1649
+ linkSync,
1650
+ lstatSync,
1651
+ mkdirSync,
1652
+ openSync,
1653
+ rmdirSync,
1654
+ unlinkSync
1655
+ } from "fs";
1656
+ import { open as open2 } from "fs/promises";
1657
+ import { basename as basename2, dirname, join as join3, relative as relative2 } from "path";
1658
+
1659
+ // src/update/transaction-windows-api.ts
1660
+ import { dlopen, FFIType, ptr } from "bun:ffi";
1661
+ var moveFileWriteThrough = 8;
1662
+ var replaceFileWriteThrough = 2;
1663
+ var kernel32;
1664
+ function replaceWindowsFile(target, replacement, backup) {
1665
+ const api = windowsApi();
1666
+ const targetBuffer = wideString(target);
1667
+ const replacementBuffer = wideString(replacement);
1668
+ const backupBuffer = backup ? wideString(backup) : undefined;
1669
+ const result = api.symbols.ReplaceFileW(ptr(targetBuffer), ptr(replacementBuffer), backupBuffer ? ptr(backupBuffer) : null, replaceFileWriteThrough, null, null);
1670
+ if (!result)
1671
+ throw windowsError("ReplaceFileW", target);
1672
+ }
1673
+ function moveWindowsFileNoReplace(source, target) {
1674
+ const api = windowsApi();
1675
+ const sourceBuffer = wideString(source);
1676
+ const targetBuffer = wideString(target);
1677
+ if (!api.symbols.MoveFileExW(ptr(sourceBuffer), ptr(targetBuffer), moveFileWriteThrough)) {
1678
+ throw windowsError("MoveFileExW", `${source} -> ${target}`);
1679
+ }
1680
+ }
1681
+ function windowsApi() {
1682
+ if (process.env.WINDY_TEST_NATIVE_UNAVAILABLE === "1") {
1683
+ throw new Error("\u5F53\u524D\u5E73\u53F0\u65E0\u6CD5\u52A0\u8F7D\u5B89\u5168\u76EE\u5F55\u53E5\u67C4 API\uFF1A\u6D4B\u8BD5\u4E0D\u53EF\u7528\u5E73\u53F0");
1684
+ }
1685
+ if (process.platform !== "win32") {
1686
+ throw new Error("Windows \u539F\u5B50\u76EE\u5F55\u9879 API \u5728\u5F53\u524D\u5E73\u53F0\u4E0D\u53EF\u7528");
1687
+ }
1688
+ return kernel32 ??= openWindowsApi();
1689
+ }
1690
+ function openWindowsApi() {
1691
+ return dlopen("kernel32.dll", {
1692
+ GetLastError: { args: [], returns: FFIType.u32 },
1693
+ MoveFileExW: {
1694
+ args: [FFIType.ptr, FFIType.ptr, FFIType.u32],
1695
+ returns: FFIType.i32
1696
+ },
1697
+ ReplaceFileW: {
1698
+ args: [
1699
+ FFIType.ptr,
1700
+ FFIType.ptr,
1701
+ FFIType.ptr,
1702
+ FFIType.u32,
1703
+ FFIType.ptr,
1704
+ FFIType.ptr
1705
+ ],
1706
+ returns: FFIType.i32
1707
+ }
1708
+ });
1709
+ }
1710
+ function windowsError(syscall, path) {
1711
+ const nativeCode = windowsApi().symbols.GetLastError();
1712
+ const code = nativeCode === 2 || nativeCode === 3 ? "ENOENT" : nativeCode === 80 || nativeCode === 183 ? "EEXIST" : nativeCode === 145 ? "ENOTEMPTY" : nativeCode === 5 ? "EACCES" : "EIO";
1713
+ return Object.assign(new Error(`${syscall} ${path} \u5931\u8D25\uFF08${nativeCode}\uFF09`), {
1714
+ code,
1715
+ errno: nativeCode,
1716
+ syscall,
1717
+ path
1718
+ });
1719
+ }
1720
+ function wideString(value) {
1721
+ return Buffer.from(`${value}\x00`, "utf16le");
1722
+ }
1723
+
1724
+ // src/update/transaction-native-windows.ts
1725
+ var directoryPaths = new Map;
1726
+ async function openWindowsAnchoredParent(root, target, createParents, createdDirectoryMode) {
1727
+ const parentPath = dirname(target);
1728
+ const relativeParent = relative2(root, parentPath);
1729
+ const components = relativeParent ? relativeParent.split(/[\\/]/) : [];
1730
+ const handles = [];
1731
+ const rootHandle = await openCheckedDirectory(root);
1732
+ handles.push(rootHandle);
1733
+ let currentPath = root;
1734
+ try {
1735
+ for (const component of components) {
1736
+ currentPath = join3(currentPath, component);
1737
+ try {
1738
+ assertDirectoryPath(currentPath);
1739
+ } catch (error) {
1740
+ if (!createParents || !hasFsCode(error, "ENOENT"))
1741
+ throw error;
1742
+ mkdirSync(currentPath, { mode: createdDirectoryMode });
1743
+ syncMutatedDirectory("mkdirat", handles.at(-1).fd);
1744
+ }
1745
+ handles.push(await openCheckedDirectory(currentPath));
1746
+ }
1747
+ } catch (error) {
1748
+ await closeHandles(handles);
1749
+ throw error;
1750
+ }
1751
+ const directoryHandle = handles.at(-1);
1752
+ return {
1753
+ fd: directoryHandle.fd,
1754
+ leaf: basename2(target),
1755
+ directoryPath: currentPath,
1756
+ async close() {
1757
+ await closeHandles(handles);
1758
+ }
1759
+ };
1760
+ }
1761
+ function windowsOpenFileAt(parent, flags, mode) {
1762
+ const directoryPath = parent.directoryPath ?? windowsDirectoryPath(parent.fd);
1763
+ assertDirectoryHandle(parent.fd, directoryPath);
1764
+ const path = childPath(directoryPath, parent.leaf);
1765
+ let before;
1766
+ try {
1767
+ before = lstatSync(path, { bigint: true });
1768
+ if (before.isSymbolicLink())
1769
+ throw reparseError(path);
1770
+ } catch (error) {
1771
+ if (!hasFsCode(error, "ENOENT"))
1772
+ throw error;
1773
+ }
1774
+ const fd = openSync(path, flags, mode);
1775
+ try {
1776
+ if (before) {
1777
+ const opened = fstatSync(fd, { bigint: true });
1778
+ if (opened.dev !== before.dev || opened.ino !== before.ino) {
1779
+ throw reparseError(path);
1780
+ }
1781
+ }
1782
+ return fd;
1783
+ } catch (error) {
1784
+ closeSync(fd);
1785
+ throw error;
1786
+ }
1787
+ }
1788
+ function windowsLinkAt(parent, sourceName, targetName) {
1789
+ assertDirectoryHandle(parent.fd, parent.directoryPath);
1790
+ linkSync(childPath(parent.directoryPath, sourceName), childPath(parent.directoryPath, targetName));
1791
+ }
1792
+ function windowsUnlinkAt(parent, name, directory) {
1793
+ assertDirectoryHandle(parent.fd, parent.directoryPath);
1794
+ const path = childPath(parent.directoryPath, name);
1795
+ const info = lstatSync(path);
1796
+ if (info.isSymbolicLink())
1797
+ throw reparseError(path);
1798
+ if (directory)
1799
+ rmdirSync(path);
1800
+ else
1801
+ unlinkSync(path);
1802
+ }
1803
+ function windowsOpenChildDirectoryAt(directoryFd, name) {
1804
+ const parentPath = windowsDirectoryPath(directoryFd);
1805
+ assertDirectoryHandle(directoryFd, parentPath);
1806
+ const path = childPath(parentPath, name);
1807
+ assertDirectoryPath(path);
1808
+ const fd = openSync(path, constants.O_RDONLY);
1809
+ try {
1810
+ registerDirectory(fd, path);
1811
+ assertDirectoryHandle(fd, path);
1812
+ return fd;
1813
+ } catch (error) {
1814
+ directoryPaths.delete(fd);
1815
+ closeSync(fd);
1816
+ throw error;
1817
+ }
1818
+ }
1819
+ function closeWindowsDirectoryFd(fd) {
1820
+ directoryPaths.delete(fd);
1821
+ closeSync(fd);
1822
+ }
1823
+ function windowsExchangeAt(parent, left, right) {
1824
+ assertDirectoryHandle(parent.fd, parent.directoryPath);
1825
+ const leftPath = childPath(parent.directoryPath, left);
1826
+ const rightPath = childPath(parent.directoryPath, right);
1827
+ const backupPath = `${leftPath}.exchange-backup`;
1828
+ assertMissing(backupPath);
1829
+ replaceWindowsFile(rightPath, leftPath, backupPath);
1830
+ try {
1831
+ moveWindowsFileNoReplace(backupPath, leftPath);
1832
+ } catch (error) {
1833
+ try {
1834
+ replaceWindowsFile(rightPath, backupPath);
1835
+ } catch {}
1836
+ throw error;
1837
+ }
1838
+ }
1839
+ function windowsMoveNoReplaceAt(parent, source, target) {
1840
+ assertDirectoryHandle(parent.fd, parent.directoryPath);
1841
+ moveWindowsFileNoReplace(childPath(parent.directoryPath, source), childPath(parent.directoryPath, target));
1842
+ }
1843
+ function windowsDirectoryPath(fd) {
1844
+ const path = directoryPaths.get(fd);
1845
+ if (!path)
1846
+ throw new Error("Windows \u4E8B\u52A1\u76EE\u5F55\u53E5\u67C4\u672A\u6CE8\u518C\uFF0C\u4E8B\u52A1\u5B89\u5168\u5173\u95ED");
1847
+ return path;
1848
+ }
1849
+ async function openCheckedDirectory(path) {
1850
+ assertDirectoryPath(path);
1851
+ const handle = await open2(path, constants.O_RDONLY);
1852
+ try {
1853
+ registerDirectory(handle.fd, path);
1854
+ assertDirectoryHandle(handle.fd, path);
1855
+ return handle;
1856
+ } catch (error) {
1857
+ directoryPaths.delete(handle.fd);
1858
+ await handle.close();
1859
+ throw error;
1860
+ }
1861
+ }
1862
+ function registerDirectory(fd, path) {
1863
+ directoryPaths.set(fd, path);
1864
+ }
1865
+ async function closeHandles(handles) {
1866
+ for (const handle of handles.reverse()) {
1867
+ directoryPaths.delete(handle.fd);
1868
+ await handle.close();
1869
+ }
1870
+ }
1871
+ function assertDirectoryPath(path) {
1872
+ const info = lstatSync(path, { bigint: true });
1873
+ if (info.isSymbolicLink())
1874
+ throw reparseError(path);
1875
+ if (!info.isDirectory())
1876
+ throw fsError("ENOTDIR", path);
1877
+ }
1878
+ function assertDirectoryHandle(fd, path) {
1879
+ const opened = fstatSync(fd, { bigint: true });
1880
+ const current = lstatSync(path, { bigint: true });
1881
+ if (current.isSymbolicLink() || !opened.isDirectory() || !current.isDirectory() || opened.dev !== current.dev || opened.ino !== current.ino) {
1882
+ throw reparseError(path);
1883
+ }
1884
+ }
1885
+ function childPath(directory, name) {
1886
+ if (!name || name.includes("/") || name.includes("\\") || name.includes("\x00")) {
1887
+ throw new Error(`Windows \u4E8B\u52A1\u76EE\u5F55\u9879\u540D\u79F0\u4E0D\u5B89\u5168\uFF1A${name}`);
1888
+ }
1889
+ return join3(directory, name);
1890
+ }
1891
+ function assertMissing(path) {
1892
+ try {
1893
+ lstatSync(path);
1894
+ } catch (error) {
1895
+ if (hasFsCode(error, "ENOENT"))
1896
+ return;
1897
+ throw error;
1898
+ }
1899
+ throw fsError("EEXIST", path);
1900
+ }
1901
+ function reparseError(path) {
1902
+ return fsError("ELOOP", path);
1903
+ }
1904
+ function fsError(code, path) {
1905
+ return Object.assign(new Error(`${code}: ${path}`), { code, path });
1906
+ }
1907
+ function hasFsCode(error, code) {
1908
+ return error instanceof Error && "code" in error && error.code === code;
1909
+ }
1910
+
1627
1911
  // src/update/transaction-native.ts
1628
1912
  var nativeSymbols = {
1629
1913
  openat: {
1630
- args: [FFIType.i32, FFIType.ptr, FFIType.i32, FFIType.i32],
1631
- returns: FFIType.i32
1914
+ args: [FFIType2.i32, FFIType2.ptr, FFIType2.i32, FFIType2.i32],
1915
+ returns: FFIType2.i32
1632
1916
  },
1633
1917
  mkdirat: {
1634
- args: [FFIType.i32, FFIType.ptr, FFIType.i32],
1635
- returns: FFIType.i32
1918
+ args: [FFIType2.i32, FFIType2.ptr, FFIType2.i32],
1919
+ returns: FFIType2.i32
1636
1920
  },
1637
1921
  linkat: {
1638
- args: [FFIType.i32, FFIType.ptr, FFIType.i32, FFIType.ptr, FFIType.i32],
1639
- returns: FFIType.i32
1922
+ args: [FFIType2.i32, FFIType2.ptr, FFIType2.i32, FFIType2.ptr, FFIType2.i32],
1923
+ returns: FFIType2.i32
1640
1924
  },
1641
1925
  unlinkat: {
1642
- args: [FFIType.i32, FFIType.ptr, FFIType.i32],
1643
- returns: FFIType.i32
1926
+ args: [FFIType2.i32, FFIType2.ptr, FFIType2.i32],
1927
+ returns: FFIType2.i32
1644
1928
  },
1645
1929
  [process.platform === "darwin" ? "__error" : "__errno_location"]: {
1646
1930
  args: [],
1647
- returns: FFIType.ptr
1931
+ returns: FFIType2.ptr
1648
1932
  }
1649
1933
  };
1650
- var directoryFlags = constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW;
1934
+ var directoryFlags = constants2.O_RDONLY | constants2.O_DIRECTORY | constants2.O_NOFOLLOW;
1651
1935
  var removeDirectoryFlag = process.platform === "darwin" ? 128 : 512;
1652
- var getLibc = createLazyLibcLoader((candidate) => dlopen(candidate, nativeSymbols), "\u5F53\u524D\u5E73\u53F0\u65E0\u6CD5\u52A0\u8F7D\u5B89\u5168\u76EE\u5F55\u53E5\u67C4 API");
1936
+ var getLibc = createLazyLibcLoader((candidate) => dlopen2(candidate, nativeSymbols), "\u5F53\u524D\u5E73\u53F0\u65E0\u6CD5\u52A0\u8F7D\u5B89\u5168\u76EE\u5F55\u53E5\u67C4 API");
1653
1937
  function resolveSafeTarget(root, path) {
1654
1938
  if (!path || isAbsolute(path) || path.includes("\x00") || path.split(/[\\/]/).includes("..")) {
1655
1939
  throw new Error(`\u66F4\u65B0\u8BA1\u5212\u5305\u542B\u4E0D\u5B89\u5168\u8DEF\u5F84\uFF1A${path}`);
1656
1940
  }
1657
1941
  const target = resolve2(root, path);
1658
- const pathFromRoot = relative2(root, target);
1942
+ const pathFromRoot = relative3(root, target);
1659
1943
  if (pathFromRoot === ".." || pathFromRoot.startsWith(`..${sep2}`) || isAbsolute(pathFromRoot)) {
1660
1944
  throw new Error(`\u66F4\u65B0\u8BA1\u5212\u5305\u542B\u4E0D\u5B89\u5168\u8DEF\u5F84\uFF1A${path}`);
1661
1945
  }
@@ -1663,9 +1947,15 @@ function resolveSafeTarget(root, path) {
1663
1947
  }
1664
1948
  async function openAnchoredParent(root, path, createParents, createdDirectoryMode = 448) {
1665
1949
  const target = resolveSafeTarget(root, path);
1666
- const parentPath = relative2(root, dirname(target));
1950
+ if (process.platform === "win32") {
1951
+ if (process.env.WINDY_TEST_NATIVE_UNAVAILABLE === "1") {
1952
+ throw new Error("\u5F53\u524D\u5E73\u53F0\u65E0\u6CD5\u52A0\u8F7D\u5B89\u5168\u76EE\u5F55\u53E5\u67C4 API\uFF1A\u6D4B\u8BD5\u4E0D\u53EF\u7528\u5E73\u53F0");
1953
+ }
1954
+ return openWindowsAnchoredParent(root, target, createParents, createdDirectoryMode);
1955
+ }
1956
+ const parentPath = relative3(root, dirname2(target));
1667
1957
  const components = parentPath === "" ? [] : parentPath.split(sep2).filter(Boolean);
1668
- const rootHandle = await open2(root, directoryFlags);
1958
+ const rootHandle = await open3(root, directoryFlags);
1669
1959
  const childDescriptors = [];
1670
1960
  let current = rootHandle.fd;
1671
1961
  try {
@@ -1675,13 +1965,13 @@ async function openAnchoredParent(root, path, createParents, createdDirectoryMod
1675
1965
  try {
1676
1966
  child = nativeOpenAt(current, component, directoryFlags);
1677
1967
  } catch (error) {
1678
- if (!createParents || !hasFsCode(error, "ENOENT"))
1968
+ if (!createParents || !hasFsCode2(error, "ENOENT"))
1679
1969
  throw error;
1680
1970
  try {
1681
1971
  nativeMkdirAt(current, component, createdDirectoryMode);
1682
1972
  created = true;
1683
1973
  } catch (mkdirError) {
1684
- if (!hasFsCode(mkdirError, "EEXIST"))
1974
+ if (!hasFsCode2(mkdirError, "EEXIST"))
1685
1975
  throw mkdirError;
1686
1976
  }
1687
1977
  child = nativeOpenAt(current, component, directoryFlags);
@@ -1698,7 +1988,7 @@ async function openAnchoredParent(root, path, createParents, createdDirectoryMod
1698
1988
  }
1699
1989
  return {
1700
1990
  fd: current,
1701
- leaf: basename2(target),
1991
+ leaf: basename3(target),
1702
1992
  async close() {
1703
1993
  closeDescriptors(childDescriptors);
1704
1994
  await rootHandle.close();
@@ -1706,32 +1996,35 @@ async function openAnchoredParent(root, path, createParents, createdDirectoryMod
1706
1996
  };
1707
1997
  }
1708
1998
  function openFileAt(parent, flags, mode = 384) {
1999
+ if (process.platform === "win32") {
2000
+ return windowsOpenFileAt(parent, flags, mode);
2001
+ }
1709
2002
  return nativeOpenAt(parent.fd, parent.leaf, flags, mode);
1710
2003
  }
1711
2004
  function readFileAt(parent) {
1712
- const fd = openFileAt(parent, constants.O_RDONLY | constants.O_NOFOLLOW);
2005
+ const fd = openFileAt(parent, constants2.O_RDONLY | constants2.O_NOFOLLOW);
1713
2006
  try {
1714
- const info = fstatSync(fd);
2007
+ const info = fstatSync2(fd);
1715
2008
  if (!info.isFile())
1716
2009
  throw new Error(`\u4E8B\u52A1\u76EE\u6807\u4E0D\u662F\u666E\u901A\u6587\u4EF6\uFF1A${parent.leaf}`);
1717
2010
  return readFileSync(fd);
1718
2011
  } finally {
1719
- closeSync(fd);
2012
+ closeSync2(fd);
1720
2013
  }
1721
2014
  }
1722
2015
  function fileModeAt(parent) {
1723
- const fd = openFileAt(parent, constants.O_RDONLY | constants.O_NOFOLLOW);
2016
+ const fd = openFileAt(parent, constants2.O_RDONLY | constants2.O_NOFOLLOW);
1724
2017
  try {
1725
- const info = fstatSync(fd);
2018
+ const info = fstatSync2(fd);
1726
2019
  if (!info.isFile())
1727
2020
  throw new Error(`\u4E8B\u52A1\u76EE\u6807\u4E0D\u662F\u666E\u901A\u6587\u4EF6\uFF1A${parent.leaf}`);
1728
2021
  return info.mode & 511;
1729
2022
  } finally {
1730
- closeSync(fd);
2023
+ closeSync2(fd);
1731
2024
  }
1732
2025
  }
1733
2026
  function writeExclusiveAt(parent, content, mode = 384) {
1734
- const fd = openFileAt(parent, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, mode);
2027
+ const fd = openFileAt(parent, constants2.O_WRONLY | constants2.O_CREAT | constants2.O_EXCL | constants2.O_NOFOLLOW, mode);
1735
2028
  try {
1736
2029
  fchmodSync(fd, mode);
1737
2030
  const buffer = typeof content === "string" ? Buffer.from(content) : Buffer.from(content);
@@ -1741,34 +2034,58 @@ function writeExclusiveAt(parent, content, mode = 384) {
1741
2034
  }
1742
2035
  fsyncSync2(fd);
1743
2036
  } finally {
1744
- closeSync(fd);
2037
+ closeSync2(fd);
1745
2038
  }
1746
2039
  syncMutatedDirectory("create", parent.fd);
1747
2040
  }
1748
2041
  function linkAt(parent, sourceName, targetName) {
2042
+ if (process.platform === "win32") {
2043
+ windowsLinkAt(parent, sourceName, targetName);
2044
+ syncMutatedDirectory("linkat", parent.fd);
2045
+ return;
2046
+ }
1749
2047
  const libc = getLibc();
1750
2048
  const sourceBuffer = cString(sourceName);
1751
2049
  const targetBuffer = cString(targetName);
1752
- if (libc.symbols.linkat(parent.fd, ptr(sourceBuffer), parent.fd, ptr(targetBuffer), 0) < 0) {
2050
+ if (libc.symbols.linkat(parent.fd, ptr2(sourceBuffer), parent.fd, ptr2(targetBuffer), 0) < 0) {
1753
2051
  throw nativeError("linkat", `${sourceName} -> ${targetName}`);
1754
2052
  }
1755
2053
  syncMutatedDirectory("linkat", parent.fd);
1756
2054
  }
1757
2055
  function unlinkAt(parent, directory = false) {
2056
+ if (process.platform === "win32") {
2057
+ windowsUnlinkAt(parent, parent.leaf, directory);
2058
+ syncMutatedDirectory("unlinkat", parent.fd);
2059
+ return;
2060
+ }
1758
2061
  nativeUnlinkAt(parent.fd, parent.leaf, directory ? removeDirectoryFlag : 0);
1759
2062
  syncMutatedDirectory("unlinkat", parent.fd);
1760
2063
  }
1761
2064
  function openChildDirectoryAt(directoryFd, name) {
2065
+ if (process.platform === "win32") {
2066
+ return windowsOpenChildDirectoryAt(directoryFd, name);
2067
+ }
1762
2068
  return nativeOpenAt(directoryFd, name, directoryFlags);
1763
2069
  }
1764
2070
  function unlinkNameAt(directoryFd, name, directory = false) {
2071
+ if (process.platform === "win32") {
2072
+ const parent = {
2073
+ fd: directoryFd,
2074
+ leaf: name,
2075
+ directoryPath: windowsDirectoryPath(directoryFd),
2076
+ async close() {}
2077
+ };
2078
+ windowsUnlinkAt(parent, name, directory);
2079
+ syncMutatedDirectory("unlinkat", directoryFd);
2080
+ return;
2081
+ }
1765
2082
  nativeUnlinkAt(directoryFd, name, directory ? removeDirectoryFlag : 0);
1766
2083
  syncMutatedDirectory("unlinkat", directoryFd);
1767
2084
  }
1768
2085
  function nativeOpenAt(directoryFd, name, flags, mode = 0) {
1769
2086
  const libc = getLibc();
1770
2087
  const nameBuffer = cString(name);
1771
- const result = libc.symbols.openat(directoryFd, ptr(nameBuffer), flags, mode);
2088
+ const result = libc.symbols.openat(directoryFd, ptr2(nameBuffer), flags, mode);
1772
2089
  if (result < 0)
1773
2090
  throw nativeError("openat", name);
1774
2091
  return result;
@@ -1776,7 +2093,7 @@ function nativeOpenAt(directoryFd, name, flags, mode = 0) {
1776
2093
  function nativeMkdirAt(directoryFd, name, mode) {
1777
2094
  const libc = getLibc();
1778
2095
  const nameBuffer = cString(name);
1779
- if (libc.symbols.mkdirat(directoryFd, ptr(nameBuffer), mode) < 0) {
2096
+ if (libc.symbols.mkdirat(directoryFd, ptr2(nameBuffer), mode) < 0) {
1780
2097
  throw nativeError("mkdirat", name);
1781
2098
  }
1782
2099
  syncMutatedDirectory("mkdirat", directoryFd);
@@ -1784,7 +2101,7 @@ function nativeMkdirAt(directoryFd, name, mode) {
1784
2101
  function nativeUnlinkAt(directoryFd, name, flags) {
1785
2102
  const libc = getLibc();
1786
2103
  const nameBuffer = cString(name);
1787
- if (libc.symbols.unlinkat(directoryFd, ptr(nameBuffer), flags) < 0) {
2104
+ if (libc.symbols.unlinkat(directoryFd, ptr2(nameBuffer), flags) < 0) {
1788
2105
  throw nativeError("unlinkat", name);
1789
2106
  }
1790
2107
  }
@@ -1808,35 +2125,38 @@ function cString(value) {
1808
2125
  }
1809
2126
  function closeDescriptors(descriptors) {
1810
2127
  for (const descriptor of descriptors.reverse())
1811
- closeSync(descriptor);
2128
+ closeSync2(descriptor);
1812
2129
  }
1813
- function hasFsCode(error, code) {
2130
+ function hasFsCode2(error, code) {
1814
2131
  return error instanceof Error && "code" in error && error.code === code;
1815
2132
  }
1816
2133
 
1817
2134
  // src/update/transaction-tree.ts
1818
- import { constants as constants2, closeSync as closeSync3, fstatSync as fstatSync2 } from "fs";
2135
+ import { constants as constants3, closeSync as closeSync4, fstatSync as fstatSync3 } from "fs";
1819
2136
 
1820
2137
  // src/update/transaction-native-directory.ts
1821
- import { closeSync as closeSync2 } from "fs";
1822
- import { dlopen as dlopen2, FFIType as FFIType2, read as read2, toArrayBuffer } from "bun:ffi";
2138
+ import { closeSync as closeSync3, readdirSync } from "fs";
2139
+ import { dlopen as dlopen3, FFIType as FFIType3, read as read2, toArrayBuffer } from "bun:ffi";
1823
2140
  var errnoName = process.platform === "darwin" ? "__error" : "__errno_location";
1824
2141
  var symbols = {
1825
- dup: { args: [FFIType2.i32], returns: FFIType2.i32 },
1826
- fdopendir: { args: [FFIType2.i32], returns: FFIType2.ptr },
1827
- readdir: { args: [FFIType2.ptr], returns: FFIType2.ptr },
1828
- closedir: { args: [FFIType2.ptr], returns: FFIType2.i32 },
1829
- [errnoName]: { args: [], returns: FFIType2.ptr }
2142
+ dup: { args: [FFIType3.i32], returns: FFIType3.i32 },
2143
+ fdopendir: { args: [FFIType3.i32], returns: FFIType3.ptr },
2144
+ readdir: { args: [FFIType3.ptr], returns: FFIType3.ptr },
2145
+ closedir: { args: [FFIType3.ptr], returns: FFIType3.i32 },
2146
+ [errnoName]: { args: [], returns: FFIType3.ptr }
1830
2147
  };
1831
- var getLibc2 = createLazyLibcLoader((candidate) => dlopen2(candidate, symbols), "\u65E0\u6CD5\u52A0\u8F7D\u5B89\u5168\u76EE\u5F55\u679A\u4E3E API\uFF0C\u4E8B\u52A1\u5B89\u5168\u5173\u95ED");
2148
+ var getLibc2 = createLazyLibcLoader((candidate) => dlopen3(candidate, symbols), "\u65E0\u6CD5\u52A0\u8F7D\u5B89\u5168\u76EE\u5F55\u679A\u4E3E API\uFF0C\u4E8B\u52A1\u5B89\u5168\u5173\u95ED");
1832
2149
  function readDirectoryNames(directoryFd) {
2150
+ if (process.platform === "win32") {
2151
+ return readdirSync(windowsDirectoryPath(directoryFd));
2152
+ }
1833
2153
  const libc = getLibc2();
1834
2154
  const duplicate = libc.symbols.dup(directoryFd);
1835
2155
  if (duplicate < 0)
1836
2156
  throw new Error("\u65E0\u6CD5\u590D\u5236\u5907\u4EFD\u76EE\u5F55\u53E5\u67C4\uFF0C\u4E8B\u52A1\u5B89\u5168\u5173\u95ED");
1837
2157
  const directory = libc.symbols.fdopendir(duplicate);
1838
2158
  if (!directory) {
1839
- closeSync2(duplicate);
2159
+ closeSync3(duplicate);
1840
2160
  throw new Error("\u65E0\u6CD5\u8BFB\u53D6\u5907\u4EFD\u76EE\u5F55\u53E5\u67C4\uFF0C\u4E8B\u52A1\u5B89\u5168\u5173\u95ED");
1841
2161
  }
1842
2162
  const names = [];
@@ -1891,7 +2211,7 @@ async function removeKnownTree(root, path, knownFiles, hooks) {
1891
2211
  try {
1892
2212
  parent = await openAnchoredParent(root, path, false);
1893
2213
  } catch (error) {
1894
- if (hasFsCode2(error, "ENOENT"))
2214
+ if (hasFsCode3(error, "ENOENT"))
1895
2215
  return;
1896
2216
  throw safePathError(error, path);
1897
2217
  }
@@ -1908,11 +2228,11 @@ async function removeKnownTree(root, path, knownFiles, hooks) {
1908
2228
  }
1909
2229
  unlinkAt(parent, true);
1910
2230
  } catch (error) {
1911
- if (!hasFsCode2(error, "ENOENT"))
2231
+ if (!hasFsCode3(error, "ENOENT"))
1912
2232
  throw safePathError(error, path);
1913
2233
  } finally {
1914
2234
  if (treeFd !== undefined)
1915
- closeSync3(treeFd);
2235
+ closeDirectory(treeFd);
1916
2236
  await parent.close();
1917
2237
  }
1918
2238
  }
@@ -1934,7 +2254,7 @@ function inspectDirectory(directoryFd, directory, expected) {
1934
2254
  try {
1935
2255
  inspectDirectory(childFd, directory ? `${directory}/${name}` : name, expected);
1936
2256
  } finally {
1937
- closeSync3(childFd);
2257
+ closeDirectory(childFd);
1938
2258
  }
1939
2259
  }
1940
2260
  }
@@ -1944,13 +2264,13 @@ function assertRegularFile(directoryFd, name) {
1944
2264
  leaf: name,
1945
2265
  async close() {}
1946
2266
  };
1947
- const fileFd = openFileAt(parent, constants2.O_RDONLY | constants2.O_NOFOLLOW | constants2.O_NONBLOCK);
2267
+ const fileFd = openFileAt(parent, constants3.O_RDONLY | constants3.O_NOFOLLOW | constants3.O_NONBLOCK);
1948
2268
  try {
1949
- if (!fstatSync2(fileFd).isFile()) {
2269
+ if (!fstatSync3(fileFd).isFile()) {
1950
2270
  throw new Error(`\u5907\u4EFD\u6761\u76EE\u7C7B\u578B\u5F02\u5E38\uFF1A${name}`);
1951
2271
  }
1952
2272
  } finally {
1953
- closeSync3(fileFd);
2273
+ closeSync4(fileFd);
1954
2274
  }
1955
2275
  }
1956
2276
  function expectedTree(files) {
@@ -1996,13 +2316,19 @@ async function removeTreeEntry(treeFd, path, directory) {
1996
2316
  }
1997
2317
  unlinkNameAt(current, leaf, directory);
1998
2318
  } catch (error) {
1999
- if (!hasFsCode2(error, "ENOENT"))
2319
+ if (!hasFsCode3(error, "ENOENT"))
2000
2320
  throw error;
2001
2321
  } finally {
2002
2322
  for (const descriptor of descriptors.reverse())
2003
- closeSync3(descriptor);
2323
+ closeDirectory(descriptor);
2004
2324
  }
2005
2325
  }
2326
+ function closeDirectory(fd) {
2327
+ if (process.platform === "win32")
2328
+ closeWindowsDirectoryFd(fd);
2329
+ else
2330
+ closeSync4(fd);
2331
+ }
2006
2332
  function assertKnownTreePath(path) {
2007
2333
  const parts = path.split("/");
2008
2334
  if (!path || path.includes("\\") || path.includes("\x00") || parts.some((part) => !part || part === "." || part === "..")) {
@@ -2011,14 +2337,14 @@ function assertKnownTreePath(path) {
2011
2337
  return parts.join("/");
2012
2338
  }
2013
2339
  function safePathError(error, path) {
2014
- if (hasFsCode2(error, "ELOOP") || hasFsCode2(error, "ENOTDIR")) {
2340
+ if (hasFsCode3(error, "ELOOP") || hasFsCode3(error, "ENOTDIR")) {
2015
2341
  return new Error(`\u4E8B\u52A1\u8DEF\u5F84\u5305\u542B\u7B26\u53F7\u94FE\u63A5\u6216\u975E\u76EE\u5F55\u7EC4\u4EF6\uFF1A${path}`, {
2016
2342
  cause: error
2017
2343
  });
2018
2344
  }
2019
2345
  return error;
2020
2346
  }
2021
- function hasFsCode2(error, code) {
2347
+ function hasFsCode3(error, code) {
2022
2348
  return error instanceof Error && "code" in error && error.code === code;
2023
2349
  }
2024
2350
 
@@ -2041,15 +2367,15 @@ async function inspectSafePath(root, path) {
2041
2367
  try {
2042
2368
  parent = await openAnchoredParent(root, path, false);
2043
2369
  } catch (error) {
2044
- if (hasFsCode3(error, "ENOENT"))
2370
+ if (hasFsCode4(error, "ENOENT"))
2045
2371
  return target;
2046
2372
  throw safePathError2(error, path);
2047
2373
  }
2048
2374
  try {
2049
- const fd = openFileAt(parent, constants3.O_RDONLY | constants3.O_NOFOLLOW);
2050
- closeSync4(fd);
2375
+ const fd = openFileAt(parent, constants4.O_RDONLY | constants4.O_NOFOLLOW);
2376
+ closeSync5(fd);
2051
2377
  } catch (error) {
2052
- if (hasFsCode3(error, "ENOENT"))
2378
+ if (hasFsCode4(error, "ENOENT"))
2053
2379
  return target;
2054
2380
  throw safePathError2(error, path);
2055
2381
  } finally {
@@ -2062,16 +2388,16 @@ async function safePathExists(root, path) {
2062
2388
  try {
2063
2389
  parent = await openAnchoredParent(root, path, false);
2064
2390
  } catch (error) {
2065
- if (hasFsCode3(error, "ENOENT"))
2391
+ if (hasFsCode4(error, "ENOENT"))
2066
2392
  return false;
2067
2393
  throw safePathError2(error, path);
2068
2394
  }
2069
2395
  try {
2070
- const fd = openFileAt(parent, constants3.O_RDONLY | constants3.O_NOFOLLOW);
2071
- closeSync4(fd);
2396
+ const fd = openFileAt(parent, constants4.O_RDONLY | constants4.O_NOFOLLOW);
2397
+ closeSync5(fd);
2072
2398
  return true;
2073
2399
  } catch (error) {
2074
- if (hasFsCode3(error, "ENOENT"))
2400
+ if (hasFsCode4(error, "ENOENT"))
2075
2401
  return false;
2076
2402
  throw safePathError2(error, path);
2077
2403
  } finally {
@@ -2083,14 +2409,14 @@ async function readSafeOptional(root, path) {
2083
2409
  try {
2084
2410
  parent = await openAnchoredParent(root, path, false);
2085
2411
  } catch (error) {
2086
- if (hasFsCode3(error, "ENOENT"))
2412
+ if (hasFsCode4(error, "ENOENT"))
2087
2413
  return;
2088
2414
  throw safePathError2(error, path);
2089
2415
  }
2090
2416
  try {
2091
2417
  return readFileAt(parent);
2092
2418
  } catch (error) {
2093
- if (hasFsCode3(error, "ENOENT"))
2419
+ if (hasFsCode4(error, "ENOENT"))
2094
2420
  return;
2095
2421
  throw safePathError2(error, path);
2096
2422
  } finally {
@@ -2102,14 +2428,14 @@ async function safeFileMode(root, path) {
2102
2428
  try {
2103
2429
  parent = await openAnchoredParent(root, path, false);
2104
2430
  } catch (error) {
2105
- if (hasFsCode3(error, "ENOENT"))
2431
+ if (hasFsCode4(error, "ENOENT"))
2106
2432
  return;
2107
2433
  throw safePathError2(error, path);
2108
2434
  }
2109
2435
  try {
2110
2436
  return fileModeAt(parent);
2111
2437
  } catch (error) {
2112
- if (hasFsCode3(error, "ENOENT"))
2438
+ if (hasFsCode4(error, "ENOENT"))
2113
2439
  return;
2114
2440
  throw safePathError2(error, path);
2115
2441
  } finally {
@@ -2146,7 +2472,7 @@ async function validateBackupDirectory(root, updateId, backupDirectory) {
2146
2472
  return relativePath;
2147
2473
  }
2148
2474
  async function removeEmptyDeletedFileParents(deletedFile, projectRoot) {
2149
- let directory = dirname2(deletedFile);
2475
+ let directory = dirname3(deletedFile);
2150
2476
  while (directory !== ".") {
2151
2477
  try {
2152
2478
  await removeEmptyDirectorySafe(projectRoot, directory);
@@ -2155,7 +2481,7 @@ async function removeEmptyDeletedFileParents(deletedFile, projectRoot) {
2155
2481
  return;
2156
2482
  throw error;
2157
2483
  }
2158
- directory = dirname2(directory);
2484
+ directory = dirname3(directory);
2159
2485
  }
2160
2486
  }
2161
2487
  async function removeEmptyDirectorySafe(root, path) {
@@ -2163,24 +2489,24 @@ async function removeEmptyDirectorySafe(root, path) {
2163
2489
  try {
2164
2490
  parent = await openAnchoredParent(root, path, false);
2165
2491
  } catch (error) {
2166
- if (hasFsCode3(error, "ENOENT"))
2492
+ if (hasFsCode4(error, "ENOENT"))
2167
2493
  return;
2168
2494
  throw safePathError2(error, path);
2169
2495
  }
2170
2496
  try {
2171
2497
  unlinkAt(parent, true);
2172
2498
  } catch (error) {
2173
- if (!hasFsCode3(error, "ENOENT"))
2499
+ if (!hasFsCode4(error, "ENOENT"))
2174
2500
  throw safePathError2(error, path);
2175
2501
  } finally {
2176
2502
  await parent.close();
2177
2503
  }
2178
2504
  }
2179
- function hasFsCode3(error, code) {
2505
+ function hasFsCode4(error, code) {
2180
2506
  return error instanceof Error && "code" in error && error.code === code;
2181
2507
  }
2182
2508
  function safePathError2(error, path) {
2183
- if (hasFsCode3(error, "ELOOP") || hasFsCode3(error, "ENOTDIR")) {
2509
+ if (hasFsCode4(error, "ELOOP") || hasFsCode4(error, "ENOTDIR")) {
2184
2510
  return new Error(`\u4E8B\u52A1\u8DEF\u5F84\u5305\u542B\u7B26\u53F7\u94FE\u63A5\u6216\u975E\u76EE\u5F55\u7EC4\u4EF6\uFF1A${path}`, {
2185
2511
  cause: error
2186
2512
  });
@@ -2196,7 +2522,7 @@ function isDirectoryNotRemovable(error) {
2196
2522
 
2197
2523
  // src/workspace-membership.ts
2198
2524
  import { readdir as readdir2 } from "fs/promises";
2199
- import { join as join3 } from "path";
2525
+ import { join as join4 } from "path";
2200
2526
  function deriveFinalWorkspaceMembership(current, target, files) {
2201
2527
  const membersByBase = new Map;
2202
2528
  for (const expectation of [...current, ...target]) {
@@ -2228,7 +2554,7 @@ function deriveFinalWorkspaceMembership(current, target, files) {
2228
2554
  async function snapshotWorkspaceBase(root, base) {
2229
2555
  assertSafeWorkspaceBase(base);
2230
2556
  await inspectSafePath(root, base);
2231
- const entries = await readdir2(join3(root, base), {
2557
+ const entries = await readdir2(join4(root, base), {
2232
2558
  withFileTypes: true
2233
2559
  }).catch((error) => {
2234
2560
  if (isMissing2(error))
@@ -2270,8 +2596,8 @@ function isDirectWorkspaceManifest(base, path) {
2270
2596
  const prefix = `${base}/`;
2271
2597
  if (!path.startsWith(prefix))
2272
2598
  return false;
2273
- const relative3 = path.slice(prefix.length);
2274
- const segments = relative3.split("/");
2599
+ const relative4 = path.slice(prefix.length);
2600
+ const segments = relative4.split("/");
2275
2601
  return segments.length === 2 && segments[0]?.length > 0 && segments[1] === "package.json";
2276
2602
  }
2277
2603
  function isMissing2(error) {
@@ -2478,7 +2804,7 @@ var supplierWorkspaceCopies = [
2478
2804
  var supplierWorkspacePaths = ["packages/license-sdk"];
2479
2805
  async function prepareCustomerDockerfiles(root) {
2480
2806
  await Promise.all(["apps/server/Dockerfile", webDockerfilePath].map(async (path) => {
2481
- const absolutePath = join4(root, path);
2807
+ const absolutePath = join5(root, path);
2482
2808
  const source = await readFile3(absolutePath, "utf8");
2483
2809
  await writeFile2(absolutePath, rewriteCustomerDockerfile(source));
2484
2810
  }));
@@ -2487,7 +2813,7 @@ async function prepareCustomerDockerfiles(root) {
2487
2813
  requireAnchors: true
2488
2814
  });
2489
2815
  if (plan.changed && plan.content !== undefined) {
2490
- await writeFile2(join4(root, target.dockerfilePath), plan.content);
2816
+ await writeFile2(join5(root, target.dockerfilePath), plan.content);
2491
2817
  }
2492
2818
  }
2493
2819
  }
@@ -2502,7 +2828,7 @@ function rewriteCustomerDockerfile(source) {
2502
2828
 
2503
2829
  // src/code-quality.ts
2504
2830
  import { readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
2505
- import { join as join5 } from "path";
2831
+ import { join as join6 } from "path";
2506
2832
  var oxcStarterPolicy = [
2507
2833
  "- \u751F\u6210\u65F6\u9ED8\u8BA4\u9884\u88C5 Oxlint\u3001Oxfmt\u3001lint-staged \u4E0E Husky\u3002",
2508
2834
  "- \u63D0\u4EA4\u524D\u81EA\u52A8\u683C\u5F0F\u5316\u6682\u5B58\u6587\u4EF6\uFF1Blint\u3001typecheck \u548C test \u4FDD\u7559\u4E3A\u663E\u5F0F\u547D\u4EE4\u3002",
@@ -2511,7 +2837,7 @@ var oxcStarterPolicy = [
2511
2837
  `);
2512
2838
  var noCodeQualityPolicy = "- \u672C\u9879\u76EE\u751F\u6210\u65F6\u672A\u5F15\u5165 lint \u6216 format \u5DE5\u5177\uFF1B\u9879\u76EE\u6240\u6709\u8005\u53EF\u6309\u56E2\u961F\u9700\u8981\u81EA\u884C\u9009\u62E9\u3002";
2513
2839
  async function reflectCodeQualityChoice(targetDirectory, includeOxc) {
2514
- const path = join5(targetDirectory, "AGENTS.md");
2840
+ const path = join6(targetDirectory, "AGENTS.md");
2515
2841
  const source = await readFile4(path, "utf8");
2516
2842
  if (includeOxc)
2517
2843
  return;
@@ -2523,18 +2849,18 @@ async function reflectCodeQualityChoice(targetDirectory, includeOxc) {
2523
2849
 
2524
2850
  // src/license-files.ts
2525
2851
  import { mkdir, readFile as readFile5, rm as rm2, writeFile as writeFile4 } from "fs/promises";
2526
- import { dirname as dirname3, join as join6, resolve as resolve4 } from "path";
2852
+ import { dirname as dirname4, join as join7, resolve as resolve4 } from "path";
2527
2853
  import { fileURLToPath } from "url";
2528
- var packageRoot = resolve4(dirname3(fileURLToPath(import.meta.url)), "..");
2854
+ var packageRoot = resolve4(dirname4(fileURLToPath(import.meta.url)), "..");
2529
2855
  var apacheLicensePath = resolve4(packageRoot, "LICENSE");
2530
2856
  var windyLicensePath = ".windy/licenses/WINDY-APACHE-2.0.txt";
2531
2857
  async function applyWindyBaseLicense(targetDirectory) {
2532
- const target = join6(targetDirectory, windyLicensePath);
2533
- await mkdir(dirname3(target), { recursive: true });
2858
+ const target = join7(targetDirectory, windyLicensePath);
2859
+ await mkdir(dirname4(target), { recursive: true });
2534
2860
  await writeFile4(target, await readFile5(apacheLicensePath));
2535
2861
  }
2536
2862
  async function applyProjectLicense(targetDirectory, license, holder, year = new Date().getFullYear()) {
2537
- const target = join6(targetDirectory, "LICENSE");
2863
+ const target = join7(targetDirectory, "LICENSE");
2538
2864
  if (license === "UNLICENSED") {
2539
2865
  await rm2(target, { force: true });
2540
2866
  return;
@@ -2577,7 +2903,7 @@ SOFTWARE.
2577
2903
 
2578
2904
  // src/module-materializer.ts
2579
2905
  import { lstat as lstat3, readFile as readFile6, readdir as readdir3, rm as rm3, writeFile as writeFile5 } from "fs/promises";
2580
- import { basename as basename3, extname, join as join7, relative as relative3, sep as sep3 } from "path";
2906
+ import { basename as basename4, extname, join as join8, relative as relative4, sep as sep3 } from "path";
2581
2907
  var textExtensions = new Set([
2582
2908
  ".css",
2583
2909
  ".html",
@@ -2613,7 +2939,7 @@ async function materializeSelectedModules(targetDirectory, selectedNames) {
2613
2939
  ...manifest.documentation,
2614
2940
  ...manifest.schemaFiles
2615
2941
  ]));
2616
- await Promise.all([...new Set(removedRoots)].map((path) => rm3(join7(targetDirectory, path), { recursive: true, force: true })));
2942
+ await Promise.all([...new Set(removedRoots)].map((path) => rm3(join8(targetDirectory, path), { recursive: true, force: true })));
2617
2943
  await pruneWorkspaceReferences(targetDirectory, removedPackageNames, removedRoots);
2618
2944
  }
2619
2945
  function collapseRemovalRoots(paths) {
@@ -2628,7 +2954,7 @@ function collapseRemovalRoots(paths) {
2628
2954
  }
2629
2955
  async function stripModuleBlocks(root, selected) {
2630
2956
  for (const path of await collectFiles2(root)) {
2631
- if (basename3(path) !== "Dockerfile" && !textExtensions.has(extname(path))) {
2957
+ if (basename4(path) !== "Dockerfile" && !textExtensions.has(extname(path))) {
2632
2958
  continue;
2633
2959
  }
2634
2960
  const source = await readFile6(path, "utf8");
@@ -2668,7 +2994,7 @@ async function readRemovedPackageNames(root, roots) {
2668
2994
  const names = new Set;
2669
2995
  for (const packageRoot2 of roots) {
2670
2996
  try {
2671
- const value = JSON.parse(await readFile6(join7(root, packageRoot2, "package.json"), "utf8"));
2997
+ const value = JSON.parse(await readFile6(join8(root, packageRoot2, "package.json"), "utf8"));
2672
2998
  if (value.name)
2673
2999
  names.add(value.name);
2674
3000
  } catch (error) {
@@ -2680,7 +3006,7 @@ async function readRemovedPackageNames(root, roots) {
2680
3006
  }
2681
3007
  async function pruneWorkspaceReferences(root, removedPackages, removedRoots) {
2682
3008
  for (const path of await collectFiles2(root)) {
2683
- if (basename3(path) === "package.json") {
3009
+ if (basename4(path) === "package.json") {
2684
3010
  const value = JSON.parse(await readFile6(path, "utf8"));
2685
3011
  let changed = false;
2686
3012
  for (const section of ["dependencies", "devDependencies"]) {
@@ -2697,7 +3023,7 @@ async function pruneWorkspaceReferences(root, removedPackages, removedRoots) {
2697
3023
  `);
2698
3024
  continue;
2699
3025
  }
2700
- if (basename3(path) !== "Dockerfile")
3026
+ if (basename4(path) !== "Dockerfile")
2701
3027
  continue;
2702
3028
  const source = await readFile6(path, "utf8");
2703
3029
  const output = source.split(`
@@ -2711,7 +3037,7 @@ async function pruneDatabaseArtifacts(root, tableNames, statementTokens) {
2711
3037
  if (!tableNames.length && !statementTokens.length)
2712
3038
  return;
2713
3039
  const tablePatterns = tableNames.map((name) => new RegExp(`(?:"${escapeRegExp(name)}"|\\b${escapeRegExp(name)}\\b)`));
2714
- const drizzleRoot = join7(root, "packages/database/drizzle");
3040
+ const drizzleRoot = join8(root, "packages/database/drizzle");
2715
3041
  try {
2716
3042
  for (const path of await collectFiles2(drizzleRoot)) {
2717
3043
  if (path.endsWith(".sql")) {
@@ -2754,7 +3080,7 @@ async function collectFiles2(root) {
2754
3080
  for (const name of (await readdir3(directory)).sort()) {
2755
3081
  if ([".git", "node_modules", "dist"].includes(name))
2756
3082
  continue;
2757
- const path = join7(directory, name);
3083
+ const path = join8(directory, name);
2758
3084
  const metadata = await lstat3(path);
2759
3085
  if (metadata.isSymbolicLink())
2760
3086
  continue;
@@ -2766,7 +3092,7 @@ async function collectFiles2(root) {
2766
3092
  }
2767
3093
  }
2768
3094
  function relativePath(root, path) {
2769
- return relative3(root, path).split(sep3).join("/");
3095
+ return relative4(root, path).split(sep3).join("/");
2770
3096
  }
2771
3097
  function escapeRegExp(value) {
2772
3098
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -3280,7 +3606,7 @@ License \u7B7E\u53D1\u4E2D\u5FC3\u3001\u72EC\u7ACB\u7B7E\u540D\u670D\u52A1\u3001
3280
3606
  - \u90E8\u7F72\u671F\u6A21\u5757\u7BA1\u7406\uFF1A[\u6A21\u5757\u751F\u547D\u5468\u671F](./development/module-lifecycle.md)\u3002
3281
3607
  - \u4E1A\u52A1\u6A21\u5757\u5F00\u53D1\uFF1A[windy-business-module Skill](../.agents/skills/windy-business-module/SKILL.md)\u3002
3282
3608
  ${includeStorage ? "- \u5927\u62A5\u544A\u5BFC\u5165\uFF1A[\u53D7\u6CBB\u7406\u7684\u5927\u62A5\u544A\u6682\u5B58](./architecture/report-staging.md)\u3002" : ""}
3283
- ${includeOfflineLicense ? "- License \u6D88\u8D39\u7AEF\uFF1A[\u79BB\u7EBF\u6FC0\u6D3B\u4E0E\u5B89\u88C5\u534F\u8BAE](./license/license-offline-activation-code.md)\uFF1B\u8FD0\u884C\u65F6\u80FD\u529B\u7531 npm \u4F9D\u8D56 `@southwind-ai/license` \u63D0\u4F9B\u3002" : ""}
3609
+ ${includeOfflineLicense ? "- License \u6D88\u8D39\u7AEF\uFF1A[\u79BB\u7EBF\u6FC0\u6D3B\u4E0E\u5B89\u88C5\u534F\u8BAE](./license/license-offline-activation-code.md)\u4E0E[\u624B\u673A\u626B\u7801\u914D\u5BF9\u6FC0\u6D3B](./license/license-pairing-activation.md)\uFF1B\u8FD0\u884C\u65F6\u80FD\u529B\u7531 npm \u4F9D\u8D56 `@southwind-ai/license` \u63D0\u4F9B\u3002" : ""}
3284
3610
  - \u8FD0\u7EF4\uFF1A[\u53EF\u89C2\u6D4B\u6027](./operations/observability.md)${includeOperations ? " \u4E0E [\u8FD0\u7EF4\u603B\u89C8](./platform/operations-overview.md)" : ""}\u3002
3285
3611
  - \u4EA4\u4ED8\uFF1A[\u6309 registry digest \u4E0E OCI blob \u5DEE\u91CF\u53D1\u5E03](./operations/incremental-delivery.md)\u3002
3286
3612
  ${includeAgent ? "- Agent\u3001\u591A\u6A21\u6001 Runtime \u4E0E MCP\uFF1A[Agent Runtime \u63A5\u5165](./platform/agent-runtime.md)\u3001[Document AI Runtime](./platform/document-ai-runtime.md)\u3001[Speech AI Runtime](./platform/speech-ai-runtime.md)\u3001[\u53D7\u63A7\u5DE5\u5177](./platform/agent-tools.md)\u4E0E[MCP \u4E1A\u52A1\u80FD\u529B](./architecture/mcp-business-capabilities.md)\u3002" : ""}
@@ -3338,6 +3664,10 @@ Drizzle migration\uFF0C\u518D\u542F\u52A8 Server \u4E0E Web\uFF1B\u4E0D\u8981\u8
3338
3664
  BuildKit \u4E2D\u7684 Bun \u5305\u4E0B\u8F7D\u7F13\u5B58\uFF0C\u53EA\u4E0B\u8F7D\u65B0\u589E\u6216\u53D1\u751F\u53D8\u5316\u7684\u4F9D\u8D56\uFF1B\u51B7\u5B89\u88C5\u6BCF 15 \u79D2\u8F93\u51FA\u4E00\u6B21
3339
3665
  \u4E0D\u542B registry \u5730\u5740\u6216\u51ED\u636E\u7684\u8FDB\u5EA6\u5FC3\u8DF3\u3002
3340
3666
 
3667
+ Windows 10/11 \u53EF\u5728\u539F\u751F PowerShell \u4E2D\u914D\u5408 Docker Desktop \u76F4\u63A5\u8FD0\u884C \`bun run dev\` \u4E0E
3668
+ \`bun run dev:build\`\uFF0C\u4E0D\u9700\u8981 WSL\u3002Windows \u662F\u672C\u5730\u5F00\u53D1\u5BBF\u4E3B\uFF1B\u751F\u4EA7\u4EA4\u4ED8\u4ECD\u4F7F\u7528 Linux
3669
+ amd64 \u5BB9\u5668\u3002
3670
+
3341
3671
  | \u670D\u52A1 | \u5730\u5740 |
3342
3672
  | ---- | ---- |
3343
3673
  | Web | http://localhost:18746 |
@@ -3698,9 +4028,11 @@ var templateDocumentationFiles = [
3698
4028
  "docs/development/module-lifecycle.md",
3699
4029
  "docs/development/ui-component-gallery.md",
3700
4030
  "docs/license/license-offline-activation-code.md",
4031
+ "docs/license/license-pairing-activation.md",
3701
4032
  "docs/operations/observability.md",
3702
4033
  "docs/operations/incremental-delivery.md",
3703
4034
  "docs/platform/agent-run-attestation.md",
4035
+ "docs/platform/agent-supervisor-output-contract.md",
3704
4036
  "docs/platform/agent-tools.md",
3705
4037
  "docs/platform/agent-runtime.md",
3706
4038
  "docs/platform/agent-runtime-observability.md",
@@ -3762,11 +4094,11 @@ function isExcludedTemplateName(name) {
3762
4094
  // src/provenance.ts
3763
4095
  import { createHash as createHash2 } from "crypto";
3764
4096
  import { mkdir as mkdir2, readFile as readFile7, writeFile as writeFile6 } from "fs/promises";
3765
- import { join as join8 } from "path";
4097
+ import { join as join9 } from "path";
3766
4098
  var templateMetadataFile = ".windy-template.json";
3767
4099
  var generationMetadataFile = ".windy/generation.json";
3768
4100
  async function readTemplateMetadata(sourceRoot) {
3769
- const path = join8(sourceRoot, templateMetadataFile);
4101
+ const path = join9(sourceRoot, templateMetadataFile);
3770
4102
  const parsed = JSON.parse(await readFile7(path, "utf8"));
3771
4103
  if (!isTemplateMetadata(parsed)) {
3772
4104
  throw new Error("create-windy \u6A21\u677F\u6765\u6E90\u5143\u6570\u636E\u65E0\u6548");
@@ -3777,7 +4109,7 @@ async function readGenerationProvenance(targetDirectory) {
3777
4109
  return (await readGenerationProvenanceSnapshot(targetDirectory)).provenance;
3778
4110
  }
3779
4111
  async function readGenerationProvenanceSnapshot(targetDirectory) {
3780
- const path = join8(targetDirectory, generationMetadataFile);
4112
+ const path = join9(targetDirectory, generationMetadataFile);
3781
4113
  const content = await readFile7(path);
3782
4114
  return {
3783
4115
  content,
@@ -3818,8 +4150,8 @@ async function writeGenerationProvenance(targetDirectory, metadata, profile, sel
3818
4150
  includeOxc
3819
4151
  }
3820
4152
  };
3821
- const path = join8(targetDirectory, generationMetadataFile);
3822
- await mkdir2(join8(path, ".."), { recursive: true });
4153
+ const path = join9(targetDirectory, generationMetadataFile);
4154
+ await mkdir2(join9(path, ".."), { recursive: true });
3823
4155
  await writeFile6(path, `${JSON.stringify(provenance, null, 2)}
3824
4156
  `);
3825
4157
  }
@@ -3846,7 +4178,7 @@ function isModuleVersion(value) {
3846
4178
 
3847
4179
  // src/registry-dependencies.ts
3848
4180
  import { lstat as lstat4, readFile as readFile8, readdir as readdir4, writeFile as writeFile7 } from "fs/promises";
3849
- import { basename as basename4, extname as extname2, join as join9 } from "path";
4181
+ import { basename as basename5, extname as extname2, join as join10 } from "path";
3850
4182
  var dependencySections = [
3851
4183
  "dependencies",
3852
4184
  "devDependencies",
@@ -3870,7 +4202,7 @@ async function materializeRegistryDependencies(root, dependencies) {
3870
4202
  for (const path of await collectFiles3(root)) {
3871
4203
  if (!replaceableExtensions.has(extname2(path)))
3872
4204
  continue;
3873
- if (basename4(path) === "package.json") {
4205
+ if (basename5(path) === "package.json") {
3874
4206
  await rewritePackageJson(path, dependencies);
3875
4207
  continue;
3876
4208
  }
@@ -3907,7 +4239,7 @@ async function collectFiles3(root) {
3907
4239
  for (const name of (await readdir4(directory)).sort()) {
3908
4240
  if ([".git", "node_modules", "dist"].includes(name))
3909
4241
  continue;
3910
- const path = join9(directory, name);
4242
+ const path = join10(directory, name);
3911
4243
  const metadata = await lstat4(path);
3912
4244
  if (metadata.isSymbolicLink())
3913
4245
  continue;
@@ -3922,10 +4254,10 @@ async function collectFiles3(root) {
3922
4254
  // src/project-module-registry.ts
3923
4255
  import { createHash as createHash3 } from "crypto";
3924
4256
  import { readFile as readFile9, writeFile as writeFile8 } from "fs/promises";
3925
- import { join as join10 } from "path";
4257
+ import { join as join11 } from "path";
3926
4258
  var projectModuleRegistryPath = "windy.modules.json";
3927
4259
  async function readProjectModuleRegistrySnapshot(projectDirectory, installedNames) {
3928
- const path = join10(projectDirectory, projectModuleRegistryPath);
4260
+ const path = join11(projectDirectory, projectModuleRegistryPath);
3929
4261
  let content;
3930
4262
  try {
3931
4263
  content = await readFile9(path);
@@ -3978,7 +4310,7 @@ async function writeInitialProjectModuleRegistry(targetDirectory, selectedNames)
3978
4310
  config: {}
3979
4311
  })));
3980
4312
  const registry = { schemaVersion: 1, modules };
3981
- await writeFile8(join10(targetDirectory, projectModuleRegistryPath), `${JSON.stringify(registry, null, 2)}
4313
+ await writeFile8(join11(targetDirectory, projectModuleRegistryPath), `${JSON.stringify(registry, null, 2)}
3982
4314
  `);
3983
4315
  }
3984
4316
  function assertRegistryMatchesInstalled(registry, installedNames) {
@@ -4034,29 +4366,29 @@ async function generateProject(input) {
4034
4366
  const selectedModules = input.selectedModules ?? templateMetadata.modules.filter(({ name }) => requestedIncludeExample || name !== "work-order").map(({ name }) => name);
4035
4367
  const includeExample = selectedModules.includes("work-order");
4036
4368
  for (const relativePath2 of generationTemplatePaths(true, includeOxc)) {
4037
- await copyTree(await resolveTemplateSource(input.sourceRoot, relativePath2), join11(input.targetDirectory, relativePath2));
4369
+ await copyTree(await resolveTemplateSource(input.sourceRoot, relativePath2), join12(input.targetDirectory, relativePath2));
4038
4370
  }
4039
4371
  await materializeSelectedModules(input.targetDirectory, selectedModules);
4040
4372
  await materializeRegistryDependencies(input.targetDirectory, selectedModuleManifests(selectedModules).flatMap(({ registryDependencies }) => registryDependencies));
4041
- const packagePath = join11(input.targetDirectory, "package.json");
4373
+ const packagePath = join12(input.targetDirectory, "package.json");
4042
4374
  const packageJson = JSON.parse(await readFile10(packagePath, "utf8"));
4043
4375
  await writeFile9(packagePath, `${JSON.stringify(createStarterPackage(packageJson, input.projectName, includeOxc, projectLicense, selectedModules, templateMetadata.generatorVersion), null, 2)}
4044
4376
  `);
4045
- await writeFile9(join11(input.targetDirectory, "docker-compose.yml"), starterComposeFor(selectedModules.includes("system.agent"), selectedModules.includes("system.search"), selectedModules.includes("system.storage")));
4046
- await writeFile9(join11(input.targetDirectory, ".env.example"), environmentExample(includeExample, selectedModules.includes("system.agent"), selectedModules.includes("system.search"), selectedModules.includes("system.storage")));
4047
- await writeFile9(join11(input.targetDirectory, "README.md"), starterReadme(input.projectName, includeExample, includeOxc, projectLicense, selectedModules));
4048
- await writeFile9(join11(input.targetDirectory, "docs/README.md"), starterDocsReadme(selectedModules.includes("system.license"), selectedModules.includes("system.agent"), selectedModules.includes("system.operations"), selectedModules.includes("system.storage")));
4377
+ await writeFile9(join12(input.targetDirectory, "docker-compose.yml"), starterComposeFor(selectedModules.includes("system.agent"), selectedModules.includes("system.search"), selectedModules.includes("system.storage")));
4378
+ await writeFile9(join12(input.targetDirectory, ".env.example"), environmentExample(includeExample, selectedModules.includes("system.agent"), selectedModules.includes("system.search"), selectedModules.includes("system.storage")));
4379
+ await writeFile9(join12(input.targetDirectory, "README.md"), starterReadme(input.projectName, includeExample, includeOxc, projectLicense, selectedModules));
4380
+ await writeFile9(join12(input.targetDirectory, "docs/README.md"), starterDocsReadme(selectedModules.includes("system.license"), selectedModules.includes("system.agent"), selectedModules.includes("system.operations"), selectedModules.includes("system.storage")));
4049
4381
  await reflectCodeQualityChoice(input.targetDirectory, includeOxc);
4050
4382
  await applyWindyBaseLicense(input.targetDirectory);
4051
4383
  await applyProjectLicense(input.targetDirectory, projectLicense, input.licenseHolder);
4052
4384
  await prepareCustomerDockerfiles(input.targetDirectory);
4053
4385
  await writeGenerationProvenance(input.targetDirectory, templateMetadata, input.profile ?? starterProfile.key, selectedModules, includeOxc, projectLicense);
4054
4386
  await writeInitialProjectModuleRegistry(input.targetDirectory, selectedModules);
4055
- await rm4(join11(input.targetDirectory, "bun.lock"), { force: true });
4387
+ await rm4(join12(input.targetDirectory, "bun.lock"), { force: true });
4056
4388
  await writeManagedFilesManifest(input.targetDirectory, templateMetadata.generatorVersion);
4057
4389
  }
4058
4390
  async function resolveTemplateSource(sourceRoot, relativePath2) {
4059
- const source = join11(sourceRoot, relativePath2);
4391
+ const source = join12(sourceRoot, relativePath2);
4060
4392
  try {
4061
4393
  await lstat5(source);
4062
4394
  return source;
@@ -4067,12 +4399,12 @@ async function resolveTemplateSource(sourceRoot, relativePath2) {
4067
4399
  const alias = npmTemplateAliases[relativePath2];
4068
4400
  if (!alias)
4069
4401
  return source;
4070
- return join11(sourceRoot, alias);
4402
+ return join12(sourceRoot, alias);
4071
4403
  }
4072
4404
  async function assertGeneratedProjectIsClean(targetDirectory) {
4073
4405
  const violations = [];
4074
4406
  await walk(targetDirectory, async (path) => {
4075
- const name = basename5(path);
4407
+ const name = basename6(path);
4076
4408
  const extension = extname3(name).toLowerCase();
4077
4409
  if (isExcludedTemplateName(name) || excludedRuntimeFiles.has(name) || [".key", ".pem", ".p12", ".pfx"].includes(extension)) {
4078
4410
  violations.push(path.slice(targetDirectory.length + 1));
@@ -4103,17 +4435,17 @@ async function assertTargetAvailable(targetDirectory) {
4103
4435
  }
4104
4436
  async function copyTree(source, target) {
4105
4437
  const metadata = await lstat5(source);
4106
- const name = basename5(source);
4438
+ const name = basename6(source);
4107
4439
  if (shouldExclude(name) || metadata.isSymbolicLink())
4108
4440
  return;
4109
4441
  if (metadata.isDirectory()) {
4110
4442
  await mkdir3(target, { recursive: true });
4111
4443
  for (const child of await readdir5(source)) {
4112
- await copyTree(join11(source, child), join11(target, child));
4444
+ await copyTree(join12(source, child), join12(target, child));
4113
4445
  }
4114
4446
  return;
4115
4447
  }
4116
- await mkdir3(join11(target, ".."), { recursive: true });
4448
+ await mkdir3(join12(target, ".."), { recursive: true });
4117
4449
  await copyFile(source, target);
4118
4450
  }
4119
4451
  function shouldExclude(name) {
@@ -4121,7 +4453,7 @@ function shouldExclude(name) {
4121
4453
  }
4122
4454
  async function walk(directory, visit) {
4123
4455
  for (const name of await readdir5(directory)) {
4124
- const path = join11(directory, name);
4456
+ const path = join12(directory, name);
4125
4457
  await visit(path);
4126
4458
  if ((await lstat5(path)).isDirectory())
4127
4459
  await walk(path, visit);
@@ -4133,10 +4465,10 @@ function isMissing5(error) {
4133
4465
 
4134
4466
  // src/template-root.ts
4135
4467
  import { access } from "fs/promises";
4136
- import { dirname as dirname4, resolve as resolve5 } from "path";
4468
+ import { dirname as dirname5, resolve as resolve5 } from "path";
4137
4469
  import { fileURLToPath as fileURLToPath2 } from "url";
4138
4470
  async function resolveTemplateRoot() {
4139
- const currentDirectory = dirname4(fileURLToPath2(import.meta.url));
4471
+ const currentDirectory = dirname5(fileURLToPath2(import.meta.url));
4140
4472
  const templateRoot = resolve5(currentDirectory, "../template");
4141
4473
  try {
4142
4474
  await access(resolve5(templateRoot, "package.json"));
@@ -5978,7 +6310,7 @@ import { resolve as resolve8 } from "path";
5978
6310
 
5979
6311
  // src/update/doctor.ts
5980
6312
  import { readFile as readFile11 } from "fs/promises";
5981
- import { join as join15 } from "path";
6313
+ import { join as join16 } from "path";
5982
6314
 
5983
6315
  // src/update/process.ts
5984
6316
  import { spawn as spawn2 } from "child_process";
@@ -6031,10 +6363,10 @@ function withoutParentGitRepository(source) {
6031
6363
  }
6032
6364
 
6033
6365
  // src/update/transaction-cas.ts
6034
- import { basename as basename6, dirname as dirname5 } from "path";
6366
+ import { basename as basename8, dirname as dirname7 } from "path";
6035
6367
 
6036
6368
  // src/update/transaction-native-cas.ts
6037
- import { ptr as ptr2, read as read3, dlopen as dlopen3, FFIType as FFIType3 } from "bun:ffi";
6369
+ import { ptr as ptr3, read as read3, dlopen as dlopen4, FFIType as FFIType4 } from "bun:ffi";
6038
6370
 
6039
6371
  // src/update/transaction-native-cas-config.ts
6040
6372
  function nativeRenameConfiguration(platform) {
@@ -6059,19 +6391,19 @@ function nativeRenameConfiguration(platform) {
6059
6391
 
6060
6392
  // src/update/transaction-native-cas.ts
6061
6393
  var renameSignature = {
6062
- args: [FFIType3.i32, FFIType3.ptr, FFIType3.i32, FFIType3.ptr, FFIType3.i32],
6063
- returns: FFIType3.i32
6394
+ args: [FFIType4.i32, FFIType4.ptr, FFIType4.i32, FFIType4.ptr, FFIType4.i32],
6395
+ returns: FFIType4.i32
6064
6396
  };
6065
6397
  var linuxSymbols = {
6066
6398
  renameat2: renameSignature,
6067
- __errno_location: { args: [], returns: FFIType3.ptr }
6399
+ __errno_location: { args: [], returns: FFIType4.ptr }
6068
6400
  };
6069
6401
  var darwinSymbols = {
6070
6402
  renameatx_np: renameSignature,
6071
- __error: { args: [], returns: FFIType3.ptr }
6403
+ __error: { args: [], returns: FFIType4.ptr }
6072
6404
  };
6073
- var getLinuxLibc = createLazyLibcLoader((candidate) => dlopen3(candidate, linuxSymbols), "\u5F53\u524D\u5E73\u53F0\u65E0\u6CD5\u52A0\u8F7D renameat2\uFF0C\u4E8B\u52A1 CAS \u5B89\u5168\u5173\u95ED");
6074
- var getDarwinLibc = createLazyLibcLoader((candidate) => dlopen3(candidate, darwinSymbols), "\u5F53\u524D\u5E73\u53F0\u65E0\u6CD5\u52A0\u8F7D renameatx_np\uFF0C\u4E8B\u52A1 CAS \u5B89\u5168\u5173\u95ED");
6405
+ var getLinuxLibc = createLazyLibcLoader((candidate) => dlopen4(candidate, linuxSymbols), "\u5F53\u524D\u5E73\u53F0\u65E0\u6CD5\u52A0\u8F7D renameat2\uFF0C\u4E8B\u52A1 CAS \u5B89\u5168\u5173\u95ED");
6406
+ var getDarwinLibc = createLazyLibcLoader((candidate) => dlopen4(candidate, darwinSymbols), "\u5F53\u524D\u5E73\u53F0\u65E0\u6CD5\u52A0\u8F7D renameatx_np\uFF0C\u4E8B\u52A1 CAS \u5B89\u5168\u5173\u95ED");
6075
6407
  function exchangeAt(parent, left, right, rollback = false) {
6076
6408
  atomicRename(parent, left, right, "exchange");
6077
6409
  syncMutatedDirectory(rollback ? "rename-exchange-back" : "rename-exchange", parent.fd);
@@ -6081,10 +6413,18 @@ function moveNoReplaceAt(parent, source, target) {
6081
6413
  syncMutatedDirectory("rename-noreplace", parent.fd);
6082
6414
  }
6083
6415
  function atomicRename(parent, source, target, operation) {
6416
+ if (process.platform === "win32") {
6417
+ if (operation === "exchange") {
6418
+ windowsExchangeAt(parent, source, target);
6419
+ } else {
6420
+ windowsMoveNoReplaceAt(parent, source, target);
6421
+ }
6422
+ return;
6423
+ }
6084
6424
  const configuration = nativeRenameConfiguration(process.platform);
6085
6425
  if (process.platform === "linux") {
6086
6426
  const libc = getLinuxLibc();
6087
- const result = libc.symbols.renameat2(parent.fd, ptr2(cString2(source)), parent.fd, ptr2(cString2(target)), operation === "exchange" ? configuration.exchangeFlag : configuration.noReplaceFlag);
6427
+ const result = libc.symbols.renameat2(parent.fd, ptr3(cString2(source)), parent.fd, ptr3(cString2(target)), operation === "exchange" ? configuration.exchangeFlag : configuration.noReplaceFlag);
6088
6428
  if (result < 0) {
6089
6429
  throw linuxError(`renameat2 ${source} -> ${target}`);
6090
6430
  }
@@ -6092,7 +6432,7 @@ function atomicRename(parent, source, target, operation) {
6092
6432
  }
6093
6433
  if (process.platform === "darwin") {
6094
6434
  const libc = getDarwinLibc();
6095
- const result = libc.symbols.renameatx_np(parent.fd, ptr2(cString2(source)), parent.fd, ptr2(cString2(target)), operation === "exchange" ? configuration.exchangeFlag : configuration.noReplaceFlag);
6435
+ const result = libc.symbols.renameatx_np(parent.fd, ptr3(cString2(source)), parent.fd, ptr3(cString2(target)), operation === "exchange" ? configuration.exchangeFlag : configuration.noReplaceFlag);
6096
6436
  if (result < 0) {
6097
6437
  throw darwinError(`renameatx_np ${source} -> ${target}`);
6098
6438
  }
@@ -6125,18 +6465,18 @@ function cString2(value) {
6125
6465
  }
6126
6466
 
6127
6467
  // src/update/transaction-cas-proof.ts
6128
- import { closeSync as closeSync5, constants as constants4, fstatSync as fstatSync3, readSync } from "fs";
6468
+ import { closeSync as closeSync6, constants as constants5, fstatSync as fstatSync4, readSync } from "fs";
6129
6469
  function openFileProof(parent) {
6130
- const fd = openFileAt(parent, constants4.O_RDONLY | constants4.O_NOFOLLOW);
6470
+ const fd = openFileAt(parent, constants5.O_RDONLY | constants5.O_NOFOLLOW);
6131
6471
  try {
6132
6472
  const identity = identityOf(fd);
6133
6473
  return {
6134
6474
  fd,
6135
6475
  ...identity,
6136
- close: () => closeSync5(fd)
6476
+ close: () => closeSync6(fd)
6137
6477
  };
6138
6478
  } catch (error) {
6139
- closeSync5(fd);
6479
+ closeSync6(fd);
6140
6480
  throw error;
6141
6481
  }
6142
6482
  }
@@ -6154,7 +6494,7 @@ function assertProofPayload(proof, content, mode) {
6154
6494
  function pathMatchesProof(parent, proof) {
6155
6495
  let fd;
6156
6496
  try {
6157
- fd = openFileAt(parent, constants4.O_RDONLY | constants4.O_NOFOLLOW);
6497
+ fd = openFileAt(parent, constants5.O_RDONLY | constants5.O_NOFOLLOW);
6158
6498
  } catch {
6159
6499
  return false;
6160
6500
  }
@@ -6162,7 +6502,7 @@ function pathMatchesProof(parent, proof) {
6162
6502
  const identity = identityOf(fd);
6163
6503
  return identity.device === proof.device && identity.inode === proof.inode;
6164
6504
  } finally {
6165
- closeSync5(fd);
6505
+ closeSync6(fd);
6166
6506
  }
6167
6507
  }
6168
6508
  function pathMatchesExpectedProof(parent, proof, expected, expectedMode) {
@@ -6183,7 +6523,7 @@ function modeOfProof(proof) {
6183
6523
  return inspectProof(proof).mode;
6184
6524
  }
6185
6525
  function inspectProof(proof) {
6186
- const stat2 = fstatSync3(proof.fd, { bigint: true });
6526
+ const stat2 = fstatSync4(proof.fd, { bigint: true });
6187
6527
  if (!stat2.isFile())
6188
6528
  throw new Error("\u4E8B\u52A1\u76EE\u6807\u4E0D\u662F\u666E\u901A\u6587\u4EF6");
6189
6529
  if (stat2.dev !== proof.device || stat2.ino !== proof.inode) {
@@ -6200,7 +6540,7 @@ function inspectProof(proof) {
6200
6540
  throw new Error("\u4E8B\u52A1\u76EE\u6807\u8BFB\u53D6\u63D0\u524D\u7ED3\u675F");
6201
6541
  offset += count;
6202
6542
  }
6203
- const after = fstatSync3(proof.fd, { bigint: true });
6543
+ const after = fstatSync4(proof.fd, { bigint: true });
6204
6544
  if (after.dev !== stat2.dev || after.ino !== stat2.ino || after.size !== stat2.size || after.mtimeNs !== stat2.mtimeNs || after.ctimeNs !== stat2.ctimeNs || after.mode !== stat2.mode) {
6205
6545
  throw new Error("\u4E8B\u52A1\u76EE\u6807\u5728\u8BC1\u660E\u671F\u95F4\u53D1\u751F\u53D8\u5316");
6206
6546
  }
@@ -6210,7 +6550,7 @@ function inspectProof(proof) {
6210
6550
  };
6211
6551
  }
6212
6552
  function identityOf(fd) {
6213
- const stat2 = fstatSync3(fd, { bigint: true });
6553
+ const stat2 = fstatSync4(fd, { bigint: true });
6214
6554
  if (!stat2.isFile())
6215
6555
  throw new Error("\u4E8B\u52A1\u76EE\u6807\u4E0D\u662F\u666E\u901A\u6587\u4EF6");
6216
6556
  return { device: stat2.dev, inode: stat2.ino };
@@ -6331,11 +6671,218 @@ function isBackupEntry(value) {
6331
6671
  return typeof entry.path === "string" && typeof entry.existed === "boolean" && (entry.mode === undefined || Number.isInteger(entry.mode) && entry.mode >= 0 && entry.mode <= 511);
6332
6672
  }
6333
6673
 
6674
+ // src/update/transaction-cas-windows.ts
6675
+ import { basename as basename7, dirname as dirname6 } from "path";
6676
+ import { closeSync as closeSync7, constants as constants6, fstatSync as fstatSync5, readSync as readSync2 } from "fs";
6677
+ async function windowsAnchoredCompareAndReplace(input) {
6678
+ assertSameDirectory(input.path, input.temporaryPath);
6679
+ const parent = await openAnchoredParent(input.root, input.path, true, input.parentMode);
6680
+ const temporaryName = basename7(input.temporaryPath);
6681
+ let ownsTemporary = false;
6682
+ let exchanged = false;
6683
+ let containsUnknownProjectBytes = false;
6684
+ try {
6685
+ const targetSnapshot = input.expected.kind === "hash" ? snapshot(parent) : undefined;
6686
+ const requestedMode = input.mode ?? targetSnapshot?.mode ?? 384;
6687
+ writeExclusiveAt(withLeaf(parent, temporaryName), input.content, requestedMode);
6688
+ ownsTemporary = true;
6689
+ const desiredSnapshot = snapshot(withLeaf(parent, temporaryName));
6690
+ if (!matchesPayload(desiredSnapshot, input.content))
6691
+ throw casError(input.path);
6692
+ await input.hooks?.beforeAtomicRename?.();
6693
+ if (input.expected.kind === "missing") {
6694
+ publishMissing(parent, temporaryName, input, desiredSnapshot);
6695
+ await input.hooks?.afterAtomicRenameBeforeInspect?.();
6696
+ ownsTemporary = pathMatchesPayload(withLeaf(parent, temporaryName), desiredSnapshot, input.content);
6697
+ containsUnknownProjectBytes = !ownsTemporary;
6698
+ if (!ownsTemporary)
6699
+ throw casError(input.path, input.temporaryPath);
6700
+ return;
6701
+ }
6702
+ if (!targetSnapshot || !pathMatches(parent, targetSnapshot) || !matchesExpected(targetSnapshot, input.expected) || !pathMatches(withLeaf(parent, temporaryName), desiredSnapshot) || !matchesPayload(desiredSnapshot, input.content)) {
6703
+ throw casError(input.path);
6704
+ }
6705
+ exchangeAt(parent, temporaryName, parent.leaf);
6706
+ exchanged = true;
6707
+ ownsTemporary = false;
6708
+ containsUnknownProjectBytes = true;
6709
+ await input.hooks?.afterExchangeBeforeProof?.();
6710
+ if (!pathMatches(withLeaf(parent, temporaryName), targetSnapshot) || !matchesExpected(targetSnapshot, input.expected) || !pathMatches(parent, desiredSnapshot) || !matchesPayload(desiredSnapshot, input.content)) {
6711
+ await rollbackExchange(parent, temporaryName, input, targetSnapshot);
6712
+ exchanged = false;
6713
+ ownsTemporary = pathMatchesPayload(withLeaf(parent, temporaryName), desiredSnapshot, input.content);
6714
+ containsUnknownProjectBytes = !ownsTemporary;
6715
+ throw casError(input.path, ownsTemporary ? undefined : input.temporaryPath);
6716
+ }
6717
+ await input.hooks?.afterAtomicRenameBeforeInspect?.();
6718
+ ownsTemporary = pathMatches(withLeaf(parent, temporaryName), targetSnapshot) && matchesExpected(targetSnapshot, input.expected);
6719
+ containsUnknownProjectBytes = !ownsTemporary;
6720
+ if (!ownsTemporary)
6721
+ throw casError(input.path, input.temporaryPath);
6722
+ } catch (error) {
6723
+ if (error instanceof TransactionCasError)
6724
+ throw error;
6725
+ if (exchanged || containsUnknownProjectBytes) {
6726
+ throw casError(input.path, input.temporaryPath, error);
6727
+ }
6728
+ if (hasFsCode5(error, "ENOENT") || hasFsCode5(error, "EEXIST")) {
6729
+ throw casError(input.path);
6730
+ }
6731
+ throw error;
6732
+ } finally {
6733
+ if (ownsTemporary)
6734
+ removeTemporary(parent, temporaryName);
6735
+ await parent.close();
6736
+ }
6737
+ }
6738
+ async function windowsAnchoredCompareAndRemove(input) {
6739
+ assertSameDirectory(input.path, input.quarantinePath);
6740
+ if (input.expected.kind === "missing")
6741
+ return;
6742
+ const parent = await openAnchoredParent(input.root, input.path, false);
6743
+ const quarantineName = basename7(input.quarantinePath);
6744
+ let ownsQuarantine = false;
6745
+ try {
6746
+ const targetSnapshot = snapshot(parent);
6747
+ await input.hooks?.beforeAtomicRename?.();
6748
+ if (!pathMatches(parent, targetSnapshot) || !matchesExpected(targetSnapshot, input.expected)) {
6749
+ throw casError(input.path);
6750
+ }
6751
+ moveNoReplaceAt(parent, parent.leaf, quarantineName);
6752
+ ownsQuarantine = true;
6753
+ if (!pathMatches(withLeaf(parent, quarantineName), targetSnapshot) || !matchesExpected(targetSnapshot, input.expected)) {
6754
+ throw casError(input.path, input.quarantinePath);
6755
+ }
6756
+ await input.hooks?.afterAtomicRenameBeforeInspect?.();
6757
+ if (pathMatches(withLeaf(parent, quarantineName), targetSnapshot) && matchesExpected(targetSnapshot, input.expected)) {
6758
+ removeTemporary(parent, quarantineName);
6759
+ ownsQuarantine = false;
6760
+ return;
6761
+ }
6762
+ throw casError(input.path, input.quarantinePath);
6763
+ } catch (error) {
6764
+ if (error instanceof TransactionCasError)
6765
+ throw error;
6766
+ if (ownsQuarantine)
6767
+ throw casError(input.path, input.quarantinePath, error);
6768
+ if (hasFsCode5(error, "ENOENT") || hasFsCode5(error, "EEXIST")) {
6769
+ throw casError(input.path);
6770
+ }
6771
+ throw error;
6772
+ } finally {
6773
+ await parent.close();
6774
+ }
6775
+ }
6776
+ function publishMissing(parent, temporaryName, input, desiredSnapshot) {
6777
+ if (!pathMatches(withLeaf(parent, temporaryName), desiredSnapshot) || !matchesPayload(desiredSnapshot, input.content)) {
6778
+ throw casError(input.path);
6779
+ }
6780
+ try {
6781
+ linkAt(parent, temporaryName, parent.leaf);
6782
+ } catch (error) {
6783
+ if (hasFsCode5(error, "EEXIST"))
6784
+ throw casError(input.path);
6785
+ throw error;
6786
+ }
6787
+ if (!pathMatches(parent, desiredSnapshot) || !matchesPayload(desiredSnapshot, input.content)) {
6788
+ throw casError(input.path, input.temporaryPath);
6789
+ }
6790
+ }
6791
+ async function rollbackExchange(parent, temporaryName, input, targetSnapshot) {
6792
+ if (!pathMatches(withLeaf(parent, temporaryName), targetSnapshot) || !matchesExpected(targetSnapshot, input.expected)) {
6793
+ throw casError(input.path, input.temporaryPath);
6794
+ }
6795
+ await input.hooks?.beforeExchangeRollback?.();
6796
+ if (!pathMatches(withLeaf(parent, temporaryName), targetSnapshot) || !matchesExpected(targetSnapshot, input.expected)) {
6797
+ throw casError(input.path, input.temporaryPath);
6798
+ }
6799
+ exchangeAt(parent, temporaryName, parent.leaf, true);
6800
+ await input.hooks?.afterExchangeRollbackBeforeCleanup?.();
6801
+ }
6802
+ function snapshot(parent) {
6803
+ const fd = openFileAt(parent, constants6.O_RDONLY);
6804
+ try {
6805
+ const before = fstatSync5(fd, { bigint: true });
6806
+ if (!before.isFile())
6807
+ throw new Error("\u4E8B\u52A1\u76EE\u6807\u4E0D\u662F\u666E\u901A\u6587\u4EF6");
6808
+ if (before.size > BigInt(Number.MAX_SAFE_INTEGER)) {
6809
+ throw new Error("\u4E8B\u52A1\u76EE\u6807\u8FC7\u5927\uFF0C\u65E0\u6CD5\u5B89\u5168\u9A8C\u8BC1");
6810
+ }
6811
+ const content = Buffer.alloc(Number(before.size));
6812
+ let offset = 0;
6813
+ while (offset < content.length) {
6814
+ const count = readSync2(fd, content, offset, content.length - offset, offset);
6815
+ if (!count)
6816
+ throw new Error("\u4E8B\u52A1\u76EE\u6807\u8BFB\u53D6\u63D0\u524D\u7ED3\u675F");
6817
+ offset += count;
6818
+ }
6819
+ const after = fstatSync5(fd, { bigint: true });
6820
+ if (after.dev !== before.dev || after.ino !== before.ino || after.size !== before.size || after.mtimeNs !== before.mtimeNs || after.ctimeNs !== before.ctimeNs) {
6821
+ throw new Error("\u4E8B\u52A1\u76EE\u6807\u5728\u8BC1\u660E\u671F\u95F4\u53D1\u751F\u53D8\u5316");
6822
+ }
6823
+ return {
6824
+ device: before.dev,
6825
+ inode: before.ino,
6826
+ hash: hashContent(content),
6827
+ mode: Number(before.mode & 0o777n)
6828
+ };
6829
+ } finally {
6830
+ closeSync7(fd);
6831
+ }
6832
+ }
6833
+ function pathMatches(parent, expected) {
6834
+ try {
6835
+ const current = snapshot(parent);
6836
+ return current.device === expected.device && current.inode === expected.inode && current.hash === expected.hash;
6837
+ } catch {
6838
+ return false;
6839
+ }
6840
+ }
6841
+ function pathMatchesPayload(parent, expected, content) {
6842
+ try {
6843
+ const current = snapshot(parent);
6844
+ return current.device === expected.device && current.inode === expected.inode && current.hash === hashContent(content);
6845
+ } catch {
6846
+ return false;
6847
+ }
6848
+ }
6849
+ function matchesExpected(snapshot2, expected) {
6850
+ return expected.kind === "hash" && snapshot2.hash === expected.value;
6851
+ }
6852
+ function matchesPayload(snapshot2, content) {
6853
+ return snapshot2.hash === hashContent(content);
6854
+ }
6855
+ function removeTemporary(parent, name) {
6856
+ try {
6857
+ unlinkAt(withLeaf(parent, name));
6858
+ } catch (error) {
6859
+ if (!hasFsCode5(error, "ENOENT"))
6860
+ throw error;
6861
+ }
6862
+ }
6863
+ function withLeaf(parent, leaf) {
6864
+ return { ...parent, leaf };
6865
+ }
6866
+ function assertSameDirectory(path2, temporaryPath) {
6867
+ if (dirname6(path2) !== dirname6(temporaryPath)) {
6868
+ throw new Error("\u4E8B\u52A1 CAS \u4E34\u65F6\u6587\u4EF6\u5FC5\u987B\u4E0E\u76EE\u6807\u4F4D\u4E8E\u540C\u4E00\u76EE\u5F55");
6869
+ }
6870
+ }
6871
+ function casError(path2, artifactPath, cause) {
6872
+ return new TransactionCasError(`\u8BA1\u5212\u540E\u5DF2\u53D8\u5316\uFF1A${path2}`, path2, artifactPath ? [{ path: path2, artifactPath }] : [], { cause });
6873
+ }
6874
+ function hasFsCode5(error, code) {
6875
+ return error instanceof Error && "code" in error && error.code === code;
6876
+ }
6877
+
6334
6878
  // src/update/transaction-cas.ts
6335
6879
  async function anchoredCompareAndReplace(input) {
6336
- assertSameDirectory(input.path, input.temporaryPath);
6880
+ if (process.platform === "win32") {
6881
+ return windowsAnchoredCompareAndReplace(input);
6882
+ }
6883
+ assertSameDirectory2(input.path, input.temporaryPath);
6337
6884
  const parent = await openAnchoredParent(input.root, input.path, true, input.parentMode);
6338
- const temporaryName = basename6(input.temporaryPath);
6885
+ const temporaryName = basename8(input.temporaryPath);
6339
6886
  let ownsTemporary = false;
6340
6887
  let exchanged = false;
6341
6888
  let containsUnknownProjectBytes = false;
@@ -6346,103 +6893,106 @@ async function anchoredCompareAndReplace(input) {
6346
6893
  targetProof = openFileProof(parent);
6347
6894
  }
6348
6895
  const mode = input.mode ?? (targetProof ? modeOfProof(targetProof) : 384);
6349
- writeExclusiveAt(withLeaf(parent, temporaryName), input.content, mode);
6896
+ writeExclusiveAt(withLeaf2(parent, temporaryName), input.content, mode);
6350
6897
  ownsTemporary = true;
6351
- desiredProof = openFileProof(withLeaf(parent, temporaryName));
6898
+ desiredProof = openFileProof(withLeaf2(parent, temporaryName));
6352
6899
  await input.hooks?.beforeAtomicRename?.();
6353
6900
  if (input.expected.kind === "missing") {
6354
- await publishMissing(parent, temporaryName, input, desiredProof, mode);
6355
- ownsTemporary = pathMatchesPayloadProof(withLeaf(parent, temporaryName), desiredProof, input.content, mode);
6901
+ await publishMissing2(parent, temporaryName, input, desiredProof, mode);
6902
+ ownsTemporary = pathMatchesPayloadProof(withLeaf2(parent, temporaryName), desiredProof, input.content, mode);
6356
6903
  containsUnknownProjectBytes = !ownsTemporary;
6357
6904
  if (!ownsTemporary) {
6358
- throw casError(input.path, input.temporaryPath);
6905
+ throw casError2(input.path, input.temporaryPath);
6359
6906
  }
6360
6907
  return;
6361
6908
  }
6362
- if (!targetProof || !pathMatchesProof(parent, targetProof) || !assertProofMatches(targetProof, input.expected, input.expectedMode) || !pathMatchesProof(withLeaf(parent, temporaryName), desiredProof) || !assertProofPayload(desiredProof, input.content, mode)) {
6363
- throw casError(input.path);
6909
+ if (!targetProof || !pathMatchesProof(parent, targetProof) || !assertProofMatches(targetProof, input.expected, input.expectedMode) || !pathMatchesProof(withLeaf2(parent, temporaryName), desiredProof) || !assertProofPayload(desiredProof, input.content, mode)) {
6910
+ throw casError2(input.path);
6364
6911
  }
6365
6912
  exchangeAt(parent, temporaryName, parent.leaf);
6366
6913
  exchanged = true;
6367
6914
  ownsTemporary = false;
6368
6915
  containsUnknownProjectBytes = true;
6369
6916
  await input.hooks?.afterExchangeBeforeProof?.();
6370
- const proofValid = pathMatchesProof(withLeaf(parent, temporaryName), targetProof) && assertProofMatches(targetProof, input.expected, input.expectedMode) && pathMatchesProof(parent, desiredProof) && assertProofPayload(desiredProof, input.content, mode);
6917
+ const proofValid = pathMatchesProof(withLeaf2(parent, temporaryName), targetProof) && assertProofMatches(targetProof, input.expected, input.expectedMode) && pathMatchesProof(parent, desiredProof) && assertProofPayload(desiredProof, input.content, mode);
6371
6918
  if (!proofValid) {
6372
- await rollbackExchange(parent, temporaryName, input, targetProof);
6919
+ await rollbackExchange2(parent, temporaryName, input, targetProof);
6373
6920
  exchanged = false;
6374
- ownsTemporary = pathMatchesPayloadProof(withLeaf(parent, temporaryName), desiredProof, input.content, mode);
6921
+ ownsTemporary = pathMatchesPayloadProof(withLeaf2(parent, temporaryName), desiredProof, input.content, mode);
6375
6922
  containsUnknownProjectBytes = !ownsTemporary;
6376
- throw casError(input.path, ownsTemporary ? undefined : input.temporaryPath);
6923
+ throw casError2(input.path, ownsTemporary ? undefined : input.temporaryPath);
6377
6924
  }
6378
6925
  await input.hooks?.afterAtomicRenameBeforeInspect?.();
6379
- ownsTemporary = pathMatchesExpectedProof(withLeaf(parent, temporaryName), targetProof, input.expected, input.expectedMode);
6926
+ ownsTemporary = pathMatchesExpectedProof(withLeaf2(parent, temporaryName), targetProof, input.expected, input.expectedMode);
6380
6927
  containsUnknownProjectBytes = !ownsTemporary;
6381
6928
  if (!ownsTemporary) {
6382
- throw casError(input.path, input.temporaryPath);
6929
+ throw casError2(input.path, input.temporaryPath);
6383
6930
  }
6384
6931
  } catch (error) {
6385
6932
  if (error instanceof TransactionCasError)
6386
6933
  throw error;
6387
6934
  if (exchanged) {
6388
- throw casError(input.path, input.temporaryPath, error);
6935
+ throw casError2(input.path, input.temporaryPath, error);
6389
6936
  }
6390
6937
  if (containsUnknownProjectBytes) {
6391
- throw casError(input.path, input.temporaryPath, error);
6938
+ throw casError2(input.path, input.temporaryPath, error);
6392
6939
  }
6393
- if (hasFsCode3(error, "ENOENT") || hasFsCode3(error, "EEXIST") || hasFsCode3(error, "ELOOP") || hasFsCode3(error, "ENOTDIR")) {
6394
- throw casError(input.path);
6940
+ if (hasFsCode4(error, "ENOENT") || hasFsCode4(error, "EEXIST") || hasFsCode4(error, "ELOOP") || hasFsCode4(error, "ENOTDIR")) {
6941
+ throw casError2(input.path);
6395
6942
  }
6396
6943
  throw error;
6397
6944
  } finally {
6398
6945
  if (ownsTemporary)
6399
- removeTemporary(parent, temporaryName);
6946
+ removeTemporary2(parent, temporaryName);
6400
6947
  desiredProof?.close();
6401
6948
  targetProof?.close();
6402
6949
  await parent.close();
6403
6950
  }
6404
6951
  }
6405
6952
  async function anchoredCompareAndRemove(input) {
6406
- assertSameDirectory(input.path, input.quarantinePath);
6953
+ if (process.platform === "win32") {
6954
+ return windowsAnchoredCompareAndRemove(input);
6955
+ }
6956
+ assertSameDirectory2(input.path, input.quarantinePath);
6407
6957
  if (input.expected.kind === "missing")
6408
6958
  return;
6409
6959
  let parent;
6410
6960
  try {
6411
6961
  parent = await openAnchoredParent(input.root, input.path, false);
6412
6962
  } catch (error) {
6413
- if (hasFsCode3(error, "ENOENT"))
6414
- throw casError(input.path);
6963
+ if (hasFsCode4(error, "ENOENT"))
6964
+ throw casError2(input.path);
6415
6965
  throw error;
6416
6966
  }
6417
- const quarantineName = basename6(input.quarantinePath);
6967
+ const quarantineName = basename8(input.quarantinePath);
6418
6968
  let ownsQuarantine = false;
6419
6969
  let targetProof;
6420
6970
  try {
6421
6971
  targetProof = openFileProof(parent);
6422
6972
  await input.hooks?.beforeAtomicRename?.();
6423
6973
  if (!pathMatchesProof(parent, targetProof) || !assertProofMatches(targetProof, input.expected, input.expectedMode)) {
6424
- throw casError(input.path);
6974
+ throw casError2(input.path);
6425
6975
  }
6426
6976
  moveNoReplaceAt(parent, parent.leaf, quarantineName);
6427
6977
  ownsQuarantine = true;
6428
- if (!pathMatchesProof(withLeaf(parent, quarantineName), targetProof) || !assertProofMatches(targetProof, input.expected, input.expectedMode)) {
6429
- throw casError(input.path, input.quarantinePath);
6978
+ if (!pathMatchesProof(withLeaf2(parent, quarantineName), targetProof) || !assertProofMatches(targetProof, input.expected, input.expectedMode)) {
6979
+ throw casError2(input.path, input.quarantinePath);
6430
6980
  }
6431
6981
  await input.hooks?.afterAtomicRenameBeforeInspect?.();
6432
- if (pathMatchesExpectedProof(withLeaf(parent, quarantineName), targetProof, input.expected, input.expectedMode)) {
6433
- removeTemporary(parent, quarantineName);
6982
+ if (pathMatchesExpectedProof(withLeaf2(parent, quarantineName), targetProof, input.expected, input.expectedMode)) {
6983
+ removeTemporary2(parent, quarantineName);
6434
6984
  ownsQuarantine = false;
6435
6985
  return;
6436
6986
  }
6437
- throw casError(input.path, input.quarantinePath);
6987
+ throw casError2(input.path, input.quarantinePath);
6438
6988
  } catch (error) {
6439
6989
  if (error instanceof TransactionCasError)
6440
6990
  throw error;
6441
6991
  if (ownsQuarantine) {
6442
- throw casError(input.path, input.quarantinePath, error);
6992
+ throw casError2(input.path, input.quarantinePath, error);
6443
6993
  }
6444
- if (hasFsCode3(error, "ENOENT") || hasFsCode3(error, "EEXIST")) {
6445
- throw casError(input.path);
6994
+ if (hasFsCode4(error, "ENOENT") || hasFsCode4(error, "EEXIST")) {
6995
+ throw casError2(input.path);
6446
6996
  }
6447
6997
  throw error;
6448
6998
  } finally {
@@ -6458,8 +7008,8 @@ async function linearizeExpectation(input) {
6458
7008
  content = readFileAt(parent);
6459
7009
  } catch (error) {
6460
7010
  await parent.close();
6461
- if (hasFsCode3(error, "ENOENT"))
6462
- throw casError(input.path);
7011
+ if (hasFsCode4(error, "ENOENT"))
7012
+ throw casError2(input.path);
6463
7013
  throw error;
6464
7014
  }
6465
7015
  await parent.close();
@@ -6471,61 +7021,61 @@ async function linearizeExpectation(input) {
6471
7021
  }
6472
7022
  throw new Error(`\u7F3A\u5931\u8DEF\u5F84\u5FC5\u987B\u7531\u5199\u5165\u6216\u5220\u9664 CAS \u63D0\u4F9B\u7EBF\u6027\u5316\u8BC1\u636E\uFF1A${input.path}`);
6473
7023
  }
6474
- async function publishMissing(parent, temporaryName, input, desiredProof, mode) {
6475
- if (!pathMatchesProof(withLeaf(parent, temporaryName), desiredProof) || !assertProofPayload(desiredProof, input.content, mode)) {
6476
- throw casError(input.path);
7024
+ async function publishMissing2(parent, temporaryName, input, desiredProof, mode) {
7025
+ if (!pathMatchesProof(withLeaf2(parent, temporaryName), desiredProof) || !assertProofPayload(desiredProof, input.content, mode)) {
7026
+ throw casError2(input.path);
6477
7027
  }
6478
7028
  try {
6479
7029
  linkAt(parent, temporaryName, parent.leaf);
6480
7030
  } catch (error) {
6481
- if (hasFsCode3(error, "EEXIST"))
6482
- throw casError(input.path);
7031
+ if (hasFsCode4(error, "EEXIST"))
7032
+ throw casError2(input.path);
6483
7033
  throw error;
6484
7034
  }
6485
7035
  if (!pathMatchesProof(parent, desiredProof) || !assertProofPayload(desiredProof, input.content, mode)) {
6486
- throw casError(input.path, input.temporaryPath);
7036
+ throw casError2(input.path, input.temporaryPath);
6487
7037
  }
6488
7038
  await input.hooks?.afterAtomicRenameBeforeInspect?.();
6489
7039
  }
6490
- async function rollbackExchange(parent, temporaryName, input, targetProof) {
6491
- if (!pathMatchesProof(withLeaf(parent, temporaryName), targetProof) || !assertProofMatches(targetProof, input.expected, input.expectedMode)) {
6492
- throw casError(input.path, input.temporaryPath);
7040
+ async function rollbackExchange2(parent, temporaryName, input, targetProof) {
7041
+ if (!pathMatchesProof(withLeaf2(parent, temporaryName), targetProof) || !assertProofMatches(targetProof, input.expected, input.expectedMode)) {
7042
+ throw casError2(input.path, input.temporaryPath);
6493
7043
  }
6494
7044
  await input.hooks?.beforeExchangeRollback?.();
6495
- if (!pathMatchesProof(withLeaf(parent, temporaryName), targetProof) || !assertProofMatches(targetProof, input.expected, input.expectedMode)) {
6496
- throw casError(input.path, input.temporaryPath);
7045
+ if (!pathMatchesProof(withLeaf2(parent, temporaryName), targetProof) || !assertProofMatches(targetProof, input.expected, input.expectedMode)) {
7046
+ throw casError2(input.path, input.temporaryPath);
6497
7047
  }
6498
7048
  exchangeAt(parent, temporaryName, parent.leaf, true);
6499
7049
  await input.hooks?.afterExchangeRollbackBeforeCleanup?.();
6500
7050
  }
6501
- function removeTemporary(parent, name) {
7051
+ function removeTemporary2(parent, name) {
6502
7052
  try {
6503
- unlinkAt(withLeaf(parent, name));
7053
+ unlinkAt(withLeaf2(parent, name));
6504
7054
  } catch (error) {
6505
- if (!hasFsCode3(error, "ENOENT"))
7055
+ if (!hasFsCode4(error, "ENOENT"))
6506
7056
  throw error;
6507
7057
  }
6508
7058
  }
6509
- function withLeaf(parent, leaf) {
7059
+ function withLeaf2(parent, leaf) {
6510
7060
  return { ...parent, leaf };
6511
7061
  }
6512
- function assertSameDirectory(path2, temporaryPath) {
6513
- if (dirname5(path2) !== dirname5(temporaryPath)) {
7062
+ function assertSameDirectory2(path2, temporaryPath) {
7063
+ if (dirname7(path2) !== dirname7(temporaryPath)) {
6514
7064
  throw new Error("\u4E8B\u52A1 CAS \u4E34\u65F6\u6587\u4EF6\u5FC5\u987B\u4E0E\u76EE\u6807\u4F4D\u4E8E\u540C\u4E00\u76EE\u5F55");
6515
7065
  }
6516
7066
  }
6517
- function casError(path2, artifactPath, cause) {
7067
+ function casError2(path2, artifactPath, cause) {
6518
7068
  return new TransactionCasError(`\u8BA1\u5212\u540E\u5DF2\u53D8\u5316\uFF1A${path2}`, path2, artifactPath ? [{ path: path2, artifactPath }] : [], { cause });
6519
7069
  }
6520
7070
 
6521
7071
  // src/update/transaction-runtime.ts
6522
7072
  import { randomUUID as randomUUID2 } from "crypto";
6523
- import { join as join13 } from "path";
7073
+ import { join as join14 } from "path";
6524
7074
 
6525
7075
  // src/update/transaction-state-temporaries.ts
6526
7076
  import { randomUUID } from "crypto";
6527
7077
  import { readdir as readdir7 } from "fs/promises";
6528
- import { join as join12 } from "path";
7078
+ import { join as join13 } from "path";
6529
7079
  function serializeTransactionState(state) {
6530
7080
  return `${JSON.stringify(state, null, 2)}
6531
7081
  `;
@@ -6641,8 +7191,8 @@ function stateTemporaryName(identity, cleanup) {
6641
7191
  return `${prefix}.${identity.kind}.${identity.ownerToken}.${identity.nonce}.tmp`;
6642
7192
  }
6643
7193
  async function listWindyDirectory(root) {
6644
- return readdir7(join12(root, ".windy")).catch((error) => {
6645
- if (hasFsCode3(error, "ENOENT"))
7194
+ return readdir7(join13(root, ".windy")).catch((error) => {
7195
+ if (hasFsCode4(error, "ENOENT"))
6646
7196
  return [];
6647
7197
  throw error;
6648
7198
  });
@@ -6675,7 +7225,7 @@ function createTransactionState(root, updateId, entries, manifestHash) {
6675
7225
  return {
6676
7226
  schemaVersion: 1,
6677
7227
  updateId,
6678
- backupDirectory: join13(root, backupRelativePath(updateId)),
7228
+ backupDirectory: join14(root, backupRelativePath(updateId)),
6679
7229
  entries,
6680
7230
  ownerToken: randomUUID2(),
6681
7231
  phase: "claiming",
@@ -6694,7 +7244,7 @@ async function claimTransactionState(root, state, hooks) {
6694
7244
  expected: { kind: "missing" }
6695
7245
  });
6696
7246
  } catch (error) {
6697
- if (hasFsCode3(error, "EEXIST") || error instanceof TransactionCasError) {
7247
+ if (hasFsCode4(error, "EEXIST") || error instanceof TransactionCasError) {
6698
7248
  throw new Error("\u68C0\u6D4B\u5230\u672A\u5B8C\u6210\u66F4\u65B0\uFF0C\u8BF7\u5148\u8FD0\u884C bun run windy doctor --repair", { cause: error });
6699
7249
  }
6700
7250
  throw error;
@@ -6734,7 +7284,7 @@ async function backupEntriesToDisk(root, backupPath, entries, afterEntry) {
6734
7284
  if (entry.mode !== undefined && await safeFileMode(root, entry.path) !== entry.mode) {
6735
7285
  throw new TransactionCasError(`\u5F85\u5907\u4EFD\u6587\u4EF6 mode \u5DF2\u53D8\u5316\uFF1A${entry.path}`, entry.path);
6736
7286
  }
6737
- await writeExclusive(root, join13(backupPath, "files", entry.path), content, undefined, entry.mode);
7287
+ await writeExclusive(root, join14(backupPath, "files", entry.path), content, undefined, entry.mode);
6738
7288
  await afterEntry?.();
6739
7289
  }
6740
7290
  }
@@ -7042,8 +7592,8 @@ async function removeOwnedResidue(root, evidence, hash, mode) {
7042
7592
  }
7043
7593
 
7044
7594
  // src/update/transaction-recovery-files.ts
7045
- import { join as join14 } from "path";
7046
- function matchesExpected(actualHash, actualMode, expected, expectedMode) {
7595
+ import { join as join15 } from "path";
7596
+ function matchesExpected2(actualHash, actualMode, expected, expectedMode) {
7047
7597
  return expected.kind === "missing" ? actualHash === undefined : actualHash === expected.value && (expectedMode === undefined || actualMode === expectedMode);
7048
7598
  }
7049
7599
  async function readRecoveryBackups(root, backupPath, state, preserved) {
@@ -7054,7 +7604,7 @@ async function readRecoveryBackups(root, backupPath, state, preserved) {
7054
7604
  await inspectSafePath(root, entry.path);
7055
7605
  if (!entry.existed)
7056
7606
  continue;
7057
- const backupFile = join14(backupPath, "files", entry.path);
7607
+ const backupFile = join15(backupPath, "files", entry.path);
7058
7608
  const content = await readSafeOptional(root, backupFile);
7059
7609
  if (!content)
7060
7610
  throw new Error(`\u4E8B\u52A1\u5907\u4EFD\u7F3A\u5931\uFF1A${entry.path}`);
@@ -7068,7 +7618,7 @@ async function readRecoveryBackups(root, backupPath, state, preserved) {
7068
7618
  async function assertRestoredEntries(root, state, backups) {
7069
7619
  for (const entry of state.entries) {
7070
7620
  const expected = entry.existed ? { kind: "hash", value: hashContent(backups.get(entry.path)) } : { kind: "missing" };
7071
- if (!matchesExpected(await hashSafePath(root, entry.path), await safeFileMode(root, entry.path), expected, entry.mode)) {
7621
+ if (!matchesExpected2(await hashSafePath(root, entry.path), await safeFileMode(root, entry.path), expected, entry.mode)) {
7072
7622
  throw new Error(`\u4E8B\u52A1\u8DEF\u5F84\u5C1A\u672A\u771F\u5B9E\u6062\u590D\uFF1A${entry.path}`);
7073
7623
  }
7074
7624
  const evidence = state.recoveryEvidence?.find(({ path: path2 }) => path2 === entry.path);
@@ -7091,8 +7641,8 @@ async function unresolvedPreservePaths(root, backupPath, state) {
7091
7641
  const actualHash = await hashSafePath(root, path2);
7092
7642
  const actualMode = await safeFileMode(root, path2);
7093
7643
  const mutation = state.mutationEvidence?.find((evidence) => evidence.path === path2);
7094
- const matchesBackup = matchesExpected(actualHash, actualMode, backup, entry.mode);
7095
- const matchesOutcome = Boolean(mutation?.linearized && mutation.outcome && matchesExpected(actualHash, actualMode, mutation.outcome, mutation.outcomeMode));
7644
+ const matchesBackup = matchesExpected2(actualHash, actualMode, backup, entry.mode);
7645
+ const matchesOutcome = Boolean(mutation?.linearized && mutation.outcome && matchesExpected2(actualHash, actualMode, mutation.outcome, mutation.outcomeMode));
7096
7646
  const hasConflictArtifact = state.conflictArtifacts?.some((artifact) => artifact.path === path2) ?? false;
7097
7647
  if (!matchesBackup && (!matchesOutcome || hasConflictArtifact)) {
7098
7648
  unresolved.push(path2);
@@ -7164,7 +7714,7 @@ async function restoreUpdateState(projectDirectory, state, options) {
7164
7714
  const actualHash = await hashSafePath(root, entry.path);
7165
7715
  if (current.phase === "committing") {
7166
7716
  const expected = current.expectations?.find(({ path: path2 }) => path2 === entry.path);
7167
- if (!expected || !matchesExpected(actualHash, await safeFileMode(root, entry.path), expected.expected, expected.mode)) {
7717
+ if (!expected || !matchesExpected2(actualHash, await safeFileMode(root, entry.path), expected.expected, expected.mode)) {
7168
7718
  newlyPreserved.push(entry.path);
7169
7719
  } else {
7170
7720
  recoveryExpectations.set(entry.path, expected);
@@ -7174,9 +7724,9 @@ async function restoreUpdateState(projectDirectory, state, options) {
7174
7724
  const evidence = current.mutationEvidence?.find(({ path: path2 }) => path2 === entry.path);
7175
7725
  if (!evidence) {
7176
7726
  newlyPreserved.push(entry.path);
7177
- } else if (matchesExpected(actualHash, await safeFileMode(root, entry.path), evidence.before, evidence.beforeMode)) {
7727
+ } else if (matchesExpected2(actualHash, await safeFileMode(root, entry.path), evidence.before, evidence.beforeMode)) {
7178
7728
  continue;
7179
- } else if (evidence.outcome && matchesExpected(actualHash, await safeFileMode(root, entry.path), evidence.outcome, evidence.outcomeMode)) {
7729
+ } else if (evidence.outcome && matchesExpected2(actualHash, await safeFileMode(root, entry.path), evidence.outcome, evidence.outcomeMode)) {
7180
7730
  recoveryExpectations.set(entry.path, {
7181
7731
  expected: evidence.outcome,
7182
7732
  mode: evidence.outcomeMode
@@ -7685,7 +8235,7 @@ async function diagnoseProject(projectDirectory, repair = false) {
7685
8235
  if (file.ownership === "project-owned")
7686
8236
  continue;
7687
8237
  try {
7688
- const changed = hashContent(await readFile11(join15(projectDirectory, file.path))) !== file.hash;
8238
+ const changed = hashContent(await readFile11(join16(projectDirectory, file.path))) !== file.hash;
7689
8239
  if (!changed)
7690
8240
  continue;
7691
8241
  modifiedManagedFiles.push(file.path);
@@ -7735,6 +8285,11 @@ var recipes = [
7735
8285
  id: "starter-0.6.8-to-0.6.9",
7736
8286
  from: "0.6.8",
7737
8287
  to: "0.6.9"
8288
+ },
8289
+ {
8290
+ id: "starter-0.6.9-to-0.6.10",
8291
+ from: "0.6.9",
8292
+ to: "0.6.10"
7738
8293
  }
7739
8294
  ];
7740
8295
  function resolveRecipeChain(sourceVersion, targetVersion) {
@@ -7781,17 +8336,17 @@ function parseVersion2(version) {
7781
8336
 
7782
8337
  // src/update/updater.ts
7783
8338
  import { readFile as readFile23, rm as rm8 } from "fs/promises";
7784
- import { join as join27 } from "path";
8339
+ import { join as join28 } from "path";
7785
8340
 
7786
8341
  // src/update/artifacts.ts
7787
8342
  import { mkdtemp, readFile as readFile14 } from "fs/promises";
7788
8343
  import { tmpdir } from "os";
7789
- import { basename as basename8, join as join18 } from "path";
8344
+ import { basename as basename10, join as join19 } from "path";
7790
8345
 
7791
8346
  // src/update/published-artifacts.ts
7792
8347
  import { createHash as createHash4 } from "crypto";
7793
8348
  import { mkdir as mkdir6, readFile as readFile12, writeFile as writeFile10 } from "fs/promises";
7794
- import { basename as basename7, join as join16 } from "path";
8349
+ import { basename as basename9, join as join17 } from "path";
7795
8350
 
7796
8351
  // src/update/safe-archive.ts
7797
8352
  import { mkdir as mkdir5 } from "fs/promises";
@@ -7843,17 +8398,17 @@ async function downloadPublicArtifact(temporaryRoot, label, version, expectedInt
7843
8398
  }
7844
8399
  const archive = await readBoundedResponse(response, `create-windy@${version} artifact `);
7845
8400
  verifyArchive(metadata, archive);
7846
- const destination = join16(temporaryRoot, `${label}-artifact`);
7847
- const archivePath = join16(temporaryRoot, `${label}.tgz`);
8401
+ const destination = join17(temporaryRoot, `${label}-artifact`);
8402
+ const archivePath = join17(temporaryRoot, `${label}.tgz`);
7848
8403
  await writeFile10(archivePath, archive);
7849
8404
  await extractSafeTarArchive({
7850
8405
  archivePath,
7851
8406
  destination,
7852
8407
  cwd: temporaryRoot
7853
8408
  });
7854
- const packageRoot2 = join16(destination, "package");
7855
- const packageJson = JSON.parse(await readFile12(join16(packageRoot2, "package.json"), "utf8"));
7856
- const template = await readTemplateMetadata(join16(packageRoot2, "template"));
8409
+ const packageRoot2 = join17(destination, "package");
8410
+ const packageJson = JSON.parse(await readFile12(join17(packageRoot2, "package.json"), "utf8"));
8411
+ const template = await readTemplateMetadata(join17(packageRoot2, "template"));
7857
8412
  if (packageJson.name !== "create-windy" || packageJson.version !== version || template.generatorVersion !== version) {
7858
8413
  throw new Error(`create-windy@${version} \u5305\u8EAB\u4EFD\u6216\u6A21\u677F\u5143\u6570\u636E\u4E0D\u4E00\u81F4`);
7859
8414
  }
@@ -7985,10 +8540,10 @@ function verifyArchive(metadata, archive) {
7985
8540
  }
7986
8541
  }
7987
8542
  async function generatePublicArtifactProject(temporaryRoot, label, projectName, packageRoot2, provenance) {
7988
- const parent = join16(temporaryRoot, label);
8543
+ const parent = join17(temporaryRoot, label);
7989
8544
  await mkdir6(parent, { recursive: true });
7990
8545
  const args = [
7991
- join16(packageRoot2, "dist/cli.js"),
8546
+ join17(packageRoot2, "dist/cli.js"),
7992
8547
  projectName,
7993
8548
  "--yes",
7994
8549
  "--skip-install",
@@ -8008,7 +8563,7 @@ async function generatePublicArtifactProject(temporaryRoot, label, projectName,
8008
8563
  }
8009
8564
  }
8010
8565
  await assertProcess("bun", args, parent);
8011
- return join16(parent, projectName);
8566
+ return join17(parent, projectName);
8012
8567
  }
8013
8568
 
8014
8569
  // src/module-history.ts
@@ -8019,15 +8574,15 @@ import {
8019
8574
  readFile as readFile13,
8020
8575
  writeFile as writeFile11
8021
8576
  } from "fs/promises";
8022
- import { dirname as dirname6, join as join17, relative as relative4, sep as sep4 } from "path";
8577
+ import { dirname as dirname8, join as join18, relative as relative5, sep as sep4 } from "path";
8023
8578
  async function archiveRemovedModuleMigrations(input) {
8024
8579
  await assertExistingHistoryIntegrity(input.projectDirectory);
8025
- let changed = await copyMigrationTree(input.projectDirectory, ".windy/module-history", join17(input.targetDirectory, ".windy/module-history"));
8580
+ let changed = await copyMigrationTree(input.projectDirectory, ".windy/module-history", join18(input.targetDirectory, ".windy/module-history"));
8026
8581
  const target = new Set(input.targetModules);
8027
8582
  const removed = moduleDistributionCatalog.filter(({ name }) => input.sourceModules.includes(name) && !target.has(name));
8028
8583
  for (const manifest of removed) {
8029
8584
  for (const root of manifest.migrationRoots) {
8030
- changed = await copyMigrationTree(input.projectDirectory, root, join17(input.targetDirectory, ".windy/module-history", manifest.name, root)) || changed;
8585
+ changed = await copyMigrationTree(input.projectDirectory, root, join18(input.targetDirectory, ".windy/module-history", manifest.name, root)) || changed;
8031
8586
  }
8032
8587
  }
8033
8588
  if (changed) {
@@ -8035,7 +8590,7 @@ async function archiveRemovedModuleMigrations(input) {
8035
8590
  }
8036
8591
  }
8037
8592
  async function assertExistingHistoryIntegrity(projectDirectory) {
8038
- const historyRoot = join17(projectDirectory, ".windy/module-history");
8593
+ const historyRoot = join18(projectDirectory, ".windy/module-history");
8039
8594
  const metadata = await readOptionalMetadata(historyRoot);
8040
8595
  if (!metadata)
8041
8596
  return;
@@ -8045,7 +8600,7 @@ async function assertExistingHistoryIntegrity(projectDirectory) {
8045
8600
  const manifest = await readManagedFilesManifest(projectDirectory);
8046
8601
  const expected = new Map(manifest.files.map((entry) => [entry.path, entry]));
8047
8602
  for (const path2 of await collectRegularFiles(historyRoot)) {
8048
- const relativePath2 = relative4(projectDirectory, path2).split(sep4).join("/");
8603
+ const relativePath2 = relative5(projectDirectory, path2).split(sep4).join("/");
8049
8604
  const entry = expected.get(relativePath2);
8050
8605
  if (!entry || isMissingManagedFile(entry)) {
8051
8606
  throw new Error(`\u6A21\u5757 migration \u5386\u53F2\u672A\u767B\u8BB0\u5230\u53D7\u7BA1\u6E05\u5355\uFF1A${relativePath2}`);
@@ -8056,7 +8611,7 @@ async function assertExistingHistoryIntegrity(projectDirectory) {
8056
8611
  }
8057
8612
  }
8058
8613
  async function copyMigrationTree(projectRoot, relativeRoot, targetRoot) {
8059
- const sourceRoot = join17(projectRoot, relativeRoot);
8614
+ const sourceRoot = join18(projectRoot, relativeRoot);
8060
8615
  const rootMetadata = await readOptionalMetadata(sourceRoot);
8061
8616
  if (!rootMetadata)
8062
8617
  return false;
@@ -8064,8 +8619,8 @@ async function copyMigrationTree(projectRoot, relativeRoot, targetRoot) {
8064
8619
  throw new Error(`\u6A21\u5757 migration \u6839\u76EE\u5F55\u65E0\u6548\uFF1A${relativeRoot}`);
8065
8620
  }
8066
8621
  for (const source of await collectRegularFiles(sourceRoot)) {
8067
- const target = join17(targetRoot, relative4(sourceRoot, source).split(sep4).join("/"));
8068
- await mkdir7(dirname6(target), { recursive: true });
8622
+ const target = join18(targetRoot, relative5(sourceRoot, source).split(sep4).join("/"));
8623
+ await mkdir7(dirname8(target), { recursive: true });
8069
8624
  await writeFile11(target, await readFile13(source));
8070
8625
  }
8071
8626
  return true;
@@ -8076,7 +8631,7 @@ async function collectRegularFiles(root) {
8076
8631
  return files.sort();
8077
8632
  async function visit(directory) {
8078
8633
  for (const name of (await readdir8(directory)).sort()) {
8079
- const path2 = join17(directory, name);
8634
+ const path2 = join18(directory, name);
8080
8635
  const metadata = await lstat6(path2);
8081
8636
  if (metadata.isSymbolicLink()) {
8082
8637
  throw new Error(`\u6A21\u5757 migration \u4E0D\u5141\u8BB8\u7B26\u53F7\u94FE\u63A5\uFF1A${path2}`);
@@ -8106,10 +8661,10 @@ class PublishedArtifactProvider {
8106
8661
  this.#fetch = fetcher;
8107
8662
  }
8108
8663
  async prepare(projectDirectory, provenance, targetModules) {
8109
- const temporaryRoot = await mkdtemp(join18(tmpdir(), "windy-update-"));
8664
+ const temporaryRoot = await mkdtemp(join19(tmpdir(), "windy-update-"));
8110
8665
  const projectName = await readProjectName2(projectDirectory);
8111
- const baseDirectory = join18(temporaryRoot, "base", projectName);
8112
- const targetDirectory = join18(temporaryRoot, "target", projectName);
8666
+ const baseDirectory = join19(temporaryRoot, "base", projectName);
8667
+ const targetDirectory = join19(temporaryRoot, "target", projectName);
8113
8668
  const baseArtifact = await downloadPublicArtifact(temporaryRoot, "base", provenance.generatorVersion, undefined, this.#fetch);
8114
8669
  if (baseArtifact.identity.templateCommit !== provenance.templateCommit) {
8115
8670
  throw new Error("Project Lock \u4E0E\u6765\u6E90 registry artifact \u7684 template commit \u4E0D\u4E00\u81F4");
@@ -8137,13 +8692,13 @@ class PublishedArtifactProvider {
8137
8692
  }
8138
8693
  }
8139
8694
  async function readProjectName2(projectDirectory) {
8140
- const source = JSON.parse(await readFile14(join18(projectDirectory, "package.json"), "utf8"));
8141
- return source.name || basename8(projectDirectory);
8695
+ const source = JSON.parse(await readFile14(join19(projectDirectory, "package.json"), "utf8"));
8696
+ return source.name || basename10(projectDirectory);
8142
8697
  }
8143
8698
 
8144
8699
  // src/update/planner.ts
8145
8700
  import { readFile as readFile21 } from "fs/promises";
8146
- import { dirname as dirname7, join as join25 } from "path";
8701
+ import { dirname as dirname9, join as join26 } from "path";
8147
8702
 
8148
8703
  // src/update/docker-copy-update-plan.ts
8149
8704
  async function deriveDockerfilePlans(files, snapshots, paths, targetWorkspaceManifests) {
@@ -8232,15 +8787,15 @@ function matchesWorkspace(pattern, directory) {
8232
8787
 
8233
8788
  // src/update/migration-reconciler.ts
8234
8789
  import { readFile as readFile18 } from "fs/promises";
8235
- import { join as join21 } from "path";
8790
+ import { join as join22 } from "path";
8236
8791
 
8237
8792
  // src/update/migration-adoption.ts
8238
8793
  import { readFile as readFile17 } from "fs/promises";
8239
- import { join as join20 } from "path";
8794
+ import { join as join21 } from "path";
8240
8795
 
8241
8796
  // src/update/migration-project-file.ts
8242
8797
  import { readFile as readFile15 } from "fs/promises";
8243
- import { join as join19 } from "path";
8798
+ import { join as join20 } from "path";
8244
8799
  async function readProjectJson(input, path2) {
8245
8800
  const content = await readProjectFile(input, path2);
8246
8801
  if (!content) {
@@ -8256,7 +8811,7 @@ async function readProjectFile(input, path2) {
8256
8811
  }
8257
8812
  let content;
8258
8813
  try {
8259
- content = await readFile15(join19(input.projectDirectory, path2));
8814
+ content = await readFile15(join20(input.projectDirectory, path2));
8260
8815
  } catch (error) {
8261
8816
  if (!isMissingFileError(error))
8262
8817
  throw error;
@@ -8397,10 +8952,10 @@ async function inspectPreexistingMigrationAdoptions(input) {
8397
8952
  projectBeforeBytes,
8398
8953
  projectAfterBytes
8399
8954
  ] = await Promise.all([
8400
- readFile17(join20(input.targetDirectory, `${drizzleRoot}/${candidate.tag}.sql`)),
8955
+ readFile17(join21(input.targetDirectory, `${drizzleRoot}/${candidate.tag}.sql`)),
8401
8956
  readProjectFile(input, projectSqlPath),
8402
- readJson(join20(input.targetDirectory, snapshotPath(previousTarget.tag))),
8403
- readJson(join20(input.targetDirectory, snapshotPath(candidate.tag))),
8957
+ readJson(join21(input.targetDirectory, snapshotPath(previousTarget.tag))),
8958
+ readJson(join21(input.targetDirectory, snapshotPath(candidate.tag))),
8404
8959
  readProjectFile(input, snapshotPath(previousProject.tag)),
8405
8960
  readProjectFile(input, projectSnapshotPath)
8406
8961
  ]);
@@ -8527,13 +9082,13 @@ async function reconcileDrizzleMigrations(input) {
8527
9082
  const tag = `${prefix}_${name}`;
8528
9083
  const sqlPath = `${drizzleRoot}/${tag}.sql`;
8529
9084
  const snapshotPath2 = `${drizzleRoot}/meta/${prefix}_snapshot.json`;
8530
- const sql = await readFile18(join21(input.targetDirectory, `${drizzleRoot}/${addition.tag}.sql`));
9085
+ const sql = await readFile18(join22(input.targetDirectory, `${drizzleRoot}/${addition.tag}.sql`));
8531
9086
  merged.id = targetAfter.id;
8532
9087
  merged.prevId = currentSnapshot.id;
8533
- const snapshot = encodeJson(merged);
9088
+ const snapshot2 = encodeJson(merged);
8534
9089
  contentOverrides.set(sqlPath, sql);
8535
- contentOverrides.set(snapshotPath2, snapshot);
8536
- files.push(managedEntry(sqlPath, sql), managedEntry(snapshotPath2, snapshot));
9090
+ contentOverrides.set(snapshotPath2, snapshot2);
9091
+ files.push(managedEntry(sqlPath, sql), managedEntry(snapshotPath2, snapshot2));
8537
9092
  previousWhen = Math.max(previousWhen + 1, addition.when);
8538
9093
  mergedJournal.entries.push({
8539
9094
  ...addition,
@@ -8574,9 +9129,9 @@ function unchanged(targetManifest) {
8574
9129
  async function readJournals(input) {
8575
9130
  try {
8576
9131
  const [base, project, target] = await Promise.all([
8577
- readJson(join21(input.baseDirectory, journalPath)),
9132
+ readJson(join22(input.baseDirectory, journalPath)),
8578
9133
  readProjectJson(input, journalPath),
8579
- readJson(join21(input.targetDirectory, journalPath))
9134
+ readJson(join22(input.targetDirectory, journalPath))
8580
9135
  ]);
8581
9136
  return { base, project, target };
8582
9137
  } catch (error) {
@@ -8607,17 +9162,17 @@ async function readLatestSnapshot(input, journal) {
8607
9162
  return JSON.parse(new TextDecoder().decode(content));
8608
9163
  }
8609
9164
  async function readSnapshot(root, tag) {
8610
- return await readJson(join21(root, snapshotPath(tag)));
9165
+ return await readJson(join22(root, snapshotPath(tag)));
8611
9166
  }
8612
9167
 
8613
9168
  // src/update/planner-file.ts
8614
9169
  import { readFile as readFile19 } from "fs/promises";
8615
- import { join as join23 } from "path";
9170
+ import { join as join24 } from "path";
8616
9171
 
8617
9172
  // src/update/merge.ts
8618
9173
  import { mkdtemp as mkdtemp2, rm as rm6, writeFile as writeFile12 } from "fs/promises";
8619
9174
  import { tmpdir as tmpdir2 } from "os";
8620
- import { join as join22 } from "path";
9175
+ import { join as join23 } from "path";
8621
9176
 
8622
9177
  // src/update/merge-convergent-additions.ts
8623
9178
  async function reconcileConvergentAdditions(input) {
@@ -8759,11 +9314,11 @@ function sameLines(left, right) {
8759
9314
 
8760
9315
  // src/update/merge.ts
8761
9316
  async function mergeTextFile(base, ours, theirs) {
8762
- const root = await mkdtemp2(join22(tmpdir2(), "windy-merge-"));
9317
+ const root = await mkdtemp2(join23(tmpdir2(), "windy-merge-"));
8763
9318
  try {
8764
- const oursPath = join22(root, "ours");
8765
- const basePath = join22(root, "base");
8766
- const theirsPath = join22(root, "theirs");
9319
+ const oursPath = join23(root, "ours");
9320
+ const basePath = join23(root, "base");
9321
+ const theirsPath = join23(root, "theirs");
8767
9322
  await Promise.all([
8768
9323
  writeFile12(oursPath, ours),
8769
9324
  writeFile12(basePath, base),
@@ -9214,8 +9769,8 @@ function conflict2(input, message) {
9214
9769
  // src/update/planner-file.ts
9215
9770
  async function planFile(path2, baseRoot, targetRoot, source, target, ours, provenance, targetContentOverride, manageGeneratedProjectOwned = false, forcePlatformBaseline = false, manageRecipeProjectOwned = false) {
9216
9771
  const [base, theirs] = await Promise.all([
9217
- readOptional(join23(baseRoot, path2)),
9218
- targetContentOverride ? Promise.resolve(targetContentOverride) : readOptional(join23(targetRoot, path2))
9772
+ readOptional(join24(baseRoot, path2)),
9773
+ targetContentOverride ? Promise.resolve(targetContentOverride) : readOptional(join24(targetRoot, path2))
9219
9774
  ]);
9220
9775
  const ownership = source?.ownership ?? target?.ownership ?? classifyOwnership(path2);
9221
9776
  const expected = expectationForSnapshot(ours);
@@ -9378,26 +9933,26 @@ function hasExistingSourceForTest(path2, sourcePaths) {
9378
9933
 
9379
9934
  // src/update/planner-snapshots.ts
9380
9935
  import { readFile as readFile20, stat as stat2 } from "fs/promises";
9381
- import { join as join24 } from "path";
9936
+ import { join as join25 } from "path";
9382
9937
  async function snapshotProjectFiles(project, paths, seed) {
9383
9938
  const snapshots = new Map(seed);
9384
9939
  await Promise.all([...paths].filter((path2) => !snapshots.has(path2)).map(async (path2) => {
9385
- snapshots.set(path2, await readOptional2(join24(project, path2)));
9940
+ snapshots.set(path2, await readOptional2(join25(project, path2)));
9386
9941
  }));
9387
9942
  return snapshots;
9388
9943
  }
9389
9944
  async function snapshotProjectModes(project, paths) {
9390
- return new Map(await Promise.all([...paths].map(async (path2) => [path2, await readModeOptional(join24(project, path2))])));
9945
+ return new Map(await Promise.all([...paths].map(async (path2) => [path2, await readModeOptional(join25(project, path2))])));
9391
9946
  }
9392
9947
  async function assertPlanSnapshots(project, expectations) {
9393
9948
  const changed = [];
9394
9949
  for (const expectation2 of expectations) {
9395
- const actual = expectationForSnapshot(await readOptional2(join24(project, expectation2.path)));
9950
+ const actual = expectationForSnapshot(await readOptional2(join25(project, expectation2.path)));
9396
9951
  if (JSON.stringify(actual) !== JSON.stringify(expectation2.expected)) {
9397
9952
  changed.push(expectation2.path);
9398
9953
  continue;
9399
9954
  }
9400
- if ("mode" in expectation2 && await readModeOptional(join24(project, expectation2.path)) !== expectation2.mode) {
9955
+ if ("mode" in expectation2 && await readModeOptional(join25(project, expectation2.path)) !== expectation2.mode) {
9401
9956
  changed.push(expectation2.path);
9402
9957
  }
9403
9958
  }
@@ -9473,7 +10028,7 @@ var oxcManagedPaths = new Set([
9473
10028
  ]);
9474
10029
  async function createUpdatePlan(request, artifacts, dependencies = {}) {
9475
10030
  await assertProjectReadyForUpdate(request.projectDirectory);
9476
- const manifestPath = join25(request.projectDirectory, ".windy/files.json");
10031
+ const manifestPath = join26(request.projectDirectory, ".windy/files.json");
9477
10032
  const expectedManifestHash = hashContent(await readFile21(manifestPath));
9478
10033
  const generationSnapshot = await readGenerationProvenanceSnapshot(request.projectDirectory);
9479
10034
  const provenance = generationSnapshot.provenance;
@@ -9521,8 +10076,8 @@ async function createUpdatePlan(request, artifacts, dependencies = {}) {
9521
10076
  const paths = new Set([...sourceEntries.keys(), ...targetEntries.keys()]);
9522
10077
  for (const path2 of paths) {
9523
10078
  if (!projectSnapshots.has(path2)) {
9524
- projectSnapshots.set(path2, await readOptional2(join25(request.projectDirectory, path2)));
9525
- projectModes.set(path2, await readModeOptional(join25(request.projectDirectory, path2)));
10079
+ projectSnapshots.set(path2, await readOptional2(join26(request.projectDirectory, path2)));
10080
+ projectModes.set(path2, await readModeOptional(join26(request.projectDirectory, path2)));
9526
10081
  }
9527
10082
  }
9528
10083
  const files = await planFiles({
@@ -9546,10 +10101,10 @@ async function createUpdatePlan(request, artifacts, dependencies = {}) {
9546
10101
  for (const file of files) {
9547
10102
  file.expectedProjectMode = projectModes.get(file.path);
9548
10103
  if (file.action === "create" || file.action === "update") {
9549
- file.mode = file.expectedProjectMode ?? await readModeOptional(join25(artifactSet.targetDirectory, file.path));
10104
+ file.mode = file.expectedProjectMode ?? await readModeOptional(join26(artifactSet.targetDirectory, file.path));
9550
10105
  }
9551
10106
  if (file.action === "create") {
9552
- file.parentMode = await readSourceParentMode(join25(artifactSet.targetDirectory, dirname7(file.path)));
10107
+ file.parentMode = await readSourceParentMode(join26(artifactSet.targetDirectory, dirname9(file.path)));
9553
10108
  }
9554
10109
  }
9555
10110
  const plannedPaths = new Set(files.map(({ path: path2 }) => path2));
@@ -9696,7 +10251,7 @@ function frozenManifestHash(file, finalizedHashes) {
9696
10251
  // src/update/format-stabilizer.ts
9697
10252
  import { mkdir as mkdir8, mkdtemp as mkdtemp3, readFile as readFile22, rm as rm7, writeFile as writeFile13 } from "fs/promises";
9698
10253
  import { tmpdir as tmpdir3 } from "os";
9699
- import { dirname as dirname8, extname as extname4, join as join26, resolve as resolve6, sep as sep5 } from "path";
10254
+ import { dirname as dirname10, extname as extname4, join as join27, resolve as resolve6, sep as sep5 } from "path";
9700
10255
  var formattedExtensions = new Set([
9701
10256
  ".cjs",
9702
10257
  ".css",
@@ -9735,7 +10290,7 @@ async function stabilizeManagedContent(result2, execute, writeProjectFile) {
9735
10290
  }
9736
10291
  }
9737
10292
  inputs.set(".windy/generation.json", new TextEncoder().encode(generationContent));
9738
- const temporaryRoot = await mkdtemp3(join26(tmpdir3(), "windy-update-format-"));
10293
+ const temporaryRoot = await mkdtemp3(join27(tmpdir3(), "windy-update-format-"));
9739
10294
  try {
9740
10295
  const stagedPaths = await stageInputs(temporaryRoot, inputs);
9741
10296
  for (let offset = 0;offset < stagedPaths.length; offset += 80) {
@@ -9743,7 +10298,7 @@ async function stabilizeManagedContent(result2, execute, writeProjectFile) {
9743
10298
  "x",
9744
10299
  "oxfmt",
9745
10300
  "--write",
9746
- `--config=${join26(result2.plan.projectDirectory, ".oxfmtrc.json")}`,
10301
+ `--config=${join27(result2.plan.projectDirectory, ".oxfmtrc.json")}`,
9747
10302
  ...stagedPaths.slice(offset, offset + 80)
9748
10303
  ], result2.plan.projectDirectory);
9749
10304
  }
@@ -9776,7 +10331,7 @@ async function stageInputs(temporaryRoot, inputs) {
9776
10331
  const paths = [];
9777
10332
  for (const [path2, content] of inputs) {
9778
10333
  const target = safeTemporaryPath(temporaryRoot, path2);
9779
- await mkdir8(dirname8(target), { recursive: true });
10334
+ await mkdir8(dirname10(target), { recursive: true });
9780
10335
  await writeFile13(target, content);
9781
10336
  paths.push(target);
9782
10337
  }
@@ -9904,7 +10459,7 @@ class DefaultStarterUpdater {
9904
10459
  const plannedPaths = new Set(result2.plan.files.map(({ path: path2 }) => path2));
9905
10460
  replaceExpectations(result2, verificationSnapshot.filter(({ path: path2 }) => !metadataPaths2.has(path2) && !plannedPaths.has(path2)));
9906
10461
  verificationExpectationsFrozen = true;
9907
- const packageJson = JSON.parse(await readFile23(join27(result2.plan.projectDirectory, "package.json"), "utf8"));
10462
+ const packageJson = JSON.parse(await readFile23(join28(result2.plan.projectDirectory, "package.json"), "utf8"));
9908
10463
  for (const name of ["lint", "typecheck", "test", "build"]) {
9909
10464
  if (!packageJson.scripts?.[name]) {
9910
10465
  steps.push({ name: `bun run ${name}`, status: "skipped" });
@@ -10843,11 +11398,11 @@ import {
10843
11398
  rm as rm11,
10844
11399
  writeFile as writeFile14
10845
11400
  } from "fs/promises";
10846
- import { dirname as dirname9, join as join28, relative as relative6 } from "path";
11401
+ import { dirname as dirname11, join as join29, relative as relative7 } from "path";
10847
11402
 
10848
11403
  // src/module-schema/config.ts
10849
11404
  import { readFile as readFile24 } from "fs/promises";
10850
- import { isAbsolute as isAbsolute2, relative as relative5, resolve as resolve9 } from "path";
11405
+ import { isAbsolute as isAbsolute2, relative as relative6, resolve as resolve9 } from "path";
10851
11406
  async function readModuleSchemaLineageConfig(projectDirectory, configPath) {
10852
11407
  const absolutePath = resolveProjectPath(projectDirectory, configPath);
10853
11408
  const parsed = JSON.parse(await readFile24(absolutePath, "utf8"));
@@ -10865,7 +11420,7 @@ function resolveProjectPath(projectDirectory, path2) {
10865
11420
  if (isAbsolute2(path2))
10866
11421
  throw new Error(`\u8DEF\u5F84\u5FC5\u987B\u76F8\u5BF9\u9879\u76EE\u6839\u76EE\u5F55\uFF1A${path2}`);
10867
11422
  const resolved = resolve9(projectDirectory, path2);
10868
- const projectRelative = relative5(projectDirectory, resolved);
11423
+ const projectRelative = relative6(projectDirectory, resolved);
10869
11424
  if (projectRelative.startsWith("..") || isAbsolute2(projectRelative)) {
10870
11425
  throw new Error(`\u8DEF\u5F84\u8D8A\u51FA\u9879\u76EE\u6839\u76EE\u5F55\uFF1A${path2}`);
10871
11426
  }
@@ -10984,17 +11539,17 @@ async function handoffModuleSchemaLineages(options) {
10984
11539
  async function stageModuleLineages(project, temporaryRoot, config, execute) {
10985
11540
  const outputs = [];
10986
11541
  for (const [index, module2] of config.modules.entries()) {
10987
- const output = join28(temporaryRoot, `module-${index}`);
11542
+ const output = join29(temporaryRoot, `module-${index}`);
10988
11543
  await mkdir9(output, { recursive: true });
10989
- const generatedConfig = join28(temporaryRoot, `module-${index}.config.ts`);
10990
- await writeDrizzleConfig(generatedConfig, project, module2.schema, relative6(temporaryRoot, output));
11544
+ const generatedConfig = join29(temporaryRoot, `module-${index}.config.ts`);
11545
+ await writeDrizzleConfig(generatedConfig, project, module2.schema, relative7(temporaryRoot, output));
10991
11546
  await execute(generatedConfig, temporaryRoot);
10992
11547
  const sqlFiles = await listSqlFiles(output);
10993
11548
  if (sqlFiles.length !== 1) {
10994
11549
  throw new Error(`${module2.key} baseline \u5FC5\u987B\u6070\u597D\u751F\u6210\u4E00\u4E2A migration`);
10995
11550
  }
10996
- await writeFile14(join28(output, sqlFiles[0]), metadataOnlySql("module"));
10997
- await writeFile14(join28(output, "lineage.json"), `${JSON.stringify({
11551
+ await writeFile14(join29(output, sqlFiles[0]), metadataOnlySql("module"));
11552
+ await writeFile14(join29(output, "lineage.json"), `${JSON.stringify({
10998
11553
  schemaVersion: 1,
10999
11554
  moduleKey: module2.key,
11000
11555
  schema: module2.schema,
@@ -11008,17 +11563,17 @@ async function stageModuleLineages(project, temporaryRoot, config, execute) {
11008
11563
  }
11009
11564
  async function stagePlatformLineage(project, temporaryRoot, config, execute) {
11010
11565
  const source = resolveProjectPath(project, config.platform.out);
11011
- const output = join28(temporaryRoot, "platform");
11566
+ const output = join29(temporaryRoot, "platform");
11012
11567
  await cp(source, output, { recursive: true });
11013
11568
  const before = new Set(await listSqlFiles(output));
11014
- const generatedConfig = join28(temporaryRoot, "platform.config.ts");
11015
- await writeDrizzleConfig(generatedConfig, project, config.platform.schema, relative6(temporaryRoot, output));
11569
+ const generatedConfig = join29(temporaryRoot, "platform.config.ts");
11570
+ await writeDrizzleConfig(generatedConfig, project, config.platform.schema, relative7(temporaryRoot, output));
11016
11571
  await execute(generatedConfig, temporaryRoot);
11017
11572
  const created = (await listSqlFiles(output)).filter((path2) => !before.has(path2));
11018
11573
  if (created.length !== 1) {
11019
11574
  throw new Error("\u5E73\u53F0 lineage handoff \u5FC5\u987B\u6070\u597D\u751F\u6210\u4E00\u4E2A migration");
11020
11575
  }
11021
- const sqlPath = join28(output, created[0]);
11576
+ const sqlPath = join29(output, created[0]);
11022
11577
  const allowed = config.modules.flatMap(({ legacyPlatformTables }) => legacyPlatformTables);
11023
11578
  validatePlatformHandoffSql(await readFile25(sqlPath, "utf8"), allowed);
11024
11579
  await writeFile14(sqlPath, metadataOnlySql("platform"));
@@ -11026,7 +11581,7 @@ async function stagePlatformLineage(project, temporaryRoot, config, execute) {
11026
11581
  }
11027
11582
  async function installStagedLineages(project, temporaryRoot, config, stagedModules, stagedPlatform) {
11028
11583
  const platform = resolveProjectPath(project, config.platform.out);
11029
- const backup = join28(temporaryRoot, "platform-backup");
11584
+ const backup = join29(temporaryRoot, "platform-backup");
11030
11585
  const installed = [];
11031
11586
  await rename2(platform, backup);
11032
11587
  try {
@@ -11036,7 +11591,7 @@ async function installStagedLineages(project, temporaryRoot, config, stagedModul
11036
11591
  if (await exists(output)) {
11037
11592
  throw new Error(`${module2.key} lineage \u8F93\u51FA\u5DF2\u5B58\u5728\uFF0C\u7981\u6B62\u8986\u76D6`);
11038
11593
  }
11039
- await mkdir9(dirname9(output), { recursive: true });
11594
+ await mkdir9(dirname11(output), { recursive: true });
11040
11595
  await rename2(stagedModules[index], output);
11041
11596
  installed.push(output);
11042
11597
  }
@@ -11073,9 +11628,9 @@ async function validateSchemaSources(project, config) {
11073
11628
  }
11074
11629
  }
11075
11630
  async function createTemporaryRoot(project) {
11076
- const windy = join28(project, ".windy");
11631
+ const windy = join29(project, ".windy");
11077
11632
  await mkdir9(windy, { recursive: true });
11078
- return await mkdtemp4(join28(windy, "module-schema-handoff-"));
11633
+ return await mkdtemp4(join29(windy, "module-schema-handoff-"));
11079
11634
  }
11080
11635
  async function listSqlFiles(root) {
11081
11636
  return (await readdir9(root)).filter((path2) => path2.endsWith(".sql")).sort();