everything-dev 2.0.0-rc.1 → 2.0.0-rc.4

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 (125) hide show
  1. package/dist/auth-login.cjs +1 -1
  2. package/dist/auth-login.mjs +1 -1
  3. package/dist/build.cjs +2 -2
  4. package/dist/build.mjs +2 -2
  5. package/dist/bundle-fs-resolve.cjs +9 -17
  6. package/dist/bundle-fs-resolve.cjs.map +1 -1
  7. package/dist/bundle-fs-resolve.d.cts +6 -0
  8. package/dist/bundle-fs-resolve.d.mts +6 -0
  9. package/dist/bundle-fs-resolve.mjs +9 -17
  10. package/dist/bundle-fs-resolve.mjs.map +1 -1
  11. package/dist/bundle-path.cjs +48 -0
  12. package/dist/bundle-path.cjs.map +1 -0
  13. package/dist/bundle-path.mjs +45 -0
  14. package/dist/bundle-path.mjs.map +1 -0
  15. package/dist/cli/init.cjs +4 -4
  16. package/dist/cli/init.cjs.map +1 -1
  17. package/dist/cli/init.mjs +4 -4
  18. package/dist/cli/init.mjs.map +1 -1
  19. package/dist/cli/status.cjs +69 -3
  20. package/dist/cli/status.cjs.map +1 -1
  21. package/dist/cli/status.mjs +67 -4
  22. package/dist/cli/status.mjs.map +1 -1
  23. package/dist/cli/sync.cjs +1 -1
  24. package/dist/cli/sync.cjs.map +1 -1
  25. package/dist/cli/sync.mjs +1 -1
  26. package/dist/cli/sync.mjs.map +1 -1
  27. package/dist/cli/upgrade.cjs +2 -2
  28. package/dist/cli/upgrade.cjs.map +1 -1
  29. package/dist/cli/upgrade.mjs +2 -2
  30. package/dist/cli/upgrade.mjs.map +1 -1
  31. package/dist/cli.cjs +5 -7
  32. package/dist/cli.cjs.map +1 -1
  33. package/dist/cli.mjs +5 -7
  34. package/dist/cli.mjs.map +1 -1
  35. package/dist/commands/deploy.cjs +26 -16
  36. package/dist/commands/deploy.cjs.map +1 -1
  37. package/dist/commands/deploy.mjs +26 -16
  38. package/dist/commands/deploy.mjs.map +1 -1
  39. package/dist/commands/init.cjs +1 -1
  40. package/dist/commands/init.cjs.map +1 -1
  41. package/dist/commands/init.mjs +1 -1
  42. package/dist/commands/init.mjs.map +1 -1
  43. package/dist/commands/plugins.cjs +2 -2
  44. package/dist/commands/plugins.cjs.map +1 -1
  45. package/dist/commands/plugins.mjs +2 -2
  46. package/dist/commands/plugins.mjs.map +1 -1
  47. package/dist/commands/upgrade.cjs +1 -1
  48. package/dist/commands/upgrade.mjs +1 -1
  49. package/dist/components/dev-render.cjs +1 -1
  50. package/dist/components/dev-render.mjs +1 -1
  51. package/dist/config.cjs +3 -3
  52. package/dist/config.cjs.map +1 -1
  53. package/dist/config.mjs +3 -3
  54. package/dist/config.mjs.map +1 -1
  55. package/dist/contract.cjs +2 -0
  56. package/dist/contract.cjs.map +1 -1
  57. package/dist/contract.d.cts +3 -0
  58. package/dist/contract.d.mts +3 -0
  59. package/dist/contract.meta.cjs +2 -1
  60. package/dist/contract.meta.cjs.map +1 -1
  61. package/dist/contract.meta.d.cts +4 -1
  62. package/dist/contract.meta.d.mts +4 -1
  63. package/dist/contract.meta.mjs +2 -1
  64. package/dist/contract.meta.mjs.map +1 -1
  65. package/dist/contract.mjs +2 -0
  66. package/dist/contract.mjs.map +1 -1
  67. package/dist/db/driver.cjs +22 -2
  68. package/dist/db/driver.cjs.map +1 -1
  69. package/dist/db/driver.d.cts +13 -2
  70. package/dist/db/driver.d.mts +13 -2
  71. package/dist/db/driver.mjs +22 -3
  72. package/dist/db/driver.mjs.map +1 -1
  73. package/dist/db/index.cjs +1 -0
  74. package/dist/db/index.d.cts +2 -2
  75. package/dist/db/index.d.mts +2 -2
  76. package/dist/db/index.mjs +2 -2
  77. package/dist/deploy-diff.cjs +1 -1
  78. package/dist/deploy-diff.cjs.map +1 -1
  79. package/dist/deploy-diff.mjs +1 -1
  80. package/dist/deploy-diff.mjs.map +1 -1
  81. package/dist/dev-program.cjs +10 -2
  82. package/dist/dev-program.cjs.map +1 -1
  83. package/dist/dev-program.mjs +10 -2
  84. package/dist/dev-program.mjs.map +1 -1
  85. package/dist/image-deploy.cjs +65 -17
  86. package/dist/image-deploy.cjs.map +1 -1
  87. package/dist/image-deploy.mjs +64 -18
  88. package/dist/image-deploy.mjs.map +1 -1
  89. package/dist/internal/manifest-normalizer.cjs.map +1 -1
  90. package/dist/internal/manifest-normalizer.mjs.map +1 -1
  91. package/dist/plugin.d.cts +902 -1
  92. package/dist/plugin.d.mts +902 -1
  93. package/dist/publish.cjs +51 -2
  94. package/dist/publish.cjs.map +1 -1
  95. package/dist/publish.mjs +51 -4
  96. package/dist/publish.mjs.map +1 -1
  97. package/dist/resolution/session.cjs.map +1 -1
  98. package/dist/resolution/session.d.cts +5 -5
  99. package/dist/resolution/session.d.mts +5 -5
  100. package/dist/resolution/session.mjs.map +1 -1
  101. package/dist/types.d.cts +31 -1
  102. package/dist/types.d.mts +31 -1
  103. package/dist/ui/auth-guards.d.cts +78 -2
  104. package/dist/ui/auth-guards.d.mts +78 -2
  105. package/dist/ui/auth.cjs.map +1 -1
  106. package/dist/ui/auth.d.cts +4133 -7
  107. package/dist/ui/auth.d.mts +4133 -7
  108. package/dist/ui/auth.mjs.map +1 -1
  109. package/dist/ui/hydrate.cjs +2 -2
  110. package/dist/ui/hydrate.cjs.map +1 -1
  111. package/dist/ui/hydrate.mjs +2 -2
  112. package/dist/ui/hydrate.mjs.map +1 -1
  113. package/dist/utils/theme.cjs +2 -2
  114. package/dist/utils/theme.cjs.map +1 -1
  115. package/dist/utils/theme.mjs +2 -2
  116. package/dist/utils/theme.mjs.map +1 -1
  117. package/dist/version-manifest-resolve.cjs +55 -10
  118. package/dist/version-manifest-resolve.cjs.map +1 -1
  119. package/dist/version-manifest-resolve.mjs +53 -10
  120. package/dist/version-manifest-resolve.mjs.map +1 -1
  121. package/dist/workspace.cjs +26 -13
  122. package/dist/workspace.cjs.map +1 -1
  123. package/dist/workspace.mjs +26 -14
  124. package/dist/workspace.mjs.map +1 -1
  125. package/package.json +11 -10
@@ -1 +1 @@
1
- {"version":3,"file":"status.cjs","names":["fetchJsonOrNull","readInstalledFrameworkVersion","existsSync","join","fetchBosConfigFromFastKv","readAuthoredConfigInput","MISSING_CONFIG_MESSAGE","resolveFrameworkPackage","readSnapshot"],"sources":["../../src/cli/status.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { MISSING_CONFIG_MESSAGE, readAuthoredConfigInput } from \"../config\";\nimport type { StatusResult } from \"../contract\";\nimport { fetchBosConfigFromFastKv } from \"../fastkv\";\nimport { fetchJsonOrNull } from \"../http-client\";\nimport { readInstalledFrameworkVersion, resolveFrameworkPackage } from \"./framework-version\";\nimport { readSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_PACKAGES = [\"everything-dev\", \"every-plugin\"];\n\nconst CATALOG_TOOL_PACKAGES = [\n \"@rspack/core\",\n \"@rspack/cli\",\n \"@rsbuild/core\",\n \"@rsbuild/plugin-react\",\n \"@module-federation/enhanced\",\n \"@module-federation/node\",\n \"@module-federation/rsbuild-plugin\",\n \"@module-federation/runtime-core\",\n \"@module-federation/sdk\",\n \"@module-federation/dts-plugin\",\n] as const;\n\nasync function fetchLatestNpmVersion(packageName: string): Promise<string | null> {\n return fetchJsonOrNull<{ version: string }>(`https://registry.npmjs.org/${packageName}/latest`, {\n headers: { Accept: \"application/json\" },\n retries: 0,\n }).then((data) => data?.version ?? null);\n}\n\nfunction readInstalledVersion(projectDir: string, packageName: string): string | undefined {\n return readInstalledFrameworkVersion(projectDir, packageName);\n}\n\nfunction checkEnvFile(projectDir: string): \"found\" | \"missing\" | \"example-only\" {\n if (existsSync(join(projectDir, \".env\"))) return \"found\";\n if (existsSync(join(projectDir, \".env.example\"))) return \"example-only\";\n return \"missing\";\n}\n\nasync function checkParentReachable(extendsRef: string | undefined): Promise<boolean | undefined> {\n if (!extendsRef?.startsWith(\"bos://\")) return undefined;\n try {\n const config = await fetchBosConfigFromFastKv(extendsRef);\n return config !== null;\n } catch {\n return false;\n }\n}\n\nexport async function getStatus(projectDir: string): Promise<StatusResult> {\n const authored = await readAuthoredConfigInput(projectDir);\n if (!authored) {\n return {\n status: \"error\",\n error: `${MISSING_CONFIG_MESSAGE} in current directory`,\n packages: [],\n envFile: \"missing\",\n };\n }\n\n const config = authored as Record<string, unknown>;\n\n const packageNames = [...FRAMEWORK_PACKAGES];\n for (const name of CATALOG_TOOL_PACKAGES) {\n if (readInstalledVersion(projectDir, name)) {\n packageNames.push(name);\n }\n }\n\n const packages = await Promise.all(\n packageNames.map(async (name) => {\n const resolved = resolveFrameworkPackage(projectDir, name);\n const latest = await fetchLatestNpmVersion(name);\n return {\n name,\n installed: resolved.installedVersion,\n latest: latest ?? undefined,\n isLinked: resolved.isLinked,\n specifier: resolved.specifier,\n };\n }),\n );\n\n const snapshot = await readSnapshot(projectDir);\n\n const extendsRef = config.extends as string | undefined;\n const parentReachable = await checkParentReachable(extendsRef);\n\n return {\n status: \"ok\",\n extends: extendsRef,\n account: config.account as string | undefined,\n domain: config.domain as string | undefined,\n packages,\n lastSync: snapshot?.timestamp,\n envFile: checkEnvFile(projectDir),\n parentReachable,\n };\n}\n"],"mappings":";;;;;;;;;AASA,MAAM,qBAAqB,CAAC,kBAAkB,cAAc;AAE5D,MAAM,wBAAwB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,eAAe,sBAAsB,aAA6C;CAChF,OAAOA,oCAAqC,8BAA8B,YAAY,UAAU;EAC9F,SAAS,EAAE,QAAQ,mBAAmB;EACtC,SAAS;CACX,CAAC,CAAC,CAAC,MAAM,SAAS,MAAM,WAAW,IAAI;AACzC;AAEA,SAAS,qBAAqB,YAAoB,aAAyC;CACzF,OAAOC,wDAA8B,YAAY,WAAW;AAC9D;AAEA,SAAS,aAAa,YAA0D;CAC9E,QAAIC,wBAAWC,gBAAK,YAAY,MAAM,CAAC,GAAG,OAAO;CACjD,QAAID,wBAAWC,gBAAK,YAAY,cAAc,CAAC,GAAG,OAAO;CACzD,OAAO;AACT;AAEA,eAAe,qBAAqB,YAA8D;CAChG,IAAI,CAAC,YAAY,WAAW,QAAQ,GAAG,OAAO;CAC9C,IAAI;EAEF,OAAO,MADcC,wCAAyB,UAAU,MACtC;CACpB,QAAQ;EACN,OAAO;CACT;AACF;AAEA,eAAsB,UAAU,YAA2C;CACzE,MAAM,WAAW,MAAMC,uCAAwB,UAAU;CACzD,IAAI,CAAC,UACH,OAAO;EACL,QAAQ;EACR,OAAO,GAAGC,sCAAuB;EACjC,UAAU,CAAC;EACX,SAAS;CACX;CAGF,MAAM,SAAS;CAEf,MAAM,eAAe,CAAC,GAAG,kBAAkB;CAC3C,KAAK,MAAM,QAAQ,uBACjB,IAAI,qBAAqB,YAAY,IAAI,GACvC,aAAa,KAAK,IAAI;CAI1B,MAAM,WAAW,MAAM,QAAQ,IAC7B,aAAa,IAAI,OAAO,SAAS;EAC/B,MAAM,WAAWC,kDAAwB,YAAY,IAAI;EACzD,MAAM,SAAS,MAAM,sBAAsB,IAAI;EAC/C,OAAO;GACL;GACA,WAAW,SAAS;GACpB,QAAQ,UAAU;GAClB,UAAU,SAAS;GACnB,WAAW,SAAS;EACtB;CACF,CAAC,CACH;CAEA,MAAM,WAAW,MAAMC,8BAAa,UAAU;CAE9C,MAAM,aAAa,OAAO;CAC1B,MAAM,kBAAkB,MAAM,qBAAqB,UAAU;CAE7D,OAAO;EACL,QAAQ;EACR,SAAS;EACT,SAAS,OAAO;EAChB,QAAQ,OAAO;EACf;EACA,UAAU,UAAU;EACpB,SAAS,aAAa,UAAU;EAChC;CACF;AACF"}
1
+ {"version":3,"file":"status.cjs","names":["fetchJsonOrNull","readInstalledFrameworkVersion","existsSync","join","fetchBosConfigFromFastKv","readAuthoredConfigInput","MISSING_CONFIG_MESSAGE","resolveFrameworkPackage","readSnapshot"],"sources":["../../src/cli/status.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { MISSING_CONFIG_MESSAGE, readAuthoredConfigInput } from \"../config\";\nimport type { StatusResult } from \"../contract\";\nimport { fetchBosConfigFromFastKv } from \"../fastkv\";\nimport { fetchJsonOrNull } from \"../http-client\";\nimport { readInstalledFrameworkVersion, resolveFrameworkPackage } from \"./framework-version\";\nimport { readSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_PACKAGES = [\"everything-dev\", \"every-plugin\"];\n\nconst CATALOG_TOOL_PACKAGES = [\n \"@rspack/core\",\n \"@rspack/cli\",\n \"@rsbuild/core\",\n \"@rsbuild/plugin-react\",\n \"@module-federation/enhanced\",\n \"@module-federation/node\",\n \"@module-federation/rsbuild-plugin\",\n \"@module-federation/runtime-core\",\n \"@module-federation/sdk\",\n \"@module-federation/dts-plugin\",\n] as const;\n\nconst PRERELEASE_PATTERN = /-[0-9A-Za-z.-]+$/;\n\n/**\n * The dist-tag to compare an installed version against: prerelease installs\n * track the `rc` dist-tag (the changesets pre-mode train), stable installs\n * track `latest`. Falls back to `latest` when no `rc` tag is published.\n */\nexport function resolveUpdateDistTag(installed: string | undefined): \"rc\" | \"latest\" {\n return installed && PRERELEASE_PATTERN.test(installed) ? \"rc\" : \"latest\";\n}\n\n/** The version a given dist-tag currently points at, or null when absent. */\nexport function pickDistTagVersion(\n distTags: Record<string, string> | undefined,\n tag: \"rc\" | \"latest\",\n): string | null {\n return distTags?.[tag] ?? null;\n}\n\nconst SEMVER_PATTERN =\n /^(?<core>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)(?:-(?<prerelease>[0-9A-Za-z.-]+))?(?:\\+[\\w.-]+)?$/;\n\ninterface ParsedVersion {\n core: readonly number[];\n prerelease: readonly (number | string)[];\n}\n\nfunction parseVersion(version: string | undefined): ParsedVersion | null {\n if (!version) return null;\n const match = SEMVER_PATTERN.exec(version.trim().replace(/^[\\^~>=v]+/, \"\"));\n if (!match?.groups) return null;\n const prerelease = match.groups.prerelease\n ? match.groups.prerelease.split(\".\").map((id) => (/^\\d+$/.test(id) ? Number(id) : id))\n : [];\n return {\n core: [Number(match.groups.core), Number(match.groups.minor), Number(match.groups.patch)],\n prerelease,\n };\n}\n\nfunction comparePrerelease(a: ParsedVersion[\"prerelease\"], b: ParsedVersion[\"prerelease\"]): number {\n if (a.length === 0 && b.length === 0) return 0;\n if (a.length === 0) return 1;\n if (b.length === 0) return -1;\n const length = Math.max(a.length, b.length);\n for (let i = 0; i < length; i += 1) {\n const left = a[i];\n const right = b[i];\n if (left === undefined) return -1;\n if (right === undefined) return 1;\n if (typeof left === \"number\" && typeof right === \"number\") {\n if (left !== right) return left < right ? -1 : 1;\n } else if (typeof left === \"number\") {\n return -1;\n } else if (typeof right === \"number\") {\n return 1;\n } else if (left !== right) {\n return left < right ? -1 : 1;\n }\n }\n return 0;\n}\n\n/**\n * Semver-ordered comparison of two version strings: -1 when `a` is older than\n * `b`, 1 when newer, 0 when equal. Unparseable versions compare as equal —\n * the update check must never fire on versions it cannot order (that is how\n * an install ahead of npm got flagged \"outdated\" with a downgrade arrow).\n */\nexport function compareSemver(a: string | undefined, b: string | undefined): number {\n const left = parseVersion(a);\n const right = parseVersion(b);\n if (!left || !right) return 0;\n for (let i = 0; i < left.core.length; i += 1) {\n if (left.core[i] !== right.core[i]) return left.core[i]! < right.core[i]! ? -1 : 1;\n }\n return comparePrerelease(left.prerelease, right.prerelease);\n}\n\nasync function fetchLatestNpmVersion(\n packageName: string,\n tag: \"rc\" | \"latest\",\n): Promise<string | null> {\n if (tag === \"latest\") {\n return fetchJsonOrNull<{ version: string }>(\n `https://registry.npmjs.org/${packageName}/latest`,\n {\n headers: { Accept: \"application/json\" },\n retries: 0,\n },\n ).then((data) => data?.version ?? null);\n }\n const packument = await fetchJsonOrNull<{ \"dist-tags\"?: Record<string, string> }>(\n `https://registry.npmjs.org/${packageName}`,\n {\n headers: { Accept: \"application/vnd.npm.install-v1+json\" },\n retries: 0,\n },\n );\n return pickDistTagVersion(packument?.[\"dist-tags\"], tag);\n}\n\nfunction readInstalledVersion(projectDir: string, packageName: string): string | undefined {\n return readInstalledFrameworkVersion(projectDir, packageName);\n}\n\nfunction checkEnvFile(projectDir: string): \"found\" | \"missing\" | \"example-only\" {\n if (existsSync(join(projectDir, \".env\"))) return \"found\";\n if (existsSync(join(projectDir, \".env.example\"))) return \"example-only\";\n return \"missing\";\n}\n\nasync function checkParentReachable(extendsRef: string | undefined): Promise<boolean | undefined> {\n if (!extendsRef?.startsWith(\"bos://\")) return undefined;\n try {\n const config = await fetchBosConfigFromFastKv(extendsRef);\n return config !== null;\n } catch {\n return false;\n }\n}\n\nexport async function getStatus(projectDir: string): Promise<StatusResult> {\n const authored = await readAuthoredConfigInput(projectDir);\n if (!authored) {\n return {\n status: \"error\",\n error: `${MISSING_CONFIG_MESSAGE} in current directory`,\n packages: [],\n envFile: \"missing\",\n };\n }\n\n const config = authored as Record<string, unknown>;\n\n const packageNames = [...FRAMEWORK_PACKAGES];\n for (const name of CATALOG_TOOL_PACKAGES) {\n if (readInstalledVersion(projectDir, name)) {\n packageNames.push(name);\n }\n }\n\n const packages = await Promise.all(\n packageNames.map(async (name) => {\n const resolved = resolveFrameworkPackage(projectDir, name);\n const tag = FRAMEWORK_PACKAGES.includes(name)\n ? resolveUpdateDistTag(resolved.installedVersion)\n : \"latest\";\n const latest = await fetchLatestNpmVersion(name, tag);\n return {\n name,\n installed: resolved.installedVersion,\n latest: latest ?? undefined,\n isLinked: resolved.isLinked,\n specifier: resolved.specifier,\n };\n }),\n );\n\n const snapshot = await readSnapshot(projectDir);\n\n const extendsRef = config.extends as string | undefined;\n const parentReachable = await checkParentReachable(extendsRef);\n\n return {\n status: \"ok\",\n extends: extendsRef,\n account: config.account as string | undefined,\n domain: config.domain as string | undefined,\n packages,\n lastSync: snapshot?.timestamp,\n envFile: checkEnvFile(projectDir),\n parentReachable,\n };\n}\n"],"mappings":"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"}
@@ -20,11 +20,74 @@ const CATALOG_TOOL_PACKAGES = [
20
20
  "@module-federation/sdk",
21
21
  "@module-federation/dts-plugin"
22
22
  ];
23
- async function fetchLatestNpmVersion(packageName) {
24
- return fetchJsonOrNull(`https://registry.npmjs.org/${packageName}/latest`, {
23
+ const PRERELEASE_PATTERN = /-[0-9A-Za-z.-]+$/;
24
+ /**
25
+ * The dist-tag to compare an installed version against: prerelease installs
26
+ * track the `rc` dist-tag (the changesets pre-mode train), stable installs
27
+ * track `latest`. Falls back to `latest` when no `rc` tag is published.
28
+ */
29
+ function resolveUpdateDistTag(installed) {
30
+ return installed && PRERELEASE_PATTERN.test(installed) ? "rc" : "latest";
31
+ }
32
+ /** The version a given dist-tag currently points at, or null when absent. */
33
+ function pickDistTagVersion(distTags, tag) {
34
+ return distTags?.[tag] ?? null;
35
+ }
36
+ const SEMVER_PATTERN = /^(?<core>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(?:-(?<prerelease>[0-9A-Za-z.-]+))?(?:\+[\w.-]+)?$/;
37
+ function parseVersion(version) {
38
+ if (!version) return null;
39
+ const match = SEMVER_PATTERN.exec(version.trim().replace(/^[\^~>=v]+/, ""));
40
+ if (!match?.groups) return null;
41
+ const prerelease = match.groups.prerelease ? match.groups.prerelease.split(".").map((id) => /^\d+$/.test(id) ? Number(id) : id) : [];
42
+ return {
43
+ core: [
44
+ Number(match.groups.core),
45
+ Number(match.groups.minor),
46
+ Number(match.groups.patch)
47
+ ],
48
+ prerelease
49
+ };
50
+ }
51
+ function comparePrerelease(a, b) {
52
+ if (a.length === 0 && b.length === 0) return 0;
53
+ if (a.length === 0) return 1;
54
+ if (b.length === 0) return -1;
55
+ const length = Math.max(a.length, b.length);
56
+ for (let i = 0; i < length; i += 1) {
57
+ const left = a[i];
58
+ const right = b[i];
59
+ if (left === void 0) return -1;
60
+ if (right === void 0) return 1;
61
+ if (typeof left === "number" && typeof right === "number") {
62
+ if (left !== right) return left < right ? -1 : 1;
63
+ } else if (typeof left === "number") return -1;
64
+ else if (typeof right === "number") return 1;
65
+ else if (left !== right) return left < right ? -1 : 1;
66
+ }
67
+ return 0;
68
+ }
69
+ /**
70
+ * Semver-ordered comparison of two version strings: -1 when `a` is older than
71
+ * `b`, 1 when newer, 0 when equal. Unparseable versions compare as equal —
72
+ * the update check must never fire on versions it cannot order (that is how
73
+ * an install ahead of npm got flagged "outdated" with a downgrade arrow).
74
+ */
75
+ function compareSemver(a, b) {
76
+ const left = parseVersion(a);
77
+ const right = parseVersion(b);
78
+ if (!left || !right) return 0;
79
+ for (let i = 0; i < left.core.length; i += 1) if (left.core[i] !== right.core[i]) return left.core[i] < right.core[i] ? -1 : 1;
80
+ return comparePrerelease(left.prerelease, right.prerelease);
81
+ }
82
+ async function fetchLatestNpmVersion(packageName, tag) {
83
+ if (tag === "latest") return fetchJsonOrNull(`https://registry.npmjs.org/${packageName}/latest`, {
25
84
  headers: { Accept: "application/json" },
26
85
  retries: 0
27
86
  }).then((data) => data?.version ?? null);
87
+ return pickDistTagVersion((await fetchJsonOrNull(`https://registry.npmjs.org/${packageName}`, {
88
+ headers: { Accept: "application/vnd.npm.install-v1+json" },
89
+ retries: 0
90
+ }))?.["dist-tags"], tag);
28
91
  }
29
92
  function readInstalledVersion(projectDir, packageName) {
30
93
  return readInstalledFrameworkVersion(projectDir, packageName);
@@ -55,7 +118,7 @@ async function getStatus(projectDir) {
55
118
  for (const name of CATALOG_TOOL_PACKAGES) if (readInstalledVersion(projectDir, name)) packageNames.push(name);
56
119
  const packages = await Promise.all(packageNames.map(async (name) => {
57
120
  const resolved = resolveFrameworkPackage(projectDir, name);
58
- const latest = await fetchLatestNpmVersion(name);
121
+ const latest = await fetchLatestNpmVersion(name, FRAMEWORK_PACKAGES.includes(name) ? resolveUpdateDistTag(resolved.installedVersion) : "latest");
59
122
  return {
60
123
  name,
61
124
  installed: resolved.installedVersion,
@@ -80,5 +143,5 @@ async function getStatus(projectDir) {
80
143
  }
81
144
 
82
145
  //#endregion
83
- export { getStatus };
146
+ export { compareSemver, getStatus, pickDistTagVersion, resolveUpdateDistTag };
84
147
  //# sourceMappingURL=status.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"status.mjs","names":[],"sources":["../../src/cli/status.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { MISSING_CONFIG_MESSAGE, readAuthoredConfigInput } from \"../config\";\nimport type { StatusResult } from \"../contract\";\nimport { fetchBosConfigFromFastKv } from \"../fastkv\";\nimport { fetchJsonOrNull } from \"../http-client\";\nimport { readInstalledFrameworkVersion, resolveFrameworkPackage } from \"./framework-version\";\nimport { readSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_PACKAGES = [\"everything-dev\", \"every-plugin\"];\n\nconst CATALOG_TOOL_PACKAGES = [\n \"@rspack/core\",\n \"@rspack/cli\",\n \"@rsbuild/core\",\n \"@rsbuild/plugin-react\",\n \"@module-federation/enhanced\",\n \"@module-federation/node\",\n \"@module-federation/rsbuild-plugin\",\n \"@module-federation/runtime-core\",\n \"@module-federation/sdk\",\n \"@module-federation/dts-plugin\",\n] as const;\n\nasync function fetchLatestNpmVersion(packageName: string): Promise<string | null> {\n return fetchJsonOrNull<{ version: string }>(`https://registry.npmjs.org/${packageName}/latest`, {\n headers: { Accept: \"application/json\" },\n retries: 0,\n }).then((data) => data?.version ?? null);\n}\n\nfunction readInstalledVersion(projectDir: string, packageName: string): string | undefined {\n return readInstalledFrameworkVersion(projectDir, packageName);\n}\n\nfunction checkEnvFile(projectDir: string): \"found\" | \"missing\" | \"example-only\" {\n if (existsSync(join(projectDir, \".env\"))) return \"found\";\n if (existsSync(join(projectDir, \".env.example\"))) return \"example-only\";\n return \"missing\";\n}\n\nasync function checkParentReachable(extendsRef: string | undefined): Promise<boolean | undefined> {\n if (!extendsRef?.startsWith(\"bos://\")) return undefined;\n try {\n const config = await fetchBosConfigFromFastKv(extendsRef);\n return config !== null;\n } catch {\n return false;\n }\n}\n\nexport async function getStatus(projectDir: string): Promise<StatusResult> {\n const authored = await readAuthoredConfigInput(projectDir);\n if (!authored) {\n return {\n status: \"error\",\n error: `${MISSING_CONFIG_MESSAGE} in current directory`,\n packages: [],\n envFile: \"missing\",\n };\n }\n\n const config = authored as Record<string, unknown>;\n\n const packageNames = [...FRAMEWORK_PACKAGES];\n for (const name of CATALOG_TOOL_PACKAGES) {\n if (readInstalledVersion(projectDir, name)) {\n packageNames.push(name);\n }\n }\n\n const packages = await Promise.all(\n packageNames.map(async (name) => {\n const resolved = resolveFrameworkPackage(projectDir, name);\n const latest = await fetchLatestNpmVersion(name);\n return {\n name,\n installed: resolved.installedVersion,\n latest: latest ?? undefined,\n isLinked: resolved.isLinked,\n specifier: resolved.specifier,\n };\n }),\n );\n\n const snapshot = await readSnapshot(projectDir);\n\n const extendsRef = config.extends as string | undefined;\n const parentReachable = await checkParentReachable(extendsRef);\n\n return {\n status: \"ok\",\n extends: extendsRef,\n account: config.account as string | undefined,\n domain: config.domain as string | undefined,\n packages,\n lastSync: snapshot?.timestamp,\n envFile: checkEnvFile(projectDir),\n parentReachable,\n };\n}\n"],"mappings":";;;;;;;;;AASA,MAAM,qBAAqB,CAAC,kBAAkB,cAAc;AAE5D,MAAM,wBAAwB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,eAAe,sBAAsB,aAA6C;CAChF,OAAO,gBAAqC,8BAA8B,YAAY,UAAU;EAC9F,SAAS,EAAE,QAAQ,mBAAmB;EACtC,SAAS;CACX,CAAC,CAAC,CAAC,MAAM,SAAS,MAAM,WAAW,IAAI;AACzC;AAEA,SAAS,qBAAqB,YAAoB,aAAyC;CACzF,OAAO,8BAA8B,YAAY,WAAW;AAC9D;AAEA,SAAS,aAAa,YAA0D;CAC9E,IAAI,WAAW,KAAK,YAAY,MAAM,CAAC,GAAG,OAAO;CACjD,IAAI,WAAW,KAAK,YAAY,cAAc,CAAC,GAAG,OAAO;CACzD,OAAO;AACT;AAEA,eAAe,qBAAqB,YAA8D;CAChG,IAAI,CAAC,YAAY,WAAW,QAAQ,GAAG,OAAO;CAC9C,IAAI;EAEF,OAAO,MADc,yBAAyB,UAAU,MACtC;CACpB,QAAQ;EACN,OAAO;CACT;AACF;AAEA,eAAsB,UAAU,YAA2C;CACzE,MAAM,WAAW,MAAM,wBAAwB,UAAU;CACzD,IAAI,CAAC,UACH,OAAO;EACL,QAAQ;EACR,OAAO,GAAG,uBAAuB;EACjC,UAAU,CAAC;EACX,SAAS;CACX;CAGF,MAAM,SAAS;CAEf,MAAM,eAAe,CAAC,GAAG,kBAAkB;CAC3C,KAAK,MAAM,QAAQ,uBACjB,IAAI,qBAAqB,YAAY,IAAI,GACvC,aAAa,KAAK,IAAI;CAI1B,MAAM,WAAW,MAAM,QAAQ,IAC7B,aAAa,IAAI,OAAO,SAAS;EAC/B,MAAM,WAAW,wBAAwB,YAAY,IAAI;EACzD,MAAM,SAAS,MAAM,sBAAsB,IAAI;EAC/C,OAAO;GACL;GACA,WAAW,SAAS;GACpB,QAAQ,UAAU;GAClB,UAAU,SAAS;GACnB,WAAW,SAAS;EACtB;CACF,CAAC,CACH;CAEA,MAAM,WAAW,MAAM,aAAa,UAAU;CAE9C,MAAM,aAAa,OAAO;CAC1B,MAAM,kBAAkB,MAAM,qBAAqB,UAAU;CAE7D,OAAO;EACL,QAAQ;EACR,SAAS;EACT,SAAS,OAAO;EAChB,QAAQ,OAAO;EACf;EACA,UAAU,UAAU;EACpB,SAAS,aAAa,UAAU;EAChC;CACF;AACF"}
1
+ {"version":3,"file":"status.mjs","names":[],"sources":["../../src/cli/status.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { MISSING_CONFIG_MESSAGE, readAuthoredConfigInput } from \"../config\";\nimport type { StatusResult } from \"../contract\";\nimport { fetchBosConfigFromFastKv } from \"../fastkv\";\nimport { fetchJsonOrNull } from \"../http-client\";\nimport { readInstalledFrameworkVersion, resolveFrameworkPackage } from \"./framework-version\";\nimport { readSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_PACKAGES = [\"everything-dev\", \"every-plugin\"];\n\nconst CATALOG_TOOL_PACKAGES = [\n \"@rspack/core\",\n \"@rspack/cli\",\n \"@rsbuild/core\",\n \"@rsbuild/plugin-react\",\n \"@module-federation/enhanced\",\n \"@module-federation/node\",\n \"@module-federation/rsbuild-plugin\",\n \"@module-federation/runtime-core\",\n \"@module-federation/sdk\",\n \"@module-federation/dts-plugin\",\n] as const;\n\nconst PRERELEASE_PATTERN = /-[0-9A-Za-z.-]+$/;\n\n/**\n * The dist-tag to compare an installed version against: prerelease installs\n * track the `rc` dist-tag (the changesets pre-mode train), stable installs\n * track `latest`. Falls back to `latest` when no `rc` tag is published.\n */\nexport function resolveUpdateDistTag(installed: string | undefined): \"rc\" | \"latest\" {\n return installed && PRERELEASE_PATTERN.test(installed) ? \"rc\" : \"latest\";\n}\n\n/** The version a given dist-tag currently points at, or null when absent. */\nexport function pickDistTagVersion(\n distTags: Record<string, string> | undefined,\n tag: \"rc\" | \"latest\",\n): string | null {\n return distTags?.[tag] ?? null;\n}\n\nconst SEMVER_PATTERN =\n /^(?<core>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)(?:-(?<prerelease>[0-9A-Za-z.-]+))?(?:\\+[\\w.-]+)?$/;\n\ninterface ParsedVersion {\n core: readonly number[];\n prerelease: readonly (number | string)[];\n}\n\nfunction parseVersion(version: string | undefined): ParsedVersion | null {\n if (!version) return null;\n const match = SEMVER_PATTERN.exec(version.trim().replace(/^[\\^~>=v]+/, \"\"));\n if (!match?.groups) return null;\n const prerelease = match.groups.prerelease\n ? match.groups.prerelease.split(\".\").map((id) => (/^\\d+$/.test(id) ? Number(id) : id))\n : [];\n return {\n core: [Number(match.groups.core), Number(match.groups.minor), Number(match.groups.patch)],\n prerelease,\n };\n}\n\nfunction comparePrerelease(a: ParsedVersion[\"prerelease\"], b: ParsedVersion[\"prerelease\"]): number {\n if (a.length === 0 && b.length === 0) return 0;\n if (a.length === 0) return 1;\n if (b.length === 0) return -1;\n const length = Math.max(a.length, b.length);\n for (let i = 0; i < length; i += 1) {\n const left = a[i];\n const right = b[i];\n if (left === undefined) return -1;\n if (right === undefined) return 1;\n if (typeof left === \"number\" && typeof right === \"number\") {\n if (left !== right) return left < right ? -1 : 1;\n } else if (typeof left === \"number\") {\n return -1;\n } else if (typeof right === \"number\") {\n return 1;\n } else if (left !== right) {\n return left < right ? -1 : 1;\n }\n }\n return 0;\n}\n\n/**\n * Semver-ordered comparison of two version strings: -1 when `a` is older than\n * `b`, 1 when newer, 0 when equal. Unparseable versions compare as equal —\n * the update check must never fire on versions it cannot order (that is how\n * an install ahead of npm got flagged \"outdated\" with a downgrade arrow).\n */\nexport function compareSemver(a: string | undefined, b: string | undefined): number {\n const left = parseVersion(a);\n const right = parseVersion(b);\n if (!left || !right) return 0;\n for (let i = 0; i < left.core.length; i += 1) {\n if (left.core[i] !== right.core[i]) return left.core[i]! < right.core[i]! ? -1 : 1;\n }\n return comparePrerelease(left.prerelease, right.prerelease);\n}\n\nasync function fetchLatestNpmVersion(\n packageName: string,\n tag: \"rc\" | \"latest\",\n): Promise<string | null> {\n if (tag === \"latest\") {\n return fetchJsonOrNull<{ version: string }>(\n `https://registry.npmjs.org/${packageName}/latest`,\n {\n headers: { Accept: \"application/json\" },\n retries: 0,\n },\n ).then((data) => data?.version ?? null);\n }\n const packument = await fetchJsonOrNull<{ \"dist-tags\"?: Record<string, string> }>(\n `https://registry.npmjs.org/${packageName}`,\n {\n headers: { Accept: \"application/vnd.npm.install-v1+json\" },\n retries: 0,\n },\n );\n return pickDistTagVersion(packument?.[\"dist-tags\"], tag);\n}\n\nfunction readInstalledVersion(projectDir: string, packageName: string): string | undefined {\n return readInstalledFrameworkVersion(projectDir, packageName);\n}\n\nfunction checkEnvFile(projectDir: string): \"found\" | \"missing\" | \"example-only\" {\n if (existsSync(join(projectDir, \".env\"))) return \"found\";\n if (existsSync(join(projectDir, \".env.example\"))) return \"example-only\";\n return \"missing\";\n}\n\nasync function checkParentReachable(extendsRef: string | undefined): Promise<boolean | undefined> {\n if (!extendsRef?.startsWith(\"bos://\")) return undefined;\n try {\n const config = await fetchBosConfigFromFastKv(extendsRef);\n return config !== null;\n } catch {\n return false;\n }\n}\n\nexport async function getStatus(projectDir: string): Promise<StatusResult> {\n const authored = await readAuthoredConfigInput(projectDir);\n if (!authored) {\n return {\n status: \"error\",\n error: `${MISSING_CONFIG_MESSAGE} in current directory`,\n packages: [],\n envFile: \"missing\",\n };\n }\n\n const config = authored as Record<string, unknown>;\n\n const packageNames = [...FRAMEWORK_PACKAGES];\n for (const name of CATALOG_TOOL_PACKAGES) {\n if (readInstalledVersion(projectDir, name)) {\n packageNames.push(name);\n }\n }\n\n const packages = await Promise.all(\n packageNames.map(async (name) => {\n const resolved = resolveFrameworkPackage(projectDir, name);\n const tag = FRAMEWORK_PACKAGES.includes(name)\n ? resolveUpdateDistTag(resolved.installedVersion)\n : \"latest\";\n const latest = await fetchLatestNpmVersion(name, tag);\n return {\n name,\n installed: resolved.installedVersion,\n latest: latest ?? undefined,\n isLinked: resolved.isLinked,\n specifier: resolved.specifier,\n };\n }),\n );\n\n const snapshot = await readSnapshot(projectDir);\n\n const extendsRef = config.extends as string | undefined;\n const parentReachable = await checkParentReachable(extendsRef);\n\n return {\n status: \"ok\",\n extends: extendsRef,\n account: config.account as string | undefined,\n domain: config.domain as string | undefined,\n packages,\n lastSync: snapshot?.timestamp,\n envFile: checkEnvFile(projectDir),\n parentReachable,\n };\n}\n"],"mappings":"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"}
package/dist/cli/sync.cjs CHANGED
@@ -274,7 +274,7 @@ function hasPluginsWorkspace(projectDir) {
274
274
  try {
275
275
  const content = (0, node_fs.readFileSync)(manifestPath, "utf-8");
276
276
  const packages = manifest === "pnpm-workspace.yaml" ? (0, yaml.parse)(content)?.packages : JSON.parse(content).workspaces;
277
- if ((Array.isArray(packages) ? packages : Array.isArray(packages?.packages) ? packages.packages : []).includes("plugins/*")) return true;
277
+ if ((Array.isArray(packages) ? packages : Array.isArray(packages?.packages) ? packages.packages ?? [] : []).includes("plugins/*")) return true;
278
278
  } catch {
279
279
  return false;
280
280
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sync.cjs","names":["join","existsSync","readFileSync","computeHash","dirname","mergeBosConfigWithTemplate","findWorkspaceRoot","relative","parseYaml","loadAppDescriptorConfig","isPlainObjectFromMerge","resolveExtendsRef","resolveSourceDir","buildChildRootScripts","readSnapshot","extractSkillsBlock","buildChildAgentsMd","personalizeConfig","syncResolvedSharedDeps","openResolution","materializeViaLayer","writeSnapshot","runPnpmInstall","runTypesGen"],"sources":["../../src/cli/sync.ts"],"sourcesContent":["import { copyFileSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative } from \"node:path\";\nimport { glob } from \"glob\";\nimport { parse as parseYaml } from \"yaml\";\nimport { loadAppDescriptorConfig } from \"../config\";\nimport type { SyncOptions, SyncResult } from \"../contract\";\nimport { materializeViaLayer } from \"../infra/materializer\";\nimport {\n isPlainObject as isPlainObjectFromMerge,\n mergeBosConfigWithTemplate,\n resolveExtendsRef,\n} from \"../merge\";\nimport { openResolution } from \"../resolution/session\";\nimport { syncResolvedSharedDeps } from \"../shared-deps\";\nimport { computeSnapshotHash as computeHash } from \"../utils/snapshot-hash\";\nimport { findWorkspaceRoot } from \"../workspace\";\nimport {\n buildChildAgentsMd,\n buildChildRootScripts,\n extractSkillsBlock,\n personalizeConfig,\n resolveSourceDir,\n runPnpmInstall,\n runTypesGen,\n} from \"./init\";\nimport { readSnapshot, writeSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_OWNED_SYNC_FILES = new Set([\n \".env.example\",\n \".gitignore\",\n \"biome.json\",\n \"bos.config.json\",\n \"package.json\",\n \".changeset/config.json\",\n \".changeset/README.md\",\n \".github/workflows/ci.yml\",\n \".github/workflows/deploy.yml\",\n \".github/workflows/staging.yml\",\n \".github/workflows/release.yml\",\n \"railway.toml\",\n \"ui/package.json\",\n \"ui/postcss.config.mjs\",\n \"ui/tsconfig.json\",\n \"api/package.json\",\n \"api/plugin.dev.ts\",\n \"api/rspack.config.js\",\n \"api/tsconfig.json\",\n \"api/src/lib/context.ts\",\n \"api/drizzle.config.ts\",\n \"api/src/db/index.ts\",\n \"api/src/db/layer.ts\",\n \"api/src/db/migrate.ts\",\n \"api/src/global.d.ts\",\n \"api/tests/types.d.ts\",\n]);\n\n/**\n * Files the scaffold previously sync-owned but has retired (ADR 0023) — the\n * generated `.gen` bootstrap stubs replaced them. During sync: a local copy\n * whose hash still matches the sync snapshot is deleted silently; a\n * hand-modified (or never-snapshotted) copy is backed up, then deleted. The\n * app's authored ui files (router.tsx, app.ts, lib, routes, components) are\n * NOT retired — they leave the sync list as app-owned files, untouched.\n */\nexport const RETIRED_SYNC_FILES = new Set([\n \"ui/src/entry.ts\",\n \"ui/src/globals.d.ts\",\n \"ui/src/hydrate.tsx\",\n \"ui/src/router.server.tsx\",\n \"ui/src/compose.ts\",\n]);\n\ntype PackageJson = Record<string, unknown>;\n\nconst AGENT_SYNC_GLOBS = [\".agents/skills/**\", \"docs/agents/**\", \"skills-lock.json\"];\n\nexport function isFrameworkOwnedSyncFile(filePath: string): boolean {\n if (FRAMEWORK_OWNED_SYNC_FILES.has(filePath)) return true;\n if (\n filePath.startsWith(\".agents/skills/\") ||\n filePath.startsWith(\"docs/agents/\") ||\n filePath === \"skills-lock.json\"\n )\n return true;\n // lib/auth.ts is NOT sync-owned since #207: the middleware factory lives in\n // everything-dev/api (framework home); projects import it, they don't own a copy.\n if (/^plugins\\/[^/]+\\/src\\/lib\\/context\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/src\\/db\\/(index|layer|migrate)\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/rspack\\.config\\.js$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/drizzle\\.config\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/src\\/global\\.d\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/tests\\/types\\.d\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/tsconfig\\.json$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/tsconfig\\.contract\\.json$/.test(filePath)) return true;\n return false;\n}\n\nfunction computeLocalHash(projectDir: string, filePath: string): string | null {\n const fullPath = join(projectDir, filePath);\n if (!existsSync(fullPath)) return null;\n try {\n const content = readFileSync(fullPath);\n return computeHash(content);\n } catch {\n return null;\n }\n}\n\nfunction backupFiles(projectDir: string, filePaths: string[]): string | null {\n const filesToBackup = filePaths.filter((f) => existsSync(join(projectDir, f)));\n if (filesToBackup.length === 0) return null;\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupDir = join(projectDir, \".bos\", \"sync-backup\", timestamp);\n\n for (const filePath of filesToBackup) {\n const src = join(projectDir, filePath);\n const dest = join(backupDir, filePath);\n mkdirSync(dirname(dest), { recursive: true });\n copyFileSync(src, dest);\n }\n\n return backupDir;\n}\n\nexport interface RetiredSyncFilesResult {\n /** unmodified stub copies — deleted (in a real run) */\n retired: string[];\n /** hand-modified or never-snapshotted stub copies — backed up, then deleted */\n retiredConflicted: string[];\n backupDir: string | null;\n}\n\n/**\n * Migrate a child off the retired bootstrap stub files (ADR 0023): unmodified\n * copies are deleted silently, hand-modified copies are backed up first. In\n * dry-run the actions are reported without touching the tree.\n */\nexport function retireSyncedFiles(\n projectDir: string,\n snapshotFiles: Record<string, string>,\n opts: { dryRun: boolean },\n): RetiredSyncFilesResult {\n const retired: string[] = [];\n const retiredConflicted: string[] = [];\n\n for (const destPath of RETIRED_SYNC_FILES) {\n const localHash = computeLocalHash(projectDir, destPath);\n if (localHash === null) continue;\n if (localHash === snapshotFiles[destPath]) {\n retired.push(destPath);\n } else {\n retiredConflicted.push(destPath);\n }\n }\n\n if (opts.dryRun || (retired.length === 0 && retiredConflicted.length === 0)) {\n return { retired, retiredConflicted, backupDir: null };\n }\n\n const backupDir = backupFiles(projectDir, retiredConflicted);\n for (const destPath of [...retired, ...retiredConflicted]) {\n rmSync(join(projectDir, destPath));\n }\n return { retired, retiredConflicted, backupDir };\n}\n\nfunction mergeStringMaps(\n local: Record<string, string> | undefined,\n template: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n if (!local && !template) return undefined;\n\n const merged: Record<string, string> = { ...local };\n for (const [name, value] of Object.entries(template ?? {})) {\n merged[name] = value;\n }\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeWorkspacePackages(local: unknown, template: unknown): string[] | undefined {\n const localPackages = Array.isArray(local) ? local : [];\n const templatePackages = Array.isArray(template) ? template : [];\n if (localPackages.length === 0 && templatePackages.length === 0) return undefined;\n\n const ordered = new Set<string>();\n for (const entry of templatePackages) {\n if (typeof entry === \"string\" && entry.length > 0) ordered.add(entry);\n }\n for (const entry of localPackages) {\n if (typeof entry === \"string\" && entry.length > 0) ordered.add(entry);\n }\n\n const hasPluginEntry = [...ordered].some((e) => e.startsWith(\"plugins/\") && e !== \"plugins/*\");\n if (hasPluginEntry) {\n for (const entry of ordered) {\n if (entry.startsWith(\"plugins/\") && entry !== \"plugins/*\") {\n ordered.delete(entry);\n }\n }\n ordered.add(\"plugins/*\");\n }\n\n return ordered.size > 0 ? [...ordered] : undefined;\n}\n\nexport function mergePackageJson(\n filePath: string,\n local: PackageJson,\n template: PackageJson,\n childScripts?: Record<string, string>,\n): PackageJson {\n const merged: PackageJson = { ...local, ...template };\n\n if (filePath === \"package.json\") {\n for (const key of [\"name\", \"private\", \"version\"] as const) {\n if (key in local) {\n merged[key] = local[key];\n }\n }\n } else if (\"version\" in local) {\n merged.version = local.version;\n }\n\n for (const depField of [\n \"dependencies\",\n \"devDependencies\",\n \"peerDependencies\",\n \"overrides\",\n ] as const) {\n const localDeps = local[depField] as Record<string, string> | undefined;\n const templateDeps = template[depField] as Record<string, string> | undefined;\n\n const mergedDeps = mergeStringMaps(localDeps, templateDeps);\n if (mergedDeps) {\n merged[depField] = mergedDeps;\n } else {\n delete merged[depField];\n }\n }\n\n if (\n (local.scripts && typeof local.scripts === \"object\") ||\n (template.scripts && typeof template.scripts === \"object\") ||\n childScripts\n ) {\n const mergedScripts = mergeStringMaps(\n local.scripts as Record<string, string> | undefined,\n filePath === \"package.json\" && childScripts\n ? childScripts\n : (template.scripts as Record<string, string> | undefined),\n );\n if (mergedScripts) {\n merged.scripts = mergedScripts;\n } else {\n delete merged.scripts;\n }\n }\n\n if (\n (local.workspaces && typeof local.workspaces === \"object\") ||\n (template.workspaces && typeof template.workspaces === \"object\")\n ) {\n const localWorkspaces = (local.workspaces ?? {}) as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n const templateWorkspaces = (template.workspaces ?? {}) as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n\n const mergedWorkspaces: { packages?: string[]; catalog?: Record<string, string> } = {\n ...localWorkspaces,\n ...templateWorkspaces,\n };\n\n const mergedPackages = mergeWorkspacePackages(\n localWorkspaces.packages,\n templateWorkspaces.packages,\n );\n if (mergedPackages) {\n mergedWorkspaces.packages = mergedPackages;\n } else {\n delete mergedWorkspaces.packages;\n }\n\n const mergedCatalog = mergeStringMaps(localWorkspaces.catalog, templateWorkspaces.catalog);\n if (mergedCatalog) {\n mergedWorkspaces.catalog = mergedCatalog;\n } else {\n delete mergedWorkspaces.catalog;\n }\n\n if (Object.keys(mergedWorkspaces).length > 0) {\n merged.workspaces = mergedWorkspaces;\n } else {\n delete merged.workspaces;\n }\n }\n\n return merged;\n}\n\nfunction toSourcePath(sourceDir: string, destPath: string): string | null {\n if (destPath.startsWith(\".github/\")) {\n const templatePath = destPath.replace(/^\\.github\\//, \".github/templates/\");\n if (existsSync(join(sourceDir, templatePath))) {\n return templatePath;\n }\n }\n\n const directPath = join(sourceDir, destPath);\n if (existsSync(directPath)) {\n return destPath;\n }\n\n return null;\n}\n\nfunction buildSyncedFileContent(\n sourceDir: string,\n projectDir: string,\n filePath: string,\n explicitDestPath?: string,\n childScripts?: Record<string, string>,\n): string | Uint8Array {\n const src = join(sourceDir, filePath);\n const destPath =\n explicitDestPath ??\n (filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath);\n const dest = join(projectDir, destPath);\n\n if (filePath.endsWith(\"bos.config.json\")) {\n const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n const templateContent = readFileSync(src, \"utf-8\");\n\n if (localContent) {\n const local = JSON.parse(localContent) as Record<string, unknown>;\n const template = JSON.parse(templateContent) as Record<string, unknown>;\n const merged = mergeBosConfigWithTemplate(local, template);\n return `${JSON.stringify(merged, null, 2)}\\n`;\n }\n }\n\n if (filePath.endsWith(\"package.json\")) {\n const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n const templateContent = readFileSync(src, \"utf-8\");\n\n if (localContent) {\n const local = JSON.parse(localContent) as Record<string, unknown>;\n const template = JSON.parse(templateContent) as Record<string, unknown>;\n const merged = mergePackageJson(destPath, local, template, childScripts);\n return `${JSON.stringify(merged, null, 2)}\\n`;\n }\n }\n\n return readFileSync(src);\n}\n\nfunction writeSyncedFile(\n sourceDir: string,\n projectDir: string,\n filePath: string,\n explicitDestPath?: string,\n childScripts?: Record<string, string>,\n): void {\n const destPath =\n explicitDestPath ??\n (filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath);\n const dest = join(projectDir, destPath);\n mkdirSync(dirname(dest), { recursive: true });\n writeFileSync(\n dest,\n buildSyncedFileContent(sourceDir, projectDir, filePath, destPath, childScripts),\n );\n}\n\nasync function getSelectedChildPlugins(\n projectDir: string,\n localConfig: Record<string, unknown>,\n): Promise<string[]> {\n if (!localConfig.plugins || typeof localConfig.plugins !== \"object\") {\n return [];\n }\n\n const pluginDirs = new Set(\n (\n await glob(\"plugins/*/package.json\", {\n cwd: projectDir,\n nodir: true,\n dot: false,\n absolute: false,\n })\n )\n .map((file) => file.match(/^plugins\\/([^/]+)\\/package\\.json$/)?.[1])\n .filter((key): key is string => Boolean(key)),\n );\n\n const selected: string[] = [];\n for (const [pluginKey, rawEntry] of Object.entries(\n localConfig.plugins as Record<string, unknown>,\n )) {\n if (typeof rawEntry === \"string\") {\n if (!rawEntry.startsWith(\"local:\")) {\n selected.push(pluginKey);\n continue;\n }\n\n const localPath = join(projectDir, rawEntry.slice(\"local:\".length).trim());\n if (existsSync(localPath) || pluginDirs.has(pluginKey)) {\n selected.push(pluginKey);\n }\n continue;\n }\n\n if (!rawEntry || typeof rawEntry !== \"object\") {\n selected.push(pluginKey);\n continue;\n }\n\n const entry = rawEntry as Record<string, unknown>;\n const development = typeof entry.development === \"string\" ? entry.development : undefined;\n if (!development?.startsWith(\"local:\")) {\n selected.push(pluginKey);\n continue;\n }\n\n const localPath = join(projectDir, development.slice(\"local:\".length).trim());\n if (existsSync(localPath) || pluginDirs.has(pluginKey)) {\n selected.push(pluginKey);\n }\n }\n\n return selected;\n}\n\nfunction hasPluginsWorkspace(projectDir: string): boolean {\n const root = findWorkspaceRoot(projectDir);\n if (!root) return false;\n const rel = relative(root.dir, projectDir);\n const baseDir = rel.startsWith(\"..\") || rel === \"\" ? root.dir : projectDir;\n for (const manifest of [\"pnpm-workspace.yaml\", \"package.json\"]) {\n const manifestPath = join(baseDir, manifest);\n if (!existsSync(manifestPath)) continue;\n try {\n const content = readFileSync(manifestPath, \"utf-8\");\n const packages =\n manifest === \"pnpm-workspace.yaml\"\n ? (parseYaml(content) as { packages?: unknown } | null)?.packages\n : (\n JSON.parse(content) as {\n workspaces?: { packages?: string[] } | string[];\n }\n ).workspaces;\n const globs = Array.isArray(packages)\n ? packages\n : Array.isArray((packages as { packages?: string[] })?.packages)\n ? (packages as { packages?: string[] }).packages\n : [];\n if (globs.includes(\"plugins/*\")) return true;\n } catch {\n return false;\n }\n }\n return false;\n}\n\nexport async function syncTemplate(projectDir: string, options: SyncOptions): Promise<SyncResult> {\n // Sync reads the user's authored config — the raw bos.config.json, or the\n // materialized bos.app.ts descriptor for TS-form children — not the\n // resolved config: it needs the user's explicit local settings (their\n // extends ref, selected plugins, etc.). The resolved config is the merged\n // result and would include inherited parent values that the user didn't\n // explicitly choose, which would break sync filtering.\n const tsFormChild = existsSync(join(projectDir, \"bos.app.ts\"));\n const localConfig = (\n tsFormChild\n ? await loadAppDescriptorConfig(join(projectDir, \"bos.app.ts\"))\n : JSON.parse(readFileSync(join(projectDir, \"bos.config.json\"), \"utf-8\"))\n ) as Record<string, unknown>;\n\n let extendsRef: string | undefined;\n if (typeof localConfig.extends === \"string\") {\n extendsRef = localConfig.extends;\n } else if (isPlainObjectFromMerge(localConfig.extends)) {\n extendsRef = resolveExtendsRef(localConfig.extends as Record<string, string>, \"production\");\n }\n if (!extendsRef?.startsWith(\"bos://\")) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n conflicted: [],\n error: \"No extends field found in bos.config.json — cannot determine parent\",\n };\n }\n\n const extendsMatch = extendsRef.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!extendsMatch) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n conflicted: [],\n error: `Invalid extends reference: ${extendsRef}`,\n };\n }\n\n const extendsAccount = extendsMatch[1];\n const extendsGateway = extendsMatch[2];\n\n const { sourceDir, cleanup } = await resolveSourceDir({\n extendsAccount,\n extendsGateway,\n });\n\n try {\n const childPlugins = await getSelectedChildPlugins(projectDir, localConfig);\n const withUi = existsSync(join(projectDir, \"ui\", \"package.json\"));\n const withApi = existsSync(join(projectDir, \"api\", \"package.json\"));\n const withHost = existsSync(join(projectDir, \"host\", \"package.json\"));\n const withPlugins = childPlugins.length > 0 || hasPluginsWorkspace(projectDir);\n\n const childScripts = buildChildRootScripts({\n ui: withUi,\n api: withApi,\n host: withHost,\n plugins: withPlugins,\n });\n\n const destToSource = new Map<string, string>();\n // TS-form children author bos.app.ts — the parent's JSON config must\n // never sync into them.\n const tsFormChild = !existsSync(join(projectDir, \"bos.config.json\"));\n for (const destPath of FRAMEWORK_OWNED_SYNC_FILES) {\n if (destPath === \"bos.config.json\" && tsFormChild) continue;\n if (destPath.startsWith(\"ui/\") && !withUi) continue;\n if (destPath.startsWith(\"api/\") && !withApi) continue;\n if (destPath.startsWith(\"host/\") && !withHost) continue;\n const sourcePath = toSourcePath(sourceDir, destPath);\n if (!sourcePath) continue;\n destToSource.set(destPath, sourcePath);\n }\n\n for (const destPath of await glob(AGENT_SYNC_GLOBS, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n ignore: [\"**/node_modules/**\", \"**/.git/**\", \"**/dist/**\", \"**/.bos/**\"],\n })) {\n destToSource.set(destPath, destPath);\n }\n\n // Sync api/src/lib/{auth,context}.ts into each plugin's src/lib/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\"))) continue;\n for (const libFile of [\"auth.ts\", \"context.ts\"]) {\n const sourceFile = `api/src/lib/${libFile}`;\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/src/lib/${libFile}`, sourceFile);\n }\n }\n\n // Sync api/src/global.d.ts into each plugin's src/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\"))) continue;\n const sourceFile = \"api/src/global.d.ts\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/src/global.d.ts`, sourceFile);\n }\n\n // Sync tests/types.d.ts into each plugin's tests/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n const sourceFile = \"plugins/_template/tests/types.d.ts\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/tests/types.d.ts`, sourceFile);\n }\n\n // Sync api/src/db/{index,layer,migrate}.ts into each plugin's src/db/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\", \"db\"))) continue;\n for (const dbFile of [\"index.ts\", \"layer.ts\", \"migrate.ts\"]) {\n const sourceFile = `api/src/db/${dbFile}`;\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/src/db/${dbFile}`, sourceFile);\n }\n }\n\n // Sync rspack.config.js from the template into each plugin\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n const sourceFile = \"plugins/_template/rspack.config.js\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/rspack.config.js`, sourceFile);\n }\n\n // Sync drizzle.config.ts from api into each DB-enabled plugin\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\", \"db\"))) continue;\n const sourceFile = \"api/drizzle.config.ts\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/drizzle.config.ts`, sourceFile);\n }\n\n // Sync tsconfig from the template into each plugin\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n const sourceFile = \"plugins/_template/tsconfig.json\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/tsconfig.json`, sourceFile);\n }\n\n const updated: string[] = [];\n const skipped: string[] = [];\n const added: string[] = [];\n const conflicted: string[] = [];\n\n const snapshot = await readSnapshot(projectDir);\n const snapshotFiles = snapshot?.files ?? {};\n\n for (const [destPath, filePath] of destToSource.entries()) {\n if (!existsSync(join(sourceDir, filePath))) {\n // The template no longer ships this file — it was retired from the\n // scaffold. Leave the local copy untouched rather than crashing the\n // sync (the old-CLI + new-template transitional combo).\n skipped.push(destPath);\n continue;\n }\n const localHash = computeLocalHash(projectDir, destPath);\n const sourceHash = computeHash(\n buildSyncedFileContent(sourceDir, projectDir, filePath, undefined, childScripts),\n );\n\n if (localHash === null) {\n added.push(destPath);\n continue;\n }\n\n if (localHash === sourceHash) {\n skipped.push(destPath);\n continue;\n }\n\n const snapshotHash = snapshotFiles[destPath];\n if (!snapshotHash) {\n updated.push(destPath);\n continue;\n }\n\n if (localHash === snapshotHash) {\n updated.push(destPath);\n continue;\n }\n\n if (sourceHash === snapshotHash) {\n skipped.push(destPath);\n continue;\n }\n\n conflicted.push(destPath);\n }\n\n const account = (localConfig.account as string) || extendsAccount;\n const domain = (localConfig.domain as string) || extendsGateway;\n const overrides: Array<\"ui\" | \"api\" | \"host\" | \"plugins\"> = [];\n if (withUi) overrides.push(\"ui\");\n if (withApi) overrides.push(\"api\");\n if (withHost) overrides.push(\"host\");\n if (withPlugins) overrides.push(\"plugins\");\n\n if (options.dryRun) {\n const agentsMdSourcePath = toSourcePath(sourceDir, \"AGENTS.md\");\n if (agentsMdSourcePath) {\n const agentsMdSourceContent = readFileSync(join(sourceDir, agentsMdSourcePath), \"utf-8\");\n const skillsBlock = extractSkillsBlock(agentsMdSourceContent);\n if (skillsBlock) {\n const expectedContent = buildChildAgentsMd(skillsBlock, {\n overrides,\n plugins: childPlugins,\n });\n const expectedHash = computeHash(expectedContent);\n const agentsMdLocalHash = computeLocalHash(projectDir, \"AGENTS.md\");\n if (agentsMdLocalHash !== expectedHash) {\n updated.push(\"AGENTS.md\");\n }\n }\n }\n\n const retirement = retireSyncedFiles(projectDir, snapshotFiles, { dryRun: true });\n\n return {\n status: \"dry-run\",\n updated,\n skipped,\n added,\n conflicted,\n retired: retirement.retired,\n retiredConflicted: retirement.retiredConflicted,\n };\n }\n\n // Migrate the child off the retired bootstrap stubs (ADR 0023) before any\n // writes — a retired file is never in destToSource, so its snapshot entry\n // drops out at the next writeSnapshot.\n const retirement = retireSyncedFiles(projectDir, snapshotFiles, { dryRun: false });\n\n const filesToWrite = [...updated, ...added, ...conflicted];\n\n let backupDir: string | undefined = retirement.backupDir ?? undefined;\n if (filesToWrite.length > 0) {\n backupDir = backupFiles(projectDir, filesToWrite) ?? backupDir;\n\n for (const destPath of filesToWrite) {\n const sourcePath = destToSource.get(destPath) ?? destPath;\n writeSyncedFile(sourceDir, projectDir, sourcePath, destPath, childScripts);\n }\n }\n\n await personalizeConfig(projectDir, {\n extendsAccount,\n extendsGateway,\n account,\n domain,\n overrides,\n plugins: childPlugins,\n workspaceOpts: { sourceDir },\n mode: \"sync\",\n existingConfig: localConfig,\n });\n\n await syncResolvedSharedDeps({\n configDir: projectDir,\n hostMode: \"local\",\n });\n\n const syncedConfig = await openResolution({ cwd: projectDir });\n if (syncedConfig?.runtime) {\n await materializeViaLayer(projectDir, syncedConfig.runtime!);\n }\n\n const newSnapshotFiles: Record<string, string> = {};\n for (const destPath of destToSource.keys()) {\n const hash = computeLocalHash(projectDir, destPath);\n if (hash) {\n newSnapshotFiles[destPath] = hash;\n }\n }\n\n const agentsMdSourcePath = toSourcePath(sourceDir, \"AGENTS.md\");\n if (agentsMdSourcePath) {\n const agentsMdSourceContent = readFileSync(join(sourceDir, agentsMdSourcePath), \"utf-8\");\n const skillsBlock = extractSkillsBlock(agentsMdSourceContent);\n if (skillsBlock) {\n const expectedContent = buildChildAgentsMd(skillsBlock, {\n overrides,\n plugins: childPlugins,\n });\n const expectedHash = computeHash(expectedContent);\n\n const agentsMdLocalHash = computeLocalHash(projectDir, \"AGENTS.md\");\n if (agentsMdLocalHash !== expectedHash) {\n writeFileSync(join(projectDir, \"AGENTS.md\"), expectedContent);\n updated.push(\"AGENTS.md\");\n }\n\n newSnapshotFiles[\"AGENTS.md\"] = expectedHash;\n }\n }\n\n await writeSnapshot(projectDir, {\n parentRef: `bos://${extendsAccount}/${extendsGateway}`,\n files: newSnapshotFiles,\n });\n\n if (!options.noInstall) {\n await runPnpmInstall(findWorkspaceRoot(projectDir)?.dir ?? projectDir);\n await runTypesGen(projectDir);\n }\n\n return {\n status: \"synced\",\n updated,\n skipped,\n added,\n conflicted,\n retired: retirement.retired,\n retiredConflicted: retirement.retiredConflicted,\n retiredBackupDir: retirement.backupDir ?? undefined,\n backupDir,\n };\n } finally {\n await cleanup();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sync.cjs","names":["join","existsSync","readFileSync","computeHash","dirname","mergeBosConfigWithTemplate","findWorkspaceRoot","relative","parseYaml","loadAppDescriptorConfig","isPlainObjectFromMerge","resolveExtendsRef","resolveSourceDir","buildChildRootScripts","readSnapshot","extractSkillsBlock","buildChildAgentsMd","personalizeConfig","syncResolvedSharedDeps","openResolution","materializeViaLayer","writeSnapshot","runPnpmInstall","runTypesGen"],"sources":["../../src/cli/sync.ts"],"sourcesContent":["import { copyFileSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative } from \"node:path\";\nimport { glob } from \"glob\";\nimport { parse as parseYaml } from \"yaml\";\nimport { loadAppDescriptorConfig } from \"../config\";\nimport type { SyncOptions, SyncResult } from \"../contract\";\nimport { materializeViaLayer } from \"../infra/materializer\";\nimport {\n isPlainObject as isPlainObjectFromMerge,\n mergeBosConfigWithTemplate,\n resolveExtendsRef,\n} from \"../merge\";\nimport { openResolution } from \"../resolution/session\";\nimport { syncResolvedSharedDeps } from \"../shared-deps\";\nimport { computeSnapshotHash as computeHash } from \"../utils/snapshot-hash\";\nimport { findWorkspaceRoot } from \"../workspace\";\nimport {\n buildChildAgentsMd,\n buildChildRootScripts,\n extractSkillsBlock,\n personalizeConfig,\n resolveSourceDir,\n runPnpmInstall,\n runTypesGen,\n} from \"./init\";\nimport { readSnapshot, writeSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_OWNED_SYNC_FILES = new Set([\n \".env.example\",\n \".gitignore\",\n \"biome.json\",\n \"bos.config.json\",\n \"package.json\",\n \".changeset/config.json\",\n \".changeset/README.md\",\n \".github/workflows/ci.yml\",\n \".github/workflows/deploy.yml\",\n \".github/workflows/staging.yml\",\n \".github/workflows/release.yml\",\n \"railway.toml\",\n \"ui/package.json\",\n \"ui/postcss.config.mjs\",\n \"ui/tsconfig.json\",\n \"api/package.json\",\n \"api/plugin.dev.ts\",\n \"api/rspack.config.js\",\n \"api/tsconfig.json\",\n \"api/src/lib/context.ts\",\n \"api/drizzle.config.ts\",\n \"api/src/db/index.ts\",\n \"api/src/db/layer.ts\",\n \"api/src/db/migrate.ts\",\n \"api/src/global.d.ts\",\n \"api/tests/types.d.ts\",\n]);\n\n/**\n * Files the scaffold previously sync-owned but has retired (ADR 0023) — the\n * generated `.gen` bootstrap stubs replaced them. During sync: a local copy\n * whose hash still matches the sync snapshot is deleted silently; a\n * hand-modified (or never-snapshotted) copy is backed up, then deleted. The\n * app's authored ui files (router.tsx, app.ts, lib, routes, components) are\n * NOT retired — they leave the sync list as app-owned files, untouched.\n */\nexport const RETIRED_SYNC_FILES = new Set([\n \"ui/src/entry.ts\",\n \"ui/src/globals.d.ts\",\n \"ui/src/hydrate.tsx\",\n \"ui/src/router.server.tsx\",\n \"ui/src/compose.ts\",\n]);\n\ntype PackageJson = Record<string, unknown>;\n\nconst AGENT_SYNC_GLOBS = [\".agents/skills/**\", \"docs/agents/**\", \"skills-lock.json\"];\n\nexport function isFrameworkOwnedSyncFile(filePath: string): boolean {\n if (FRAMEWORK_OWNED_SYNC_FILES.has(filePath)) return true;\n if (\n filePath.startsWith(\".agents/skills/\") ||\n filePath.startsWith(\"docs/agents/\") ||\n filePath === \"skills-lock.json\"\n )\n return true;\n // lib/auth.ts is NOT sync-owned since #207: the middleware factory lives in\n // everything-dev/api (framework home); projects import it, they don't own a copy.\n if (/^plugins\\/[^/]+\\/src\\/lib\\/context\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/src\\/db\\/(index|layer|migrate)\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/rspack\\.config\\.js$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/drizzle\\.config\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/src\\/global\\.d\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/tests\\/types\\.d\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/tsconfig\\.json$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/tsconfig\\.contract\\.json$/.test(filePath)) return true;\n return false;\n}\n\nfunction computeLocalHash(projectDir: string, filePath: string): string | null {\n const fullPath = join(projectDir, filePath);\n if (!existsSync(fullPath)) return null;\n try {\n const content = readFileSync(fullPath);\n return computeHash(content);\n } catch {\n return null;\n }\n}\n\nfunction backupFiles(projectDir: string, filePaths: string[]): string | null {\n const filesToBackup = filePaths.filter((f) => existsSync(join(projectDir, f)));\n if (filesToBackup.length === 0) return null;\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupDir = join(projectDir, \".bos\", \"sync-backup\", timestamp);\n\n for (const filePath of filesToBackup) {\n const src = join(projectDir, filePath);\n const dest = join(backupDir, filePath);\n mkdirSync(dirname(dest), { recursive: true });\n copyFileSync(src, dest);\n }\n\n return backupDir;\n}\n\nexport interface RetiredSyncFilesResult {\n /** unmodified stub copies — deleted (in a real run) */\n retired: string[];\n /** hand-modified or never-snapshotted stub copies — backed up, then deleted */\n retiredConflicted: string[];\n backupDir: string | null;\n}\n\n/**\n * Migrate a child off the retired bootstrap stub files (ADR 0023): unmodified\n * copies are deleted silently, hand-modified copies are backed up first. In\n * dry-run the actions are reported without touching the tree.\n */\nexport function retireSyncedFiles(\n projectDir: string,\n snapshotFiles: Record<string, string>,\n opts: { dryRun: boolean },\n): RetiredSyncFilesResult {\n const retired: string[] = [];\n const retiredConflicted: string[] = [];\n\n for (const destPath of RETIRED_SYNC_FILES) {\n const localHash = computeLocalHash(projectDir, destPath);\n if (localHash === null) continue;\n if (localHash === snapshotFiles[destPath]) {\n retired.push(destPath);\n } else {\n retiredConflicted.push(destPath);\n }\n }\n\n if (opts.dryRun || (retired.length === 0 && retiredConflicted.length === 0)) {\n return { retired, retiredConflicted, backupDir: null };\n }\n\n const backupDir = backupFiles(projectDir, retiredConflicted);\n for (const destPath of [...retired, ...retiredConflicted]) {\n rmSync(join(projectDir, destPath));\n }\n return { retired, retiredConflicted, backupDir };\n}\n\nfunction mergeStringMaps(\n local: Record<string, string> | undefined,\n template: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n if (!local && !template) return undefined;\n\n const merged: Record<string, string> = { ...local };\n for (const [name, value] of Object.entries(template ?? {})) {\n merged[name] = value;\n }\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeWorkspacePackages(local: unknown, template: unknown): string[] | undefined {\n const localPackages = Array.isArray(local) ? local : [];\n const templatePackages = Array.isArray(template) ? template : [];\n if (localPackages.length === 0 && templatePackages.length === 0) return undefined;\n\n const ordered = new Set<string>();\n for (const entry of templatePackages) {\n if (typeof entry === \"string\" && entry.length > 0) ordered.add(entry);\n }\n for (const entry of localPackages) {\n if (typeof entry === \"string\" && entry.length > 0) ordered.add(entry);\n }\n\n const hasPluginEntry = [...ordered].some((e) => e.startsWith(\"plugins/\") && e !== \"plugins/*\");\n if (hasPluginEntry) {\n for (const entry of ordered) {\n if (entry.startsWith(\"plugins/\") && entry !== \"plugins/*\") {\n ordered.delete(entry);\n }\n }\n ordered.add(\"plugins/*\");\n }\n\n return ordered.size > 0 ? [...ordered] : undefined;\n}\n\nexport function mergePackageJson(\n filePath: string,\n local: PackageJson,\n template: PackageJson,\n childScripts?: Record<string, string>,\n): PackageJson {\n const merged: PackageJson = { ...local, ...template };\n\n if (filePath === \"package.json\") {\n for (const key of [\"name\", \"private\", \"version\"] as const) {\n if (key in local) {\n merged[key] = local[key];\n }\n }\n } else if (\"version\" in local) {\n merged.version = local.version;\n }\n\n for (const depField of [\n \"dependencies\",\n \"devDependencies\",\n \"peerDependencies\",\n \"overrides\",\n ] as const) {\n const localDeps = local[depField] as Record<string, string> | undefined;\n const templateDeps = template[depField] as Record<string, string> | undefined;\n\n const mergedDeps = mergeStringMaps(localDeps, templateDeps);\n if (mergedDeps) {\n merged[depField] = mergedDeps;\n } else {\n delete merged[depField];\n }\n }\n\n if (\n (local.scripts && typeof local.scripts === \"object\") ||\n (template.scripts && typeof template.scripts === \"object\") ||\n childScripts\n ) {\n const mergedScripts = mergeStringMaps(\n local.scripts as Record<string, string> | undefined,\n filePath === \"package.json\" && childScripts\n ? childScripts\n : (template.scripts as Record<string, string> | undefined),\n );\n if (mergedScripts) {\n merged.scripts = mergedScripts;\n } else {\n delete merged.scripts;\n }\n }\n\n if (\n (local.workspaces && typeof local.workspaces === \"object\") ||\n (template.workspaces && typeof template.workspaces === \"object\")\n ) {\n const localWorkspaces = (local.workspaces ?? {}) as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n const templateWorkspaces = (template.workspaces ?? {}) as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n\n const mergedWorkspaces: { packages?: string[]; catalog?: Record<string, string> } = {\n ...localWorkspaces,\n ...templateWorkspaces,\n };\n\n const mergedPackages = mergeWorkspacePackages(\n localWorkspaces.packages,\n templateWorkspaces.packages,\n );\n if (mergedPackages) {\n mergedWorkspaces.packages = mergedPackages;\n } else {\n delete mergedWorkspaces.packages;\n }\n\n const mergedCatalog = mergeStringMaps(localWorkspaces.catalog, templateWorkspaces.catalog);\n if (mergedCatalog) {\n mergedWorkspaces.catalog = mergedCatalog;\n } else {\n delete mergedWorkspaces.catalog;\n }\n\n if (Object.keys(mergedWorkspaces).length > 0) {\n merged.workspaces = mergedWorkspaces;\n } else {\n delete merged.workspaces;\n }\n }\n\n return merged;\n}\n\nfunction toSourcePath(sourceDir: string, destPath: string): string | null {\n if (destPath.startsWith(\".github/\")) {\n const templatePath = destPath.replace(/^\\.github\\//, \".github/templates/\");\n if (existsSync(join(sourceDir, templatePath))) {\n return templatePath;\n }\n }\n\n const directPath = join(sourceDir, destPath);\n if (existsSync(directPath)) {\n return destPath;\n }\n\n return null;\n}\n\nfunction buildSyncedFileContent(\n sourceDir: string,\n projectDir: string,\n filePath: string,\n explicitDestPath?: string,\n childScripts?: Record<string, string>,\n): string | Uint8Array {\n const src = join(sourceDir, filePath);\n const destPath =\n explicitDestPath ??\n (filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath);\n const dest = join(projectDir, destPath);\n\n if (filePath.endsWith(\"bos.config.json\")) {\n const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n const templateContent = readFileSync(src, \"utf-8\");\n\n if (localContent) {\n const local = JSON.parse(localContent) as Record<string, unknown>;\n const template = JSON.parse(templateContent) as Record<string, unknown>;\n const merged = mergeBosConfigWithTemplate(local, template);\n return `${JSON.stringify(merged, null, 2)}\\n`;\n }\n }\n\n if (filePath.endsWith(\"package.json\")) {\n const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n const templateContent = readFileSync(src, \"utf-8\");\n\n if (localContent) {\n const local = JSON.parse(localContent) as Record<string, unknown>;\n const template = JSON.parse(templateContent) as Record<string, unknown>;\n const merged = mergePackageJson(destPath, local, template, childScripts);\n return `${JSON.stringify(merged, null, 2)}\\n`;\n }\n }\n\n return readFileSync(src);\n}\n\nfunction writeSyncedFile(\n sourceDir: string,\n projectDir: string,\n filePath: string,\n explicitDestPath?: string,\n childScripts?: Record<string, string>,\n): void {\n const destPath =\n explicitDestPath ??\n (filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath);\n const dest = join(projectDir, destPath);\n mkdirSync(dirname(dest), { recursive: true });\n writeFileSync(\n dest,\n buildSyncedFileContent(sourceDir, projectDir, filePath, destPath, childScripts),\n );\n}\n\nasync function getSelectedChildPlugins(\n projectDir: string,\n localConfig: Record<string, unknown>,\n): Promise<string[]> {\n if (!localConfig.plugins || typeof localConfig.plugins !== \"object\") {\n return [];\n }\n\n const pluginDirs = new Set(\n (\n await glob(\"plugins/*/package.json\", {\n cwd: projectDir,\n nodir: true,\n dot: false,\n absolute: false,\n })\n )\n .map((file) => file.match(/^plugins\\/([^/]+)\\/package\\.json$/)?.[1])\n .filter((key): key is string => Boolean(key)),\n );\n\n const selected: string[] = [];\n for (const [pluginKey, rawEntry] of Object.entries(\n localConfig.plugins as Record<string, unknown>,\n )) {\n if (typeof rawEntry === \"string\") {\n if (!rawEntry.startsWith(\"local:\")) {\n selected.push(pluginKey);\n continue;\n }\n\n const localPath = join(projectDir, rawEntry.slice(\"local:\".length).trim());\n if (existsSync(localPath) || pluginDirs.has(pluginKey)) {\n selected.push(pluginKey);\n }\n continue;\n }\n\n if (!rawEntry || typeof rawEntry !== \"object\") {\n selected.push(pluginKey);\n continue;\n }\n\n const entry = rawEntry as Record<string, unknown>;\n const development = typeof entry.development === \"string\" ? entry.development : undefined;\n if (!development?.startsWith(\"local:\")) {\n selected.push(pluginKey);\n continue;\n }\n\n const localPath = join(projectDir, development.slice(\"local:\".length).trim());\n if (existsSync(localPath) || pluginDirs.has(pluginKey)) {\n selected.push(pluginKey);\n }\n }\n\n return selected;\n}\n\nfunction hasPluginsWorkspace(projectDir: string): boolean {\n const root = findWorkspaceRoot(projectDir);\n if (!root) return false;\n const rel = relative(root.dir, projectDir);\n const baseDir = rel.startsWith(\"..\") || rel === \"\" ? root.dir : projectDir;\n for (const manifest of [\"pnpm-workspace.yaml\", \"package.json\"]) {\n const manifestPath = join(baseDir, manifest);\n if (!existsSync(manifestPath)) continue;\n try {\n const content = readFileSync(manifestPath, \"utf-8\");\n const packages =\n manifest === \"pnpm-workspace.yaml\"\n ? (parseYaml(content) as { packages?: unknown } | null)?.packages\n : (\n JSON.parse(content) as {\n workspaces?: { packages?: string[] } | string[];\n }\n ).workspaces;\n const globs: string[] = Array.isArray(packages)\n ? packages\n : Array.isArray((packages as { packages?: string[] })?.packages)\n ? ((packages as { packages?: string[] }).packages ?? [])\n : [];\n if (globs.includes(\"plugins/*\")) return true;\n } catch {\n return false;\n }\n }\n return false;\n}\n\nexport async function syncTemplate(projectDir: string, options: SyncOptions): Promise<SyncResult> {\n // Sync reads the user's authored config — the raw bos.config.json, or the\n // materialized bos.app.ts descriptor for TS-form children — not the\n // resolved config: it needs the user's explicit local settings (their\n // extends ref, selected plugins, etc.). The resolved config is the merged\n // result and would include inherited parent values that the user didn't\n // explicitly choose, which would break sync filtering.\n const tsFormChild = existsSync(join(projectDir, \"bos.app.ts\"));\n const localConfig = (\n tsFormChild\n ? await loadAppDescriptorConfig(join(projectDir, \"bos.app.ts\"))\n : JSON.parse(readFileSync(join(projectDir, \"bos.config.json\"), \"utf-8\"))\n ) as Record<string, unknown>;\n\n let extendsRef: string | undefined;\n if (typeof localConfig.extends === \"string\") {\n extendsRef = localConfig.extends;\n } else if (isPlainObjectFromMerge(localConfig.extends)) {\n extendsRef = resolveExtendsRef(localConfig.extends as Record<string, string>, \"production\");\n }\n if (!extendsRef?.startsWith(\"bos://\")) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n conflicted: [],\n error: \"No extends field found in bos.config.json — cannot determine parent\",\n };\n }\n\n const extendsMatch = extendsRef.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!extendsMatch) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n conflicted: [],\n error: `Invalid extends reference: ${extendsRef}`,\n };\n }\n\n const extendsAccount = extendsMatch[1];\n const extendsGateway = extendsMatch[2];\n\n const { sourceDir, cleanup } = await resolveSourceDir({\n extendsAccount,\n extendsGateway,\n });\n\n try {\n const childPlugins = await getSelectedChildPlugins(projectDir, localConfig);\n const withUi = existsSync(join(projectDir, \"ui\", \"package.json\"));\n const withApi = existsSync(join(projectDir, \"api\", \"package.json\"));\n const withHost = existsSync(join(projectDir, \"host\", \"package.json\"));\n const withPlugins = childPlugins.length > 0 || hasPluginsWorkspace(projectDir);\n\n const childScripts = buildChildRootScripts({\n ui: withUi,\n api: withApi,\n host: withHost,\n plugins: withPlugins,\n });\n\n const destToSource = new Map<string, string>();\n // TS-form children author bos.app.ts — the parent's JSON config must\n // never sync into them.\n const tsFormChild = !existsSync(join(projectDir, \"bos.config.json\"));\n for (const destPath of FRAMEWORK_OWNED_SYNC_FILES) {\n if (destPath === \"bos.config.json\" && tsFormChild) continue;\n if (destPath.startsWith(\"ui/\") && !withUi) continue;\n if (destPath.startsWith(\"api/\") && !withApi) continue;\n if (destPath.startsWith(\"host/\") && !withHost) continue;\n const sourcePath = toSourcePath(sourceDir, destPath);\n if (!sourcePath) continue;\n destToSource.set(destPath, sourcePath);\n }\n\n for (const destPath of await glob(AGENT_SYNC_GLOBS, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n ignore: [\"**/node_modules/**\", \"**/.git/**\", \"**/dist/**\", \"**/.bos/**\"],\n })) {\n destToSource.set(destPath, destPath);\n }\n\n // Sync api/src/lib/{auth,context}.ts into each plugin's src/lib/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\"))) continue;\n for (const libFile of [\"auth.ts\", \"context.ts\"]) {\n const sourceFile = `api/src/lib/${libFile}`;\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/src/lib/${libFile}`, sourceFile);\n }\n }\n\n // Sync api/src/global.d.ts into each plugin's src/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\"))) continue;\n const sourceFile = \"api/src/global.d.ts\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/src/global.d.ts`, sourceFile);\n }\n\n // Sync tests/types.d.ts into each plugin's tests/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n const sourceFile = \"plugins/_template/tests/types.d.ts\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/tests/types.d.ts`, sourceFile);\n }\n\n // Sync api/src/db/{index,layer,migrate}.ts into each plugin's src/db/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\", \"db\"))) continue;\n for (const dbFile of [\"index.ts\", \"layer.ts\", \"migrate.ts\"]) {\n const sourceFile = `api/src/db/${dbFile}`;\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/src/db/${dbFile}`, sourceFile);\n }\n }\n\n // Sync rspack.config.js from the template into each plugin\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n const sourceFile = \"plugins/_template/rspack.config.js\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/rspack.config.js`, sourceFile);\n }\n\n // Sync drizzle.config.ts from api into each DB-enabled plugin\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\", \"db\"))) continue;\n const sourceFile = \"api/drizzle.config.ts\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/drizzle.config.ts`, sourceFile);\n }\n\n // Sync tsconfig from the template into each plugin\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n const sourceFile = \"plugins/_template/tsconfig.json\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/tsconfig.json`, sourceFile);\n }\n\n const updated: string[] = [];\n const skipped: string[] = [];\n const added: string[] = [];\n const conflicted: string[] = [];\n\n const snapshot = await readSnapshot(projectDir);\n const snapshotFiles = snapshot?.files ?? {};\n\n for (const [destPath, filePath] of destToSource.entries()) {\n if (!existsSync(join(sourceDir, filePath))) {\n // The template no longer ships this file — it was retired from the\n // scaffold. Leave the local copy untouched rather than crashing the\n // sync (the old-CLI + new-template transitional combo).\n skipped.push(destPath);\n continue;\n }\n const localHash = computeLocalHash(projectDir, destPath);\n const sourceHash = computeHash(\n buildSyncedFileContent(sourceDir, projectDir, filePath, undefined, childScripts),\n );\n\n if (localHash === null) {\n added.push(destPath);\n continue;\n }\n\n if (localHash === sourceHash) {\n skipped.push(destPath);\n continue;\n }\n\n const snapshotHash = snapshotFiles[destPath];\n if (!snapshotHash) {\n updated.push(destPath);\n continue;\n }\n\n if (localHash === snapshotHash) {\n updated.push(destPath);\n continue;\n }\n\n if (sourceHash === snapshotHash) {\n skipped.push(destPath);\n continue;\n }\n\n conflicted.push(destPath);\n }\n\n const account = (localConfig.account as string) || extendsAccount;\n const domain = (localConfig.domain as string) || extendsGateway;\n const overrides: Array<\"ui\" | \"api\" | \"host\" | \"plugins\"> = [];\n if (withUi) overrides.push(\"ui\");\n if (withApi) overrides.push(\"api\");\n if (withHost) overrides.push(\"host\");\n if (withPlugins) overrides.push(\"plugins\");\n\n if (options.dryRun) {\n const agentsMdSourcePath = toSourcePath(sourceDir, \"AGENTS.md\");\n if (agentsMdSourcePath) {\n const agentsMdSourceContent = readFileSync(join(sourceDir, agentsMdSourcePath), \"utf-8\");\n const skillsBlock = extractSkillsBlock(agentsMdSourceContent);\n if (skillsBlock) {\n const expectedContent = buildChildAgentsMd(skillsBlock, {\n overrides,\n plugins: childPlugins,\n });\n const expectedHash = computeHash(expectedContent);\n const agentsMdLocalHash = computeLocalHash(projectDir, \"AGENTS.md\");\n if (agentsMdLocalHash !== expectedHash) {\n updated.push(\"AGENTS.md\");\n }\n }\n }\n\n const retirement = retireSyncedFiles(projectDir, snapshotFiles, { dryRun: true });\n\n return {\n status: \"dry-run\",\n updated,\n skipped,\n added,\n conflicted,\n retired: retirement.retired,\n retiredConflicted: retirement.retiredConflicted,\n };\n }\n\n // Migrate the child off the retired bootstrap stubs (ADR 0023) before any\n // writes — a retired file is never in destToSource, so its snapshot entry\n // drops out at the next writeSnapshot.\n const retirement = retireSyncedFiles(projectDir, snapshotFiles, { dryRun: false });\n\n const filesToWrite = [...updated, ...added, ...conflicted];\n\n let backupDir: string | undefined = retirement.backupDir ?? undefined;\n if (filesToWrite.length > 0) {\n backupDir = backupFiles(projectDir, filesToWrite) ?? backupDir;\n\n for (const destPath of filesToWrite) {\n const sourcePath = destToSource.get(destPath) ?? destPath;\n writeSyncedFile(sourceDir, projectDir, sourcePath, destPath, childScripts);\n }\n }\n\n await personalizeConfig(projectDir, {\n extendsAccount,\n extendsGateway,\n account,\n domain,\n overrides,\n plugins: childPlugins,\n workspaceOpts: { sourceDir },\n mode: \"sync\",\n existingConfig: localConfig,\n });\n\n await syncResolvedSharedDeps({\n configDir: projectDir,\n hostMode: \"local\",\n });\n\n const syncedConfig = await openResolution({ cwd: projectDir });\n if (syncedConfig?.runtime) {\n await materializeViaLayer(projectDir, syncedConfig.runtime!);\n }\n\n const newSnapshotFiles: Record<string, string> = {};\n for (const destPath of destToSource.keys()) {\n const hash = computeLocalHash(projectDir, destPath);\n if (hash) {\n newSnapshotFiles[destPath] = hash;\n }\n }\n\n const agentsMdSourcePath = toSourcePath(sourceDir, \"AGENTS.md\");\n if (agentsMdSourcePath) {\n const agentsMdSourceContent = readFileSync(join(sourceDir, agentsMdSourcePath), \"utf-8\");\n const skillsBlock = extractSkillsBlock(agentsMdSourceContent);\n if (skillsBlock) {\n const expectedContent = buildChildAgentsMd(skillsBlock, {\n overrides,\n plugins: childPlugins,\n });\n const expectedHash = computeHash(expectedContent);\n\n const agentsMdLocalHash = computeLocalHash(projectDir, \"AGENTS.md\");\n if (agentsMdLocalHash !== expectedHash) {\n writeFileSync(join(projectDir, \"AGENTS.md\"), expectedContent);\n updated.push(\"AGENTS.md\");\n }\n\n newSnapshotFiles[\"AGENTS.md\"] = expectedHash;\n }\n }\n\n await writeSnapshot(projectDir, {\n parentRef: `bos://${extendsAccount}/${extendsGateway}`,\n files: newSnapshotFiles,\n });\n\n if (!options.noInstall) {\n await runPnpmInstall(findWorkspaceRoot(projectDir)?.dir ?? projectDir);\n await runTypesGen(projectDir);\n }\n\n return {\n status: \"synced\",\n updated,\n skipped,\n added,\n conflicted,\n retired: retirement.retired,\n retiredConflicted: retirement.retiredConflicted,\n retiredBackupDir: retirement.backupDir ?? undefined,\n backupDir,\n };\n } finally {\n await cleanup();\n }\n}\n"],"mappings":"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"}
package/dist/cli/sync.mjs CHANGED
@@ -274,7 +274,7 @@ function hasPluginsWorkspace(projectDir) {
274
274
  try {
275
275
  const content = readFileSync(manifestPath, "utf-8");
276
276
  const packages = manifest === "pnpm-workspace.yaml" ? parse(content)?.packages : JSON.parse(content).workspaces;
277
- if ((Array.isArray(packages) ? packages : Array.isArray(packages?.packages) ? packages.packages : []).includes("plugins/*")) return true;
277
+ if ((Array.isArray(packages) ? packages : Array.isArray(packages?.packages) ? packages.packages ?? [] : []).includes("plugins/*")) return true;
278
278
  } catch {
279
279
  return false;
280
280
  }