everything-dev 1.46.1 → 1.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/build.cjs CHANGED
@@ -98,20 +98,24 @@ async function runBuildAttempt(cmd, args, cwd, env, verbose, wsKey) {
98
98
  const output = `${stdout}\n${stderr}`;
99
99
  const deployEntries = require_integrity.parseDeployLines(output);
100
100
  if (deployEntries.length > 0) {
101
- if (exitCode !== 0) {
102
- const errorLines = output.split("\n").filter((line) => /\bERROR\b/.test(line) || line.startsWith("Rspack compiled with")).slice(0, 5);
103
- if (errorLines.length > 0 && !verbose) {
104
- console.log(` ${require_theme.colors.yellow("⚠")} Build completed with errors (exit code ${exitCode}) — Zephyr deployed successfully`);
105
- for (const line of errorLines) console.log(` ${require_theme.colors.dim(line.trim())}`);
106
- }
107
- }
108
- return {
101
+ const result = {
109
102
  success: true,
110
103
  url: deployEntries[0]?.url,
111
104
  exitCode: 0,
112
105
  output,
113
106
  deployEntries
114
107
  };
108
+ if (exitCode !== 0) {
109
+ const errorLines = output.split("\n").filter((line) => /\bERROR\b/.test(line) || line.startsWith("Rspack compiled with")).slice(0, 5);
110
+ if (errorLines.length > 0) {
111
+ result.warnings = errorLines.map((l) => l.trim());
112
+ if (!verbose) {
113
+ console.log(` ${require_theme.colors.yellow("⚠")} Build completed with errors (exit code ${exitCode}) — Zephyr deployed successfully`);
114
+ for (const line of errorLines) console.log(` ${require_theme.colors.dim(line.trim())}`);
115
+ }
116
+ }
117
+ }
118
+ return result;
115
119
  }
116
120
  if (exitCode !== 0) return {
117
121
  success: false,
@@ -119,13 +123,6 @@ async function runBuildAttempt(cmd, args, cwd, env, verbose, wsKey) {
119
123
  exitCode,
120
124
  output
121
125
  };
122
- const zeMatch = output.match(/ZE\d+/);
123
- if (zeMatch) return {
124
- success: false,
125
- error: `Zephyr upload failed (${zeMatch[0]})`,
126
- exitCode: 0,
127
- output
128
- };
129
126
  const deployMatch = output.match(/🚀.*Deployed:\s*(https?:\S+)/);
130
127
  if (deployMatch) return {
131
128
  success: true,
@@ -133,6 +130,13 @@ async function runBuildAttempt(cmd, args, cwd, env, verbose, wsKey) {
133
130
  exitCode: 0,
134
131
  output
135
132
  };
133
+ const zeMatch = output.match(/ZE\d{4,}/);
134
+ if (zeMatch) return {
135
+ success: false,
136
+ error: `Zephyr upload failed (${zeMatch[0]})`,
137
+ exitCode: 0,
138
+ output
139
+ };
136
140
  if (env.DEPLOY === "true") return {
137
141
  success: false,
138
142
  error: "No deploy URL found (Zephyr may have failed)",
@@ -158,10 +162,12 @@ async function buildOneWorkspace(ws, env, opts) {
158
162
  const startTime = Date.now();
159
163
  let attempt = await runBuildAttempt(buildConfig.cmd, buildConfig.args, ws.path, wsEnv, opts.verbose ?? false, ws.key);
160
164
  let retried = false;
165
+ const firstAttempt = attempt.success ? void 0 : { ...attempt };
161
166
  if (!attempt.success && attempt.exitCode === 0 && opts.deploy) {
162
167
  if (!opts.verbose) console.log(` ${require_theme.colors.yellow("↻")} ${require_string.padRight(ws.key, 28)} retrying...`);
163
168
  retried = true;
164
169
  attempt = await runBuildAttempt(buildConfig.cmd, buildConfig.args, ws.path, wsEnv, opts.verbose ?? false, ws.key);
170
+ if (!attempt.success && firstAttempt) attempt.error = `First attempt: ${firstAttempt.error}\nRetry: ${attempt.error}`;
165
171
  }
166
172
  const durationMs = Date.now() - startTime;
167
173
  const result = {
@@ -170,6 +176,7 @@ async function buildOneWorkspace(ws, env, opts) {
170
176
  success: attempt.success,
171
177
  url: attempt.url,
172
178
  error: attempt.error,
179
+ warnings: attempt.warnings,
173
180
  deployEntries: attempt.deployEntries,
174
181
  durationMs,
175
182
  retried: retried ? true : void 0
@@ -1 +1 @@
1
- {"version":3,"file":"build.cjs","names":["resolveLocalDevelopmentPath","run","colors","parseDeployLines","padRight","formatDuration","icons","syncResolvedSharedDeps","process","applyDeployResults"],"sources":["../src/build.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { access, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport { formatDuration } from \"./cli/timing\";\nimport { resolveLocalDevelopmentPath } from \"./config\";\nimport type { WorkspaceDeployResult } from \"./contract\";\nimport { applyDeployResults, type DeployResultEntry, parseDeployLines } from \"./integrity\";\nimport { syncResolvedSharedDeps } from \"./shared-deps\";\nimport type { BosConfig, BosPluginRef, RuntimeConfig } from \"./types\";\nimport { run } from \"./utils/run\";\nimport { padRight } from \"./utils/string\";\nimport { colors, icons } from \"./utils/theme\";\n\nconst buildCommands: Record<string, { cmd: string; args: string[] }> = {\n host: { cmd: \"bun\", args: [\"run\", \"build\"] },\n ui: { cmd: \"bun\", args: [\"run\", \"build\"] },\n api: { cmd: \"bun\", args: [\"run\", \"build\"] },\n};\n\ntype WorkspaceTarget = {\n key: string;\n kind: \"app\" | \"plugin\";\n path: string;\n};\n\nexport function getPluginRef(entry: string | BosPluginRef | undefined | null): BosPluginRef | null {\n if (!entry || typeof entry === \"string\") return null;\n return entry;\n}\n\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readJsonFile<T>(path: string): Promise<T> {\n return JSON.parse(await readFile(path, \"utf8\")) as T;\n}\n\nfunction resolveWorkspaceTarget(\n key: string,\n bosConfig: BosConfig | null,\n runtimeConfig: RuntimeConfig | null,\n configDir: string,\n): WorkspaceTarget | null {\n if (bosConfig?.app && key in bosConfig.app) {\n const appEntry = (bosConfig.app as Record<string, { development?: string }>)[key];\n const devPath = resolveLocalDevelopmentPath(appEntry?.development, configDir);\n if (devPath) {\n return {\n key,\n kind: \"app\",\n path: devPath,\n };\n }\n return {\n key,\n kind: \"app\",\n path: `${configDir}/${key}`,\n };\n }\n\n const runtimePlugin = runtimeConfig?.plugins?.[key];\n const pluginPath =\n runtimePlugin?.localPath ??\n resolveLocalDevelopmentPath(getPluginRef(bosConfig?.plugins?.[key])?.development, configDir);\n if (pluginPath) {\n return {\n key,\n kind: \"plugin\",\n path: pluginPath,\n };\n }\n\n return null;\n}\n\nexport function selectWorkspaceTargets(packages: string, bosConfig: BosConfig | null): string[] {\n const allPackages = [\n ...Object.keys(bosConfig?.app ?? {}),\n ...Object.keys(bosConfig?.plugins ?? {}),\n ];\n if (packages === \"all\") {\n return allPackages;\n }\n\n return packages\n .split(\",\")\n .map((pkg) => pkg.trim())\n .filter((pkg) => allPackages.includes(pkg));\n}\n\ninterface BuildAttemptResult {\n success: boolean;\n url?: string;\n error?: string;\n exitCode: number;\n output: string;\n deployEntries?: DeployResultEntry[];\n}\n\nasync function runBuildAttempt(\n cmd: string,\n args: string[],\n cwd: string,\n env: Record<string, string>,\n verbose: boolean,\n wsKey: string,\n): Promise<BuildAttemptResult> {\n let zephyrAuthShown = false;\n const result = await run(cmd, args, {\n cwd,\n env,\n capture: true,\n onChunk: (stream, chunk) => {\n if (verbose) {\n if (stream === \"stdout\") process.stdout.write(chunk);\n else process.stderr.write(chunk);\n }\n if (zephyrAuthShown) return;\n const text = chunk.toString(\"utf-8\");\n if (\n /Authentication required.*log in to Zephyr/i.test(text) ||\n /auth\\.zephyr-cloud\\.io\\/authorize/.test(text)\n ) {\n zephyrAuthShown = true;\n const urlMatch = text.match(/https:\\/\\/auth\\.zephyr-cloud\\.io\\/authorize\\S+/);\n console.log();\n console.log(colors.yellow(` ⚠ Zephyr authentication required for ${wsKey}`));\n if (urlMatch) {\n console.log(` ${colors.cyan(urlMatch[0])}`);\n }\n console.log(colors.dim(\" Waiting for authentication...\"));\n console.log();\n }\n },\n });\n const stdout = result?.stdout ?? \"\";\n const stderr = result?.stderr ?? \"\";\n const exitCode = result?.exitCode ?? 0;\n const output = `${stdout}\\n${stderr}`;\n\n const deployEntries = parseDeployLines(output);\n\n if (deployEntries.length > 0) {\n if (exitCode !== 0) {\n const errorLines = output\n .split(\"\\n\")\n .filter((line) => /\\bERROR\\b/.test(line) || line.startsWith(\"Rspack compiled with\"))\n .slice(0, 5);\n if (errorLines.length > 0 && !verbose) {\n console.log(\n ` ${colors.yellow(\"⚠\")} Build completed with errors (exit code ${exitCode}) — Zephyr deployed successfully`,\n );\n for (const line of errorLines) {\n console.log(` ${colors.dim(line.trim())}`);\n }\n }\n }\n return { success: true, url: deployEntries[0]?.url, exitCode: 0, output, deployEntries };\n }\n\n if (exitCode !== 0) {\n const lastLines = output.trim().split(\"\\n\").slice(-5).join(\"\\n\");\n return {\n success: false,\n error: `Build failed (exit code ${exitCode})\\n${lastLines}`,\n exitCode,\n output,\n };\n }\n\n const zeMatch = output.match(/ZE\\d+/);\n if (zeMatch) {\n return {\n success: false,\n error: `Zephyr upload failed (${zeMatch[0]})`,\n exitCode: 0,\n output,\n };\n }\n\n const deployMatch = output.match(/🚀.*Deployed:\\s*(https?:\\S+)/);\n if (deployMatch) {\n return { success: true, url: deployMatch[1], exitCode: 0, output };\n }\n\n if (env.DEPLOY === \"true\") {\n return {\n success: false,\n error: \"No deploy URL found (Zephyr may have failed)\",\n exitCode: 0,\n output,\n };\n }\n return { success: true, exitCode: 0, output };\n}\n\ninterface InternalWorkspaceResult extends WorkspaceDeployResult {\n deployEntries?: DeployResultEntry[];\n}\n\nasync function buildOneWorkspace(\n ws: WorkspaceTarget,\n env: Record<string, string>,\n opts: { deploy: boolean; verbose?: boolean },\n): Promise<InternalWorkspaceResult> {\n const pkgJson = await readJsonFile<{\n scripts?: Record<string, string>;\n }>(`${ws.path}/package.json`);\n const shouldDeployScript = opts.deploy && pkgJson.scripts?.deploy;\n const buildConfig = shouldDeployScript\n ? { cmd: \"bun\", args: [\"run\", \"deploy\"] }\n : (buildCommands[ws.key] ?? { cmd: \"bun\", args: [\"run\", \"build\"] });\n\n const wsEnv = { ...env };\n\n const startTime = Date.now();\n let attempt = await runBuildAttempt(\n buildConfig.cmd,\n buildConfig.args,\n ws.path,\n wsEnv,\n opts.verbose ?? false,\n ws.key,\n );\n\n let retried = false;\n\n if (!attempt.success && attempt.exitCode === 0 && opts.deploy) {\n if (!opts.verbose) {\n console.log(` ${colors.yellow(\"↻\")} ${padRight(ws.key, 28)} retrying...`);\n }\n retried = true;\n attempt = await runBuildAttempt(\n buildConfig.cmd,\n buildConfig.args,\n ws.path,\n wsEnv,\n opts.verbose ?? false,\n ws.key,\n );\n }\n\n const durationMs = Date.now() - startTime;\n const result: InternalWorkspaceResult = {\n key: ws.key,\n kind: ws.kind,\n success: attempt.success,\n url: attempt.url,\n error: attempt.error,\n deployEntries: attempt.deployEntries,\n durationMs,\n retried: retried ? true : undefined,\n };\n\n if (!opts.verbose) {\n const name = padRight(ws.key, 28);\n if (result.success) {\n const duration = formatDuration(durationMs);\n const retryTag = retried ? \" (retried)\" : \"\";\n console.log(` ${colors.green(icons.ok)} ${name} ${colors.dim(duration + retryTag)}`);\n } else {\n const errorLine = (result.error ?? \"Failed\").split(\"\\n\")[0];\n console.log(` ${colors.error(icons.err)} ${name} ${errorLine}`);\n }\n }\n\n return result;\n}\n\nexport async function buildWorkspaceTargets(opts: {\n configDir: string;\n bosConfig: BosConfig | null;\n runtimeConfig: RuntimeConfig | null;\n targets: string[];\n deploy: boolean;\n verbose?: boolean;\n}): Promise<{\n built: string[];\n skipped: string[];\n deployResults?: WorkspaceDeployResult[];\n}> {\n const existing: WorkspaceTarget[] = [];\n const skipped: string[] = [];\n\n for (const target of opts.targets) {\n const resolved = resolveWorkspaceTarget(\n target,\n opts.bosConfig,\n opts.runtimeConfig,\n opts.configDir,\n );\n if (!resolved) {\n skipped.push(target);\n continue;\n }\n\n const exists = await fileExists(`${resolved.path}/package.json`);\n if (exists) existing.push(resolved);\n else skipped.push(target);\n }\n\n if (existing.length === 0) {\n return { built: [], skipped };\n }\n\n const sharedSync = await syncResolvedSharedDeps({\n configDir: opts.configDir,\n hostMode: \"local\",\n bosConfig: opts.bosConfig ?? undefined,\n extendsChain: [],\n });\n if (sharedSync.catalogChanged) {\n await run(\"bun\", [\"install\"], { cwd: opts.configDir });\n }\n\n const shouldBuildPlugin = existing.some((entry) => entry.key === \"api\");\n\n const forceRebuild = opts.deploy;\n const buildTasks: Promise<void>[] = [buildEverythingDevQuietly(opts.configDir, forceRebuild)];\n if (shouldBuildPlugin) {\n buildTasks.push(buildEveryPluginQuietly(opts.configDir, forceRebuild));\n }\n await Promise.all(buildTasks);\n\n const env: Record<string, string> = {\n ...process.env,\n NODE_ENV: opts.deploy ? \"production\" : \"development\",\n };\n if (opts.deploy) {\n env.DEPLOY = \"true\";\n } else {\n delete env.DEPLOY;\n }\n\n const bosConfigPath = join(opts.configDir, \"bos.config.json\");\n let configSnapshot: string | undefined;\n if (opts.deploy && existsSync(bosConfigPath)) {\n configSnapshot = readFileSync(bosConfigPath, \"utf-8\");\n }\n\n const orderedExisting = opts.deploy\n ? [\n ...existing.filter((entry) => entry.kind === \"app\" && entry.key !== \"host\"),\n ...existing.filter((entry) => entry.kind === \"plugin\"),\n ...existing.filter((entry) => entry.kind === \"app\" && entry.key === \"host\"),\n ]\n : existing;\n\n const parallelGroup = opts.deploy\n ? orderedExisting.filter((e) => e.key !== \"host\")\n : orderedExisting;\n const sequentialGroup = opts.deploy ? orderedExisting.filter((e) => e.key === \"host\") : [];\n\n const built: string[] = [];\n const deployResults: WorkspaceDeployResult[] = [];\n\n if (opts.deploy && parallelGroup.length > 0) {\n const total = parallelGroup.length + sequentialGroup.length;\n console.log();\n console.log(` Building ${total} workspace${total > 1 ? \"s\" : \"\"}...`);\n console.log();\n\n const results = await Promise.allSettled(\n parallelGroup.map((ws) => buildOneWorkspace(ws, env, opts)),\n );\n\n const allDeployEntries: DeployResultEntry[] = [];\n for (let i = 0; i < parallelGroup.length; i++) {\n const ws = parallelGroup[i];\n const result = results[i];\n if (result.status === \"fulfilled\") {\n if (result.value.success) {\n built.push(ws.key);\n }\n if (result.value.deployEntries) {\n allDeployEntries.push(...result.value.deployEntries);\n }\n const { deployEntries: _deployEntries, ...deployResult } = result.value;\n deployResults.push(deployResult);\n } else {\n deployResults.push({\n key: ws.key,\n kind: ws.kind,\n success: false,\n error: result.reason?.message ?? \"Unknown error\",\n });\n }\n }\n\n if (configSnapshot && allDeployEntries.length > 0) {\n const config = JSON.parse(configSnapshot) as Record<string, unknown>;\n const merged = applyDeployResults(config, allDeployEntries);\n writeFileSync(bosConfigPath, `${JSON.stringify(merged, null, 2)}\\n`);\n }\n\n for (const ws of sequentialGroup) {\n const result = await buildOneWorkspace(ws, env, opts);\n if (result.success) {\n built.push(ws.key);\n }\n if (result.deployEntries) {\n const hostEntries = result.deployEntries.filter((r) => r.urlField.startsWith(\"app.host\"));\n if (hostEntries.length > 0 && existsSync(bosConfigPath)) {\n const currentConfig = JSON.parse(readFileSync(bosConfigPath, \"utf-8\")) as Record<\n string,\n unknown\n >;\n const merged = applyDeployResults(currentConfig, hostEntries);\n writeFileSync(bosConfigPath, `${JSON.stringify(merged, null, 2)}\\n`);\n }\n }\n const { deployEntries: _deployEntries, ...sequentialResult } = result;\n deployResults.push(sequentialResult);\n }\n\n console.log();\n } else {\n for (const resolved of orderedExisting) {\n const buildConfig = buildCommands[resolved.key] ?? {\n cmd: \"bun\",\n args: [\"run\", \"build\"],\n };\n\n await run(buildConfig.cmd, buildConfig.args, {\n cwd: resolved.path,\n env,\n });\n built.push(resolved.key);\n }\n }\n\n return { built, skipped, deployResults: opts.deploy ? deployResults : undefined };\n}\n\nexport async function buildEveryPluginQuietly(cwd: string, force = false) {\n const packageDir = `${cwd}/packages/every-plugin`;\n const packageExists = await fileExists(`${packageDir}/package.json`);\n if (!packageExists) {\n return;\n }\n\n const distPath = `${cwd}/packages/every-plugin/dist/build/rspack/plugin.mjs`;\n const distExists = await fileExists(distPath);\n\n if (distExists && !force) {\n return;\n }\n\n const result = (await run(\"bun\", [\"run\", \"--cwd\", \"packages/every-plugin\", \"build\"], {\n cwd,\n capture: true,\n })) as { stdout: string; stderr: string; exitCode: number };\n\n if (result.exitCode === 0) {\n return;\n }\n\n if (result.stdout.trim()) {\n process.stdout.write(result.stdout);\n }\n\n if (result.stderr.trim()) {\n process.stderr.write(result.stderr);\n }\n\n throw new Error(\n `bun run --cwd packages/every-plugin build failed with exit code ${result.exitCode}`,\n );\n}\n\nexport async function buildEverythingDevQuietly(cwd: string, force = false) {\n const packageDir = `${cwd}/packages/everything-dev`;\n const packageExists = await fileExists(`${packageDir}/package.json`);\n if (!packageExists) {\n return;\n }\n\n const distPath = `${cwd}/packages/everything-dev/dist/index.mjs`;\n const distExists = await fileExists(distPath);\n\n if (distExists && !force) {\n return;\n }\n\n const result = (await run(\"bun\", [\"run\", \"--cwd\", \"packages/everything-dev\", \"build\"], {\n cwd,\n capture: true,\n })) as { stdout: string; stderr: string; exitCode: number };\n\n if (result.exitCode === 0) {\n return;\n }\n\n if (result.stdout.trim()) {\n process.stdout.write(result.stdout);\n }\n\n if (result.stderr.trim()) {\n process.stderr.write(result.stderr);\n }\n\n throw new Error(\n `bun run --cwd packages/everything-dev build failed with exit code ${result.exitCode}`,\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAcA,MAAM,gBAAiE;CACrE,MAAM;EAAE,KAAK;EAAO,MAAM,CAAC,OAAO,QAAQ;EAAE;CAC5C,IAAI;EAAE,KAAK;EAAO,MAAM,CAAC,OAAO,QAAQ;EAAE;CAC1C,KAAK;EAAE,KAAK;EAAO,MAAM,CAAC,OAAO,QAAQ;EAAE;CAC5C;AAQD,SAAgB,aAAa,OAAsE;AACjG,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAO;;AAGT,eAAsB,WAAW,MAAgC;AAC/D,KAAI;AACF,qCAAa,KAAK;AAClB,SAAO;SACD;AACN,SAAO;;;AAIX,eAAsB,aAAgB,MAA0B;AAC9D,QAAO,KAAK,MAAM,qCAAe,MAAM,OAAO,CAAC;;AAGjD,SAAS,uBACP,KACA,WACA,eACA,WACwB;AACxB,KAAI,WAAW,OAAO,OAAO,UAAU,KAAK;EAC1C,MAAM,WAAY,UAAU,IAAiD;EAC7E,MAAM,UAAUA,2CAA4B,UAAU,aAAa,UAAU;AAC7E,MAAI,QACF,QAAO;GACL;GACA,MAAM;GACN,MAAM;GACP;AAEH,SAAO;GACL;GACA,MAAM;GACN,MAAM,GAAG,UAAU,GAAG;GACvB;;CAIH,MAAM,cADgB,eAAe,UAAU,OAE9B,aACfA,2CAA4B,aAAa,WAAW,UAAU,KAAK,EAAE,aAAa,UAAU;AAC9F,KAAI,WACF,QAAO;EACL;EACA,MAAM;EACN,MAAM;EACP;AAGH,QAAO;;AAGT,SAAgB,uBAAuB,UAAkB,WAAuC;CAC9F,MAAM,cAAc,CAClB,GAAG,OAAO,KAAK,WAAW,OAAO,EAAE,CAAC,EACpC,GAAG,OAAO,KAAK,WAAW,WAAW,EAAE,CAAC,CACzC;AACD,KAAI,aAAa,MACf,QAAO;AAGT,QAAO,SACJ,MAAM,IAAI,CACV,KAAK,QAAQ,IAAI,MAAM,CAAC,CACxB,QAAQ,QAAQ,YAAY,SAAS,IAAI,CAAC;;AAY/C,eAAe,gBACb,KACA,MACA,KACA,KACA,SACA,OAC6B;CAC7B,IAAI,kBAAkB;CACtB,MAAM,SAAS,MAAMC,gBAAI,KAAK,MAAM;EAClC;EACA;EACA,SAAS;EACT,UAAU,QAAQ,UAAU;AAC1B,OAAI,QACF,KAAI,WAAW,SAAU,sBAAQ,OAAO,MAAM,MAAM;OAC/C,sBAAQ,OAAO,MAAM,MAAM;AAElC,OAAI,gBAAiB;GACrB,MAAM,OAAO,MAAM,SAAS,QAAQ;AACpC,OACE,6CAA6C,KAAK,KAAK,IACvD,oCAAoC,KAAK,KAAK,EAC9C;AACA,sBAAkB;IAClB,MAAM,WAAW,KAAK,MAAM,iDAAiD;AAC7E,YAAQ,KAAK;AACb,YAAQ,IAAIC,qBAAO,OAAO,0CAA0C,QAAQ,CAAC;AAC7E,QAAI,SACF,SAAQ,IAAI,OAAOA,qBAAO,KAAK,SAAS,GAAG,GAAG;AAEhD,YAAQ,IAAIA,qBAAO,IAAI,oCAAoC,CAAC;AAC5D,YAAQ,KAAK;;;EAGlB,CAAC;CACF,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,WAAW,QAAQ,YAAY;CACrC,MAAM,SAAS,GAAG,OAAO,IAAI;CAE7B,MAAM,gBAAgBC,mCAAiB,OAAO;AAE9C,KAAI,cAAc,SAAS,GAAG;AAC5B,MAAI,aAAa,GAAG;GAClB,MAAM,aAAa,OAChB,MAAM,KAAK,CACX,QAAQ,SAAS,YAAY,KAAK,KAAK,IAAI,KAAK,WAAW,uBAAuB,CAAC,CACnF,MAAM,GAAG,EAAE;AACd,OAAI,WAAW,SAAS,KAAK,CAAC,SAAS;AACrC,YAAQ,IACN,KAAKD,qBAAO,OAAO,IAAI,CAAC,0CAA0C,SAAS,kCAC5E;AACD,SAAK,MAAM,QAAQ,WACjB,SAAQ,IAAI,OAAOA,qBAAO,IAAI,KAAK,MAAM,CAAC,GAAG;;;AAInD,SAAO;GAAE,SAAS;GAAM,KAAK,cAAc,IAAI;GAAK,UAAU;GAAG;GAAQ;GAAe;;AAG1F,KAAI,aAAa,EAEf,QAAO;EACL,SAAS;EACT,OAAO,2BAA2B,SAAS,KAH3B,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,MAAM,GAAG,CAAC,KAAK,KAGA;EACzD;EACA;EACD;CAGH,MAAM,UAAU,OAAO,MAAM,QAAQ;AACrC,KAAI,QACF,QAAO;EACL,SAAS;EACT,OAAO,yBAAyB,QAAQ,GAAG;EAC3C,UAAU;EACV;EACD;CAGH,MAAM,cAAc,OAAO,MAAM,+BAA+B;AAChE,KAAI,YACF,QAAO;EAAE,SAAS;EAAM,KAAK,YAAY;EAAI,UAAU;EAAG;EAAQ;AAGpE,KAAI,IAAI,WAAW,OACjB,QAAO;EACL,SAAS;EACT,OAAO;EACP,UAAU;EACV;EACD;AAEH,QAAO;EAAE,SAAS;EAAM,UAAU;EAAG;EAAQ;;AAO/C,eAAe,kBACb,IACA,KACA,MACkC;CAClC,MAAM,UAAU,MAAM,aAEnB,GAAG,GAAG,KAAK,eAAe;CAE7B,MAAM,cADqB,KAAK,UAAU,QAAQ,SAAS,SAEvD;EAAE,KAAK;EAAO,MAAM,CAAC,OAAO,SAAS;EAAE,GACtC,cAAc,GAAG,QAAQ;EAAE,KAAK;EAAO,MAAM,CAAC,OAAO,QAAQ;EAAE;CAEpE,MAAM,QAAQ,EAAE,GAAG,KAAK;CAExB,MAAM,YAAY,KAAK,KAAK;CAC5B,IAAI,UAAU,MAAM,gBAClB,YAAY,KACZ,YAAY,MACZ,GAAG,MACH,OACA,KAAK,WAAW,OAChB,GAAG,IACJ;CAED,IAAI,UAAU;AAEd,KAAI,CAAC,QAAQ,WAAW,QAAQ,aAAa,KAAK,KAAK,QAAQ;AAC7D,MAAI,CAAC,KAAK,QACR,SAAQ,IAAI,KAAKA,qBAAO,OAAO,IAAI,CAAC,GAAGE,wBAAS,GAAG,KAAK,GAAG,CAAC,cAAc;AAE5E,YAAU;AACV,YAAU,MAAM,gBACd,YAAY,KACZ,YAAY,MACZ,GAAG,MACH,OACA,KAAK,WAAW,OAChB,GAAG,IACJ;;CAGH,MAAM,aAAa,KAAK,KAAK,GAAG;CAChC,MAAM,SAAkC;EACtC,KAAK,GAAG;EACR,MAAM,GAAG;EACT,SAAS,QAAQ;EACjB,KAAK,QAAQ;EACb,OAAO,QAAQ;EACf,eAAe,QAAQ;EACvB;EACA,SAAS,UAAU,OAAO;EAC3B;AAED,KAAI,CAAC,KAAK,SAAS;EACjB,MAAM,OAAOA,wBAAS,GAAG,KAAK,GAAG;AACjC,MAAI,OAAO,SAAS;GAClB,MAAM,WAAWC,8BAAe,WAAW;GAC3C,MAAM,WAAW,UAAU,eAAe;AAC1C,WAAQ,IAAI,KAAKH,qBAAO,MAAMI,oBAAM,GAAG,CAAC,GAAG,KAAK,GAAGJ,qBAAO,IAAI,WAAW,SAAS,GAAG;SAChF;GACL,MAAM,aAAa,OAAO,SAAS,UAAU,MAAM,KAAK,CAAC;AACzD,WAAQ,IAAI,KAAKA,qBAAO,MAAMI,oBAAM,IAAI,CAAC,GAAG,KAAK,GAAG,YAAY;;;AAIpE,QAAO;;AAGT,eAAsB,sBAAsB,MAWzC;CACD,MAAM,WAA8B,EAAE;CACtC,MAAM,UAAoB,EAAE;AAE5B,MAAK,MAAM,UAAU,KAAK,SAAS;EACjC,MAAM,WAAW,uBACf,QACA,KAAK,WACL,KAAK,eACL,KAAK,UACN;AACD,MAAI,CAAC,UAAU;AACb,WAAQ,KAAK,OAAO;AACpB;;AAIF,MAAI,MADiB,WAAW,GAAG,SAAS,KAAK,eAAe,CACpD,UAAS,KAAK,SAAS;MAC9B,SAAQ,KAAK,OAAO;;AAG3B,KAAI,SAAS,WAAW,EACtB,QAAO;EAAE,OAAO,EAAE;EAAE;EAAS;AAS/B,MAAI,MANqBC,2CAAuB;EAC9C,WAAW,KAAK;EAChB,UAAU;EACV,WAAW,KAAK,aAAa;EAC7B,cAAc,EAAE;EACjB,CAAC,EACa,eACb,OAAMN,gBAAI,OAAO,CAAC,UAAU,EAAE,EAAE,KAAK,KAAK,WAAW,CAAC;CAGxD,MAAM,oBAAoB,SAAS,MAAM,UAAU,MAAM,QAAQ,MAAM;CAEvE,MAAM,eAAe,KAAK;CAC1B,MAAM,aAA8B,CAAC,0BAA0B,KAAK,WAAW,aAAa,CAAC;AAC7F,KAAI,kBACF,YAAW,KAAK,wBAAwB,KAAK,WAAW,aAAa,CAAC;AAExE,OAAM,QAAQ,IAAI,WAAW;CAE7B,MAAM,MAA8B;EAClC,GAAGO,qBAAQ;EACX,UAAU,KAAK,SAAS,eAAe;EACxC;AACD,KAAI,KAAK,OACP,KAAI,SAAS;KAEb,QAAO,IAAI;CAGb,MAAM,oCAAqB,KAAK,WAAW,kBAAkB;CAC7D,IAAI;AACJ,KAAI,KAAK,kCAAqB,cAAc,CAC1C,4CAA8B,eAAe,QAAQ;CAGvD,MAAM,kBAAkB,KAAK,SACzB;EACE,GAAG,SAAS,QAAQ,UAAU,MAAM,SAAS,SAAS,MAAM,QAAQ,OAAO;EAC3E,GAAG,SAAS,QAAQ,UAAU,MAAM,SAAS,SAAS;EACtD,GAAG,SAAS,QAAQ,UAAU,MAAM,SAAS,SAAS,MAAM,QAAQ,OAAO;EAC5E,GACD;CAEJ,MAAM,gBAAgB,KAAK,SACvB,gBAAgB,QAAQ,MAAM,EAAE,QAAQ,OAAO,GAC/C;CACJ,MAAM,kBAAkB,KAAK,SAAS,gBAAgB,QAAQ,MAAM,EAAE,QAAQ,OAAO,GAAG,EAAE;CAE1F,MAAM,QAAkB,EAAE;CAC1B,MAAM,gBAAyC,EAAE;AAEjD,KAAI,KAAK,UAAU,cAAc,SAAS,GAAG;EAC3C,MAAM,QAAQ,cAAc,SAAS,gBAAgB;AACrD,UAAQ,KAAK;AACb,UAAQ,IAAI,cAAc,MAAM,YAAY,QAAQ,IAAI,MAAM,GAAG,KAAK;AACtE,UAAQ,KAAK;EAEb,MAAM,UAAU,MAAM,QAAQ,WAC5B,cAAc,KAAK,OAAO,kBAAkB,IAAI,KAAK,KAAK,CAAC,CAC5D;EAED,MAAM,mBAAwC,EAAE;AAChD,OAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;GAC7C,MAAM,KAAK,cAAc;GACzB,MAAM,SAAS,QAAQ;AACvB,OAAI,OAAO,WAAW,aAAa;AACjC,QAAI,OAAO,MAAM,QACf,OAAM,KAAK,GAAG,IAAI;AAEpB,QAAI,OAAO,MAAM,cACf,kBAAiB,KAAK,GAAG,OAAO,MAAM,cAAc;IAEtD,MAAM,EAAE,eAAe,gBAAgB,GAAG,iBAAiB,OAAO;AAClE,kBAAc,KAAK,aAAa;SAEhC,eAAc,KAAK;IACjB,KAAK,GAAG;IACR,MAAM,GAAG;IACT,SAAS;IACT,OAAO,OAAO,QAAQ,WAAW;IAClC,CAAC;;AAIN,MAAI,kBAAkB,iBAAiB,SAAS,GAAG;GAEjD,MAAM,SAASC,qCADA,KAAK,MAAM,eACc,EAAE,iBAAiB;AAC3D,8BAAc,eAAe,GAAG,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC,IAAI;;AAGtE,OAAK,MAAM,MAAM,iBAAiB;GAChC,MAAM,SAAS,MAAM,kBAAkB,IAAI,KAAK,KAAK;AACrD,OAAI,OAAO,QACT,OAAM,KAAK,GAAG,IAAI;AAEpB,OAAI,OAAO,eAAe;IACxB,MAAM,cAAc,OAAO,cAAc,QAAQ,MAAM,EAAE,SAAS,WAAW,WAAW,CAAC;AACzF,QAAI,YAAY,SAAS,6BAAgB,cAAc,EAAE;KAKvD,MAAM,SAASA,qCAJO,KAAK,gCAAmB,eAAe,QAAQ,CAItB,EAAE,YAAY;AAC7D,gCAAc,eAAe,GAAG,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC,IAAI;;;GAGxE,MAAM,EAAE,eAAe,gBAAgB,GAAG,qBAAqB;AAC/D,iBAAc,KAAK,iBAAiB;;AAGtC,UAAQ,KAAK;OAEb,MAAK,MAAM,YAAY,iBAAiB;EACtC,MAAM,cAAc,cAAc,SAAS,QAAQ;GACjD,KAAK;GACL,MAAM,CAAC,OAAO,QAAQ;GACvB;AAED,QAAMR,gBAAI,YAAY,KAAK,YAAY,MAAM;GAC3C,KAAK,SAAS;GACd;GACD,CAAC;AACF,QAAM,KAAK,SAAS,IAAI;;AAI5B,QAAO;EAAE;EAAO;EAAS,eAAe,KAAK,SAAS,gBAAgB;EAAW;;AAGnF,eAAsB,wBAAwB,KAAa,QAAQ,OAAO;AAGxE,KAAI,CAAC,MADuB,WAAW,GAAG,GADpB,IAAI,wBAC2B,eAAe,CAElE;AAMF,KAAI,MAFqB,WAAW,GADhB,IAAI,qDACqB,IAE3B,CAAC,MACjB;CAGF,MAAM,SAAU,MAAMA,gBAAI,OAAO;EAAC;EAAO;EAAS;EAAyB;EAAQ,EAAE;EACnF;EACA,SAAS;EACV,CAAC;AAEF,KAAI,OAAO,aAAa,EACtB;AAGF,KAAI,OAAO,OAAO,MAAM,CACtB,sBAAQ,OAAO,MAAM,OAAO,OAAO;AAGrC,KAAI,OAAO,OAAO,MAAM,CACtB,sBAAQ,OAAO,MAAM,OAAO,OAAO;AAGrC,OAAM,IAAI,MACR,mEAAmE,OAAO,WAC3E;;AAGH,eAAsB,0BAA0B,KAAa,QAAQ,OAAO;AAG1E,KAAI,CAAC,MADuB,WAAW,GAAG,GADpB,IAAI,0BAC2B,eAAe,CAElE;AAMF,KAAI,MAFqB,WAAW,GADhB,IAAI,yCACqB,IAE3B,CAAC,MACjB;CAGF,MAAM,SAAU,MAAMA,gBAAI,OAAO;EAAC;EAAO;EAAS;EAA2B;EAAQ,EAAE;EACrF;EACA,SAAS;EACV,CAAC;AAEF,KAAI,OAAO,aAAa,EACtB;AAGF,KAAI,OAAO,OAAO,MAAM,CACtB,sBAAQ,OAAO,MAAM,OAAO,OAAO;AAGrC,KAAI,OAAO,OAAO,MAAM,CACtB,sBAAQ,OAAO,MAAM,OAAO,OAAO;AAGrC,OAAM,IAAI,MACR,qEAAqE,OAAO,WAC7E"}
1
+ {"version":3,"file":"build.cjs","names":["resolveLocalDevelopmentPath","run","colors","parseDeployLines","padRight","formatDuration","icons","syncResolvedSharedDeps","process","applyDeployResults"],"sources":["../src/build.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { access, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport { formatDuration } from \"./cli/timing\";\nimport { resolveLocalDevelopmentPath } from \"./config\";\nimport type { WorkspaceDeployResult } from \"./contract\";\nimport { applyDeployResults, type DeployResultEntry, parseDeployLines } from \"./integrity\";\nimport { syncResolvedSharedDeps } from \"./shared-deps\";\nimport type { BosConfig, BosPluginRef, RuntimeConfig } from \"./types\";\nimport { run } from \"./utils/run\";\nimport { padRight } from \"./utils/string\";\nimport { colors, icons } from \"./utils/theme\";\n\nconst buildCommands: Record<string, { cmd: string; args: string[] }> = {\n host: { cmd: \"bun\", args: [\"run\", \"build\"] },\n ui: { cmd: \"bun\", args: [\"run\", \"build\"] },\n api: { cmd: \"bun\", args: [\"run\", \"build\"] },\n};\n\ntype WorkspaceTarget = {\n key: string;\n kind: \"app\" | \"plugin\";\n path: string;\n};\n\nexport function getPluginRef(entry: string | BosPluginRef | undefined | null): BosPluginRef | null {\n if (!entry || typeof entry === \"string\") return null;\n return entry;\n}\n\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readJsonFile<T>(path: string): Promise<T> {\n return JSON.parse(await readFile(path, \"utf8\")) as T;\n}\n\nfunction resolveWorkspaceTarget(\n key: string,\n bosConfig: BosConfig | null,\n runtimeConfig: RuntimeConfig | null,\n configDir: string,\n): WorkspaceTarget | null {\n if (bosConfig?.app && key in bosConfig.app) {\n const appEntry = (bosConfig.app as Record<string, { development?: string }>)[key];\n const devPath = resolveLocalDevelopmentPath(appEntry?.development, configDir);\n if (devPath) {\n return {\n key,\n kind: \"app\",\n path: devPath,\n };\n }\n return {\n key,\n kind: \"app\",\n path: `${configDir}/${key}`,\n };\n }\n\n const runtimePlugin = runtimeConfig?.plugins?.[key];\n const pluginPath =\n runtimePlugin?.localPath ??\n resolveLocalDevelopmentPath(getPluginRef(bosConfig?.plugins?.[key])?.development, configDir);\n if (pluginPath) {\n return {\n key,\n kind: \"plugin\",\n path: pluginPath,\n };\n }\n\n return null;\n}\n\nexport function selectWorkspaceTargets(packages: string, bosConfig: BosConfig | null): string[] {\n const allPackages = [\n ...Object.keys(bosConfig?.app ?? {}),\n ...Object.keys(bosConfig?.plugins ?? {}),\n ];\n if (packages === \"all\") {\n return allPackages;\n }\n\n return packages\n .split(\",\")\n .map((pkg) => pkg.trim())\n .filter((pkg) => allPackages.includes(pkg));\n}\n\ninterface BuildAttemptResult {\n success: boolean;\n url?: string;\n error?: string;\n warnings?: string[];\n exitCode: number;\n output: string;\n deployEntries?: DeployResultEntry[];\n}\n\nasync function runBuildAttempt(\n cmd: string,\n args: string[],\n cwd: string,\n env: Record<string, string>,\n verbose: boolean,\n wsKey: string,\n): Promise<BuildAttemptResult> {\n let zephyrAuthShown = false;\n const result = await run(cmd, args, {\n cwd,\n env,\n capture: true,\n onChunk: (stream, chunk) => {\n if (verbose) {\n if (stream === \"stdout\") process.stdout.write(chunk);\n else process.stderr.write(chunk);\n }\n if (zephyrAuthShown) return;\n const text = chunk.toString(\"utf-8\");\n if (\n /Authentication required.*log in to Zephyr/i.test(text) ||\n /auth\\.zephyr-cloud\\.io\\/authorize/.test(text)\n ) {\n zephyrAuthShown = true;\n const urlMatch = text.match(/https:\\/\\/auth\\.zephyr-cloud\\.io\\/authorize\\S+/);\n console.log();\n console.log(colors.yellow(` ⚠ Zephyr authentication required for ${wsKey}`));\n if (urlMatch) {\n console.log(` ${colors.cyan(urlMatch[0])}`);\n }\n console.log(colors.dim(\" Waiting for authentication...\"));\n console.log();\n }\n },\n });\n const stdout = result?.stdout ?? \"\";\n const stderr = result?.stderr ?? \"\";\n const exitCode = result?.exitCode ?? 0;\n const output = `${stdout}\\n${stderr}`;\n\n const deployEntries = parseDeployLines(output);\n\n if (deployEntries.length > 0) {\n const result: BuildAttemptResult = {\n success: true,\n url: deployEntries[0]?.url,\n exitCode: 0,\n output,\n deployEntries,\n };\n if (exitCode !== 0) {\n const errorLines = output\n .split(\"\\n\")\n .filter((line) => /\\bERROR\\b/.test(line) || line.startsWith(\"Rspack compiled with\"))\n .slice(0, 5);\n if (errorLines.length > 0) {\n result.warnings = errorLines.map((l) => l.trim());\n if (!verbose) {\n console.log(\n ` ${colors.yellow(\"⚠\")} Build completed with errors (exit code ${exitCode}) — Zephyr deployed successfully`,\n );\n for (const line of errorLines) {\n console.log(` ${colors.dim(line.trim())}`);\n }\n }\n }\n }\n return result;\n }\n\n if (exitCode !== 0) {\n const lastLines = output.trim().split(\"\\n\").slice(-5).join(\"\\n\");\n return {\n success: false,\n error: `Build failed (exit code ${exitCode})\\n${lastLines}`,\n exitCode,\n output,\n };\n }\n\n const deployMatch = output.match(/🚀.*Deployed:\\s*(https?:\\S+)/);\n if (deployMatch) {\n return { success: true, url: deployMatch[1], exitCode: 0, output };\n }\n\n const zeMatch = output.match(/ZE\\d{4,}/);\n if (zeMatch) {\n return {\n success: false,\n error: `Zephyr upload failed (${zeMatch[0]})`,\n exitCode: 0,\n output,\n };\n }\n\n if (env.DEPLOY === \"true\") {\n return {\n success: false,\n error: \"No deploy URL found (Zephyr may have failed)\",\n exitCode: 0,\n output,\n };\n }\n return { success: true, exitCode: 0, output };\n}\n\ninterface InternalWorkspaceResult extends WorkspaceDeployResult {\n deployEntries?: DeployResultEntry[];\n}\n\nasync function buildOneWorkspace(\n ws: WorkspaceTarget,\n env: Record<string, string>,\n opts: { deploy: boolean; verbose?: boolean },\n): Promise<InternalWorkspaceResult> {\n const pkgJson = await readJsonFile<{\n scripts?: Record<string, string>;\n }>(`${ws.path}/package.json`);\n const shouldDeployScript = opts.deploy && pkgJson.scripts?.deploy;\n const buildConfig = shouldDeployScript\n ? { cmd: \"bun\", args: [\"run\", \"deploy\"] }\n : (buildCommands[ws.key] ?? { cmd: \"bun\", args: [\"run\", \"build\"] });\n\n const wsEnv = { ...env };\n\n const startTime = Date.now();\n let attempt = await runBuildAttempt(\n buildConfig.cmd,\n buildConfig.args,\n ws.path,\n wsEnv,\n opts.verbose ?? false,\n ws.key,\n );\n\n let retried = false;\n const firstAttempt: BuildAttemptResult | undefined = attempt.success ? undefined : { ...attempt };\n\n if (!attempt.success && attempt.exitCode === 0 && opts.deploy) {\n if (!opts.verbose) {\n console.log(` ${colors.yellow(\"↻\")} ${padRight(ws.key, 28)} retrying...`);\n }\n retried = true;\n attempt = await runBuildAttempt(\n buildConfig.cmd,\n buildConfig.args,\n ws.path,\n wsEnv,\n opts.verbose ?? false,\n ws.key,\n );\n\n if (!attempt.success && firstAttempt) {\n attempt.error = `First attempt: ${firstAttempt.error}\\nRetry: ${attempt.error}`;\n }\n }\n\n const durationMs = Date.now() - startTime;\n const result: InternalWorkspaceResult = {\n key: ws.key,\n kind: ws.kind,\n success: attempt.success,\n url: attempt.url,\n error: attempt.error,\n warnings: attempt.warnings,\n deployEntries: attempt.deployEntries,\n durationMs,\n retried: retried ? true : undefined,\n };\n\n if (!opts.verbose) {\n const name = padRight(ws.key, 28);\n if (result.success) {\n const duration = formatDuration(durationMs);\n const retryTag = retried ? \" (retried)\" : \"\";\n console.log(` ${colors.green(icons.ok)} ${name} ${colors.dim(duration + retryTag)}`);\n } else {\n const errorLine = (result.error ?? \"Failed\").split(\"\\n\")[0];\n console.log(` ${colors.error(icons.err)} ${name} ${errorLine}`);\n }\n }\n\n return result;\n}\n\nexport async function buildWorkspaceTargets(opts: {\n configDir: string;\n bosConfig: BosConfig | null;\n runtimeConfig: RuntimeConfig | null;\n targets: string[];\n deploy: boolean;\n verbose?: boolean;\n}): Promise<{\n built: string[];\n skipped: string[];\n deployResults?: WorkspaceDeployResult[];\n}> {\n const existing: WorkspaceTarget[] = [];\n const skipped: string[] = [];\n\n for (const target of opts.targets) {\n const resolved = resolveWorkspaceTarget(\n target,\n opts.bosConfig,\n opts.runtimeConfig,\n opts.configDir,\n );\n if (!resolved) {\n skipped.push(target);\n continue;\n }\n\n const exists = await fileExists(`${resolved.path}/package.json`);\n if (exists) existing.push(resolved);\n else skipped.push(target);\n }\n\n if (existing.length === 0) {\n return { built: [], skipped };\n }\n\n const sharedSync = await syncResolvedSharedDeps({\n configDir: opts.configDir,\n hostMode: \"local\",\n bosConfig: opts.bosConfig ?? undefined,\n extendsChain: [],\n });\n if (sharedSync.catalogChanged) {\n await run(\"bun\", [\"install\"], { cwd: opts.configDir });\n }\n\n const shouldBuildPlugin = existing.some((entry) => entry.key === \"api\");\n\n const forceRebuild = opts.deploy;\n const buildTasks: Promise<void>[] = [buildEverythingDevQuietly(opts.configDir, forceRebuild)];\n if (shouldBuildPlugin) {\n buildTasks.push(buildEveryPluginQuietly(opts.configDir, forceRebuild));\n }\n await Promise.all(buildTasks);\n\n const env: Record<string, string> = {\n ...process.env,\n NODE_ENV: opts.deploy ? \"production\" : \"development\",\n };\n if (opts.deploy) {\n env.DEPLOY = \"true\";\n } else {\n delete env.DEPLOY;\n }\n\n const bosConfigPath = join(opts.configDir, \"bos.config.json\");\n let configSnapshot: string | undefined;\n if (opts.deploy && existsSync(bosConfigPath)) {\n configSnapshot = readFileSync(bosConfigPath, \"utf-8\");\n }\n\n const orderedExisting = opts.deploy\n ? [\n ...existing.filter((entry) => entry.kind === \"app\" && entry.key !== \"host\"),\n ...existing.filter((entry) => entry.kind === \"plugin\"),\n ...existing.filter((entry) => entry.kind === \"app\" && entry.key === \"host\"),\n ]\n : existing;\n\n const parallelGroup = opts.deploy\n ? orderedExisting.filter((e) => e.key !== \"host\")\n : orderedExisting;\n const sequentialGroup = opts.deploy ? orderedExisting.filter((e) => e.key === \"host\") : [];\n\n const built: string[] = [];\n const deployResults: WorkspaceDeployResult[] = [];\n\n if (opts.deploy && parallelGroup.length > 0) {\n const total = parallelGroup.length + sequentialGroup.length;\n console.log();\n console.log(` Building ${total} workspace${total > 1 ? \"s\" : \"\"}...`);\n console.log();\n\n const results = await Promise.allSettled(\n parallelGroup.map((ws) => buildOneWorkspace(ws, env, opts)),\n );\n\n const allDeployEntries: DeployResultEntry[] = [];\n for (let i = 0; i < parallelGroup.length; i++) {\n const ws = parallelGroup[i];\n const result = results[i];\n if (result.status === \"fulfilled\") {\n if (result.value.success) {\n built.push(ws.key);\n }\n if (result.value.deployEntries) {\n allDeployEntries.push(...result.value.deployEntries);\n }\n const { deployEntries: _deployEntries, ...deployResult } = result.value;\n deployResults.push(deployResult);\n } else {\n deployResults.push({\n key: ws.key,\n kind: ws.kind,\n success: false,\n error: result.reason?.message ?? \"Unknown error\",\n });\n }\n }\n\n if (configSnapshot && allDeployEntries.length > 0) {\n const config = JSON.parse(configSnapshot) as Record<string, unknown>;\n const merged = applyDeployResults(config, allDeployEntries);\n writeFileSync(bosConfigPath, `${JSON.stringify(merged, null, 2)}\\n`);\n }\n\n for (const ws of sequentialGroup) {\n const result = await buildOneWorkspace(ws, env, opts);\n if (result.success) {\n built.push(ws.key);\n }\n if (result.deployEntries) {\n const hostEntries = result.deployEntries.filter((r) => r.urlField.startsWith(\"app.host\"));\n if (hostEntries.length > 0 && existsSync(bosConfigPath)) {\n const currentConfig = JSON.parse(readFileSync(bosConfigPath, \"utf-8\")) as Record<\n string,\n unknown\n >;\n const merged = applyDeployResults(currentConfig, hostEntries);\n writeFileSync(bosConfigPath, `${JSON.stringify(merged, null, 2)}\\n`);\n }\n }\n const { deployEntries: _deployEntries, ...sequentialResult } = result;\n deployResults.push(sequentialResult);\n }\n\n console.log();\n } else {\n for (const resolved of orderedExisting) {\n const buildConfig = buildCommands[resolved.key] ?? {\n cmd: \"bun\",\n args: [\"run\", \"build\"],\n };\n\n await run(buildConfig.cmd, buildConfig.args, {\n cwd: resolved.path,\n env,\n });\n built.push(resolved.key);\n }\n }\n\n return { built, skipped, deployResults: opts.deploy ? deployResults : undefined };\n}\n\nexport async function buildEveryPluginQuietly(cwd: string, force = false) {\n const packageDir = `${cwd}/packages/every-plugin`;\n const packageExists = await fileExists(`${packageDir}/package.json`);\n if (!packageExists) {\n return;\n }\n\n const distPath = `${cwd}/packages/every-plugin/dist/build/rspack/plugin.mjs`;\n const distExists = await fileExists(distPath);\n\n if (distExists && !force) {\n return;\n }\n\n const result = (await run(\"bun\", [\"run\", \"--cwd\", \"packages/every-plugin\", \"build\"], {\n cwd,\n capture: true,\n })) as { stdout: string; stderr: string; exitCode: number };\n\n if (result.exitCode === 0) {\n return;\n }\n\n if (result.stdout.trim()) {\n process.stdout.write(result.stdout);\n }\n\n if (result.stderr.trim()) {\n process.stderr.write(result.stderr);\n }\n\n throw new Error(\n `bun run --cwd packages/every-plugin build failed with exit code ${result.exitCode}`,\n );\n}\n\nexport async function buildEverythingDevQuietly(cwd: string, force = false) {\n const packageDir = `${cwd}/packages/everything-dev`;\n const packageExists = await fileExists(`${packageDir}/package.json`);\n if (!packageExists) {\n return;\n }\n\n const distPath = `${cwd}/packages/everything-dev/dist/index.mjs`;\n const distExists = await fileExists(distPath);\n\n if (distExists && !force) {\n return;\n }\n\n const result = (await run(\"bun\", [\"run\", \"--cwd\", \"packages/everything-dev\", \"build\"], {\n cwd,\n capture: true,\n })) as { stdout: string; stderr: string; exitCode: number };\n\n if (result.exitCode === 0) {\n return;\n }\n\n if (result.stdout.trim()) {\n process.stdout.write(result.stdout);\n }\n\n if (result.stderr.trim()) {\n process.stderr.write(result.stderr);\n }\n\n throw new Error(\n `bun run --cwd packages/everything-dev build failed with exit code ${result.exitCode}`,\n );\n}\n"],"mappings":"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"}
package/dist/build.mjs CHANGED
@@ -96,20 +96,24 @@ async function runBuildAttempt(cmd, args, cwd, env, verbose, wsKey) {
96
96
  const output = `${stdout}\n${stderr}`;
97
97
  const deployEntries = parseDeployLines(output);
98
98
  if (deployEntries.length > 0) {
99
- if (exitCode !== 0) {
100
- const errorLines = output.split("\n").filter((line) => /\bERROR\b/.test(line) || line.startsWith("Rspack compiled with")).slice(0, 5);
101
- if (errorLines.length > 0 && !verbose) {
102
- console.log(` ${colors.yellow("⚠")} Build completed with errors (exit code ${exitCode}) — Zephyr deployed successfully`);
103
- for (const line of errorLines) console.log(` ${colors.dim(line.trim())}`);
104
- }
105
- }
106
- return {
99
+ const result = {
107
100
  success: true,
108
101
  url: deployEntries[0]?.url,
109
102
  exitCode: 0,
110
103
  output,
111
104
  deployEntries
112
105
  };
106
+ if (exitCode !== 0) {
107
+ const errorLines = output.split("\n").filter((line) => /\bERROR\b/.test(line) || line.startsWith("Rspack compiled with")).slice(0, 5);
108
+ if (errorLines.length > 0) {
109
+ result.warnings = errorLines.map((l) => l.trim());
110
+ if (!verbose) {
111
+ console.log(` ${colors.yellow("⚠")} Build completed with errors (exit code ${exitCode}) — Zephyr deployed successfully`);
112
+ for (const line of errorLines) console.log(` ${colors.dim(line.trim())}`);
113
+ }
114
+ }
115
+ }
116
+ return result;
113
117
  }
114
118
  if (exitCode !== 0) return {
115
119
  success: false,
@@ -117,13 +121,6 @@ async function runBuildAttempt(cmd, args, cwd, env, verbose, wsKey) {
117
121
  exitCode,
118
122
  output
119
123
  };
120
- const zeMatch = output.match(/ZE\d+/);
121
- if (zeMatch) return {
122
- success: false,
123
- error: `Zephyr upload failed (${zeMatch[0]})`,
124
- exitCode: 0,
125
- output
126
- };
127
124
  const deployMatch = output.match(/🚀.*Deployed:\s*(https?:\S+)/);
128
125
  if (deployMatch) return {
129
126
  success: true,
@@ -131,6 +128,13 @@ async function runBuildAttempt(cmd, args, cwd, env, verbose, wsKey) {
131
128
  exitCode: 0,
132
129
  output
133
130
  };
131
+ const zeMatch = output.match(/ZE\d{4,}/);
132
+ if (zeMatch) return {
133
+ success: false,
134
+ error: `Zephyr upload failed (${zeMatch[0]})`,
135
+ exitCode: 0,
136
+ output
137
+ };
134
138
  if (env.DEPLOY === "true") return {
135
139
  success: false,
136
140
  error: "No deploy URL found (Zephyr may have failed)",
@@ -156,10 +160,12 @@ async function buildOneWorkspace(ws, env, opts) {
156
160
  const startTime = Date.now();
157
161
  let attempt = await runBuildAttempt(buildConfig.cmd, buildConfig.args, ws.path, wsEnv, opts.verbose ?? false, ws.key);
158
162
  let retried = false;
163
+ const firstAttempt = attempt.success ? void 0 : { ...attempt };
159
164
  if (!attempt.success && attempt.exitCode === 0 && opts.deploy) {
160
165
  if (!opts.verbose) console.log(` ${colors.yellow("↻")} ${padRight(ws.key, 28)} retrying...`);
161
166
  retried = true;
162
167
  attempt = await runBuildAttempt(buildConfig.cmd, buildConfig.args, ws.path, wsEnv, opts.verbose ?? false, ws.key);
168
+ if (!attempt.success && firstAttempt) attempt.error = `First attempt: ${firstAttempt.error}\nRetry: ${attempt.error}`;
163
169
  }
164
170
  const durationMs = Date.now() - startTime;
165
171
  const result = {
@@ -168,6 +174,7 @@ async function buildOneWorkspace(ws, env, opts) {
168
174
  success: attempt.success,
169
175
  url: attempt.url,
170
176
  error: attempt.error,
177
+ warnings: attempt.warnings,
171
178
  deployEntries: attempt.deployEntries,
172
179
  durationMs,
173
180
  retried: retried ? true : void 0
@@ -1 +1 @@
1
- {"version":3,"file":"build.mjs","names":[],"sources":["../src/build.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { access, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport { formatDuration } from \"./cli/timing\";\nimport { resolveLocalDevelopmentPath } from \"./config\";\nimport type { WorkspaceDeployResult } from \"./contract\";\nimport { applyDeployResults, type DeployResultEntry, parseDeployLines } from \"./integrity\";\nimport { syncResolvedSharedDeps } from \"./shared-deps\";\nimport type { BosConfig, BosPluginRef, RuntimeConfig } from \"./types\";\nimport { run } from \"./utils/run\";\nimport { padRight } from \"./utils/string\";\nimport { colors, icons } from \"./utils/theme\";\n\nconst buildCommands: Record<string, { cmd: string; args: string[] }> = {\n host: { cmd: \"bun\", args: [\"run\", \"build\"] },\n ui: { cmd: \"bun\", args: [\"run\", \"build\"] },\n api: { cmd: \"bun\", args: [\"run\", \"build\"] },\n};\n\ntype WorkspaceTarget = {\n key: string;\n kind: \"app\" | \"plugin\";\n path: string;\n};\n\nexport function getPluginRef(entry: string | BosPluginRef | undefined | null): BosPluginRef | null {\n if (!entry || typeof entry === \"string\") return null;\n return entry;\n}\n\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readJsonFile<T>(path: string): Promise<T> {\n return JSON.parse(await readFile(path, \"utf8\")) as T;\n}\n\nfunction resolveWorkspaceTarget(\n key: string,\n bosConfig: BosConfig | null,\n runtimeConfig: RuntimeConfig | null,\n configDir: string,\n): WorkspaceTarget | null {\n if (bosConfig?.app && key in bosConfig.app) {\n const appEntry = (bosConfig.app as Record<string, { development?: string }>)[key];\n const devPath = resolveLocalDevelopmentPath(appEntry?.development, configDir);\n if (devPath) {\n return {\n key,\n kind: \"app\",\n path: devPath,\n };\n }\n return {\n key,\n kind: \"app\",\n path: `${configDir}/${key}`,\n };\n }\n\n const runtimePlugin = runtimeConfig?.plugins?.[key];\n const pluginPath =\n runtimePlugin?.localPath ??\n resolveLocalDevelopmentPath(getPluginRef(bosConfig?.plugins?.[key])?.development, configDir);\n if (pluginPath) {\n return {\n key,\n kind: \"plugin\",\n path: pluginPath,\n };\n }\n\n return null;\n}\n\nexport function selectWorkspaceTargets(packages: string, bosConfig: BosConfig | null): string[] {\n const allPackages = [\n ...Object.keys(bosConfig?.app ?? {}),\n ...Object.keys(bosConfig?.plugins ?? {}),\n ];\n if (packages === \"all\") {\n return allPackages;\n }\n\n return packages\n .split(\",\")\n .map((pkg) => pkg.trim())\n .filter((pkg) => allPackages.includes(pkg));\n}\n\ninterface BuildAttemptResult {\n success: boolean;\n url?: string;\n error?: string;\n exitCode: number;\n output: string;\n deployEntries?: DeployResultEntry[];\n}\n\nasync function runBuildAttempt(\n cmd: string,\n args: string[],\n cwd: string,\n env: Record<string, string>,\n verbose: boolean,\n wsKey: string,\n): Promise<BuildAttemptResult> {\n let zephyrAuthShown = false;\n const result = await run(cmd, args, {\n cwd,\n env,\n capture: true,\n onChunk: (stream, chunk) => {\n if (verbose) {\n if (stream === \"stdout\") process.stdout.write(chunk);\n else process.stderr.write(chunk);\n }\n if (zephyrAuthShown) return;\n const text = chunk.toString(\"utf-8\");\n if (\n /Authentication required.*log in to Zephyr/i.test(text) ||\n /auth\\.zephyr-cloud\\.io\\/authorize/.test(text)\n ) {\n zephyrAuthShown = true;\n const urlMatch = text.match(/https:\\/\\/auth\\.zephyr-cloud\\.io\\/authorize\\S+/);\n console.log();\n console.log(colors.yellow(` ⚠ Zephyr authentication required for ${wsKey}`));\n if (urlMatch) {\n console.log(` ${colors.cyan(urlMatch[0])}`);\n }\n console.log(colors.dim(\" Waiting for authentication...\"));\n console.log();\n }\n },\n });\n const stdout = result?.stdout ?? \"\";\n const stderr = result?.stderr ?? \"\";\n const exitCode = result?.exitCode ?? 0;\n const output = `${stdout}\\n${stderr}`;\n\n const deployEntries = parseDeployLines(output);\n\n if (deployEntries.length > 0) {\n if (exitCode !== 0) {\n const errorLines = output\n .split(\"\\n\")\n .filter((line) => /\\bERROR\\b/.test(line) || line.startsWith(\"Rspack compiled with\"))\n .slice(0, 5);\n if (errorLines.length > 0 && !verbose) {\n console.log(\n ` ${colors.yellow(\"⚠\")} Build completed with errors (exit code ${exitCode}) — Zephyr deployed successfully`,\n );\n for (const line of errorLines) {\n console.log(` ${colors.dim(line.trim())}`);\n }\n }\n }\n return { success: true, url: deployEntries[0]?.url, exitCode: 0, output, deployEntries };\n }\n\n if (exitCode !== 0) {\n const lastLines = output.trim().split(\"\\n\").slice(-5).join(\"\\n\");\n return {\n success: false,\n error: `Build failed (exit code ${exitCode})\\n${lastLines}`,\n exitCode,\n output,\n };\n }\n\n const zeMatch = output.match(/ZE\\d+/);\n if (zeMatch) {\n return {\n success: false,\n error: `Zephyr upload failed (${zeMatch[0]})`,\n exitCode: 0,\n output,\n };\n }\n\n const deployMatch = output.match(/🚀.*Deployed:\\s*(https?:\\S+)/);\n if (deployMatch) {\n return { success: true, url: deployMatch[1], exitCode: 0, output };\n }\n\n if (env.DEPLOY === \"true\") {\n return {\n success: false,\n error: \"No deploy URL found (Zephyr may have failed)\",\n exitCode: 0,\n output,\n };\n }\n return { success: true, exitCode: 0, output };\n}\n\ninterface InternalWorkspaceResult extends WorkspaceDeployResult {\n deployEntries?: DeployResultEntry[];\n}\n\nasync function buildOneWorkspace(\n ws: WorkspaceTarget,\n env: Record<string, string>,\n opts: { deploy: boolean; verbose?: boolean },\n): Promise<InternalWorkspaceResult> {\n const pkgJson = await readJsonFile<{\n scripts?: Record<string, string>;\n }>(`${ws.path}/package.json`);\n const shouldDeployScript = opts.deploy && pkgJson.scripts?.deploy;\n const buildConfig = shouldDeployScript\n ? { cmd: \"bun\", args: [\"run\", \"deploy\"] }\n : (buildCommands[ws.key] ?? { cmd: \"bun\", args: [\"run\", \"build\"] });\n\n const wsEnv = { ...env };\n\n const startTime = Date.now();\n let attempt = await runBuildAttempt(\n buildConfig.cmd,\n buildConfig.args,\n ws.path,\n wsEnv,\n opts.verbose ?? false,\n ws.key,\n );\n\n let retried = false;\n\n if (!attempt.success && attempt.exitCode === 0 && opts.deploy) {\n if (!opts.verbose) {\n console.log(` ${colors.yellow(\"↻\")} ${padRight(ws.key, 28)} retrying...`);\n }\n retried = true;\n attempt = await runBuildAttempt(\n buildConfig.cmd,\n buildConfig.args,\n ws.path,\n wsEnv,\n opts.verbose ?? false,\n ws.key,\n );\n }\n\n const durationMs = Date.now() - startTime;\n const result: InternalWorkspaceResult = {\n key: ws.key,\n kind: ws.kind,\n success: attempt.success,\n url: attempt.url,\n error: attempt.error,\n deployEntries: attempt.deployEntries,\n durationMs,\n retried: retried ? true : undefined,\n };\n\n if (!opts.verbose) {\n const name = padRight(ws.key, 28);\n if (result.success) {\n const duration = formatDuration(durationMs);\n const retryTag = retried ? \" (retried)\" : \"\";\n console.log(` ${colors.green(icons.ok)} ${name} ${colors.dim(duration + retryTag)}`);\n } else {\n const errorLine = (result.error ?? \"Failed\").split(\"\\n\")[0];\n console.log(` ${colors.error(icons.err)} ${name} ${errorLine}`);\n }\n }\n\n return result;\n}\n\nexport async function buildWorkspaceTargets(opts: {\n configDir: string;\n bosConfig: BosConfig | null;\n runtimeConfig: RuntimeConfig | null;\n targets: string[];\n deploy: boolean;\n verbose?: boolean;\n}): Promise<{\n built: string[];\n skipped: string[];\n deployResults?: WorkspaceDeployResult[];\n}> {\n const existing: WorkspaceTarget[] = [];\n const skipped: string[] = [];\n\n for (const target of opts.targets) {\n const resolved = resolveWorkspaceTarget(\n target,\n opts.bosConfig,\n opts.runtimeConfig,\n opts.configDir,\n );\n if (!resolved) {\n skipped.push(target);\n continue;\n }\n\n const exists = await fileExists(`${resolved.path}/package.json`);\n if (exists) existing.push(resolved);\n else skipped.push(target);\n }\n\n if (existing.length === 0) {\n return { built: [], skipped };\n }\n\n const sharedSync = await syncResolvedSharedDeps({\n configDir: opts.configDir,\n hostMode: \"local\",\n bosConfig: opts.bosConfig ?? undefined,\n extendsChain: [],\n });\n if (sharedSync.catalogChanged) {\n await run(\"bun\", [\"install\"], { cwd: opts.configDir });\n }\n\n const shouldBuildPlugin = existing.some((entry) => entry.key === \"api\");\n\n const forceRebuild = opts.deploy;\n const buildTasks: Promise<void>[] = [buildEverythingDevQuietly(opts.configDir, forceRebuild)];\n if (shouldBuildPlugin) {\n buildTasks.push(buildEveryPluginQuietly(opts.configDir, forceRebuild));\n }\n await Promise.all(buildTasks);\n\n const env: Record<string, string> = {\n ...process.env,\n NODE_ENV: opts.deploy ? \"production\" : \"development\",\n };\n if (opts.deploy) {\n env.DEPLOY = \"true\";\n } else {\n delete env.DEPLOY;\n }\n\n const bosConfigPath = join(opts.configDir, \"bos.config.json\");\n let configSnapshot: string | undefined;\n if (opts.deploy && existsSync(bosConfigPath)) {\n configSnapshot = readFileSync(bosConfigPath, \"utf-8\");\n }\n\n const orderedExisting = opts.deploy\n ? [\n ...existing.filter((entry) => entry.kind === \"app\" && entry.key !== \"host\"),\n ...existing.filter((entry) => entry.kind === \"plugin\"),\n ...existing.filter((entry) => entry.kind === \"app\" && entry.key === \"host\"),\n ]\n : existing;\n\n const parallelGroup = opts.deploy\n ? orderedExisting.filter((e) => e.key !== \"host\")\n : orderedExisting;\n const sequentialGroup = opts.deploy ? orderedExisting.filter((e) => e.key === \"host\") : [];\n\n const built: string[] = [];\n const deployResults: WorkspaceDeployResult[] = [];\n\n if (opts.deploy && parallelGroup.length > 0) {\n const total = parallelGroup.length + sequentialGroup.length;\n console.log();\n console.log(` Building ${total} workspace${total > 1 ? \"s\" : \"\"}...`);\n console.log();\n\n const results = await Promise.allSettled(\n parallelGroup.map((ws) => buildOneWorkspace(ws, env, opts)),\n );\n\n const allDeployEntries: DeployResultEntry[] = [];\n for (let i = 0; i < parallelGroup.length; i++) {\n const ws = parallelGroup[i];\n const result = results[i];\n if (result.status === \"fulfilled\") {\n if (result.value.success) {\n built.push(ws.key);\n }\n if (result.value.deployEntries) {\n allDeployEntries.push(...result.value.deployEntries);\n }\n const { deployEntries: _deployEntries, ...deployResult } = result.value;\n deployResults.push(deployResult);\n } else {\n deployResults.push({\n key: ws.key,\n kind: ws.kind,\n success: false,\n error: result.reason?.message ?? \"Unknown error\",\n });\n }\n }\n\n if (configSnapshot && allDeployEntries.length > 0) {\n const config = JSON.parse(configSnapshot) as Record<string, unknown>;\n const merged = applyDeployResults(config, allDeployEntries);\n writeFileSync(bosConfigPath, `${JSON.stringify(merged, null, 2)}\\n`);\n }\n\n for (const ws of sequentialGroup) {\n const result = await buildOneWorkspace(ws, env, opts);\n if (result.success) {\n built.push(ws.key);\n }\n if (result.deployEntries) {\n const hostEntries = result.deployEntries.filter((r) => r.urlField.startsWith(\"app.host\"));\n if (hostEntries.length > 0 && existsSync(bosConfigPath)) {\n const currentConfig = JSON.parse(readFileSync(bosConfigPath, \"utf-8\")) as Record<\n string,\n unknown\n >;\n const merged = applyDeployResults(currentConfig, hostEntries);\n writeFileSync(bosConfigPath, `${JSON.stringify(merged, null, 2)}\\n`);\n }\n }\n const { deployEntries: _deployEntries, ...sequentialResult } = result;\n deployResults.push(sequentialResult);\n }\n\n console.log();\n } else {\n for (const resolved of orderedExisting) {\n const buildConfig = buildCommands[resolved.key] ?? {\n cmd: \"bun\",\n args: [\"run\", \"build\"],\n };\n\n await run(buildConfig.cmd, buildConfig.args, {\n cwd: resolved.path,\n env,\n });\n built.push(resolved.key);\n }\n }\n\n return { built, skipped, deployResults: opts.deploy ? deployResults : undefined };\n}\n\nexport async function buildEveryPluginQuietly(cwd: string, force = false) {\n const packageDir = `${cwd}/packages/every-plugin`;\n const packageExists = await fileExists(`${packageDir}/package.json`);\n if (!packageExists) {\n return;\n }\n\n const distPath = `${cwd}/packages/every-plugin/dist/build/rspack/plugin.mjs`;\n const distExists = await fileExists(distPath);\n\n if (distExists && !force) {\n return;\n }\n\n const result = (await run(\"bun\", [\"run\", \"--cwd\", \"packages/every-plugin\", \"build\"], {\n cwd,\n capture: true,\n })) as { stdout: string; stderr: string; exitCode: number };\n\n if (result.exitCode === 0) {\n return;\n }\n\n if (result.stdout.trim()) {\n process.stdout.write(result.stdout);\n }\n\n if (result.stderr.trim()) {\n process.stderr.write(result.stderr);\n }\n\n throw new Error(\n `bun run --cwd packages/every-plugin build failed with exit code ${result.exitCode}`,\n );\n}\n\nexport async function buildEverythingDevQuietly(cwd: string, force = false) {\n const packageDir = `${cwd}/packages/everything-dev`;\n const packageExists = await fileExists(`${packageDir}/package.json`);\n if (!packageExists) {\n return;\n }\n\n const distPath = `${cwd}/packages/everything-dev/dist/index.mjs`;\n const distExists = await fileExists(distPath);\n\n if (distExists && !force) {\n return;\n }\n\n const result = (await run(\"bun\", [\"run\", \"--cwd\", \"packages/everything-dev\", \"build\"], {\n cwd,\n capture: true,\n })) as { stdout: string; stderr: string; exitCode: number };\n\n if (result.exitCode === 0) {\n return;\n }\n\n if (result.stdout.trim()) {\n process.stdout.write(result.stdout);\n }\n\n if (result.stderr.trim()) {\n process.stderr.write(result.stderr);\n }\n\n throw new Error(\n `bun run --cwd packages/everything-dev build failed with exit code ${result.exitCode}`,\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"build.mjs","names":[],"sources":["../src/build.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { access, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport { formatDuration } from \"./cli/timing\";\nimport { resolveLocalDevelopmentPath } from \"./config\";\nimport type { WorkspaceDeployResult } from \"./contract\";\nimport { applyDeployResults, type DeployResultEntry, parseDeployLines } from \"./integrity\";\nimport { syncResolvedSharedDeps } from \"./shared-deps\";\nimport type { BosConfig, BosPluginRef, RuntimeConfig } from \"./types\";\nimport { run } from \"./utils/run\";\nimport { padRight } from \"./utils/string\";\nimport { colors, icons } from \"./utils/theme\";\n\nconst buildCommands: Record<string, { cmd: string; args: string[] }> = {\n host: { cmd: \"bun\", args: [\"run\", \"build\"] },\n ui: { cmd: \"bun\", args: [\"run\", \"build\"] },\n api: { cmd: \"bun\", args: [\"run\", \"build\"] },\n};\n\ntype WorkspaceTarget = {\n key: string;\n kind: \"app\" | \"plugin\";\n path: string;\n};\n\nexport function getPluginRef(entry: string | BosPluginRef | undefined | null): BosPluginRef | null {\n if (!entry || typeof entry === \"string\") return null;\n return entry;\n}\n\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readJsonFile<T>(path: string): Promise<T> {\n return JSON.parse(await readFile(path, \"utf8\")) as T;\n}\n\nfunction resolveWorkspaceTarget(\n key: string,\n bosConfig: BosConfig | null,\n runtimeConfig: RuntimeConfig | null,\n configDir: string,\n): WorkspaceTarget | null {\n if (bosConfig?.app && key in bosConfig.app) {\n const appEntry = (bosConfig.app as Record<string, { development?: string }>)[key];\n const devPath = resolveLocalDevelopmentPath(appEntry?.development, configDir);\n if (devPath) {\n return {\n key,\n kind: \"app\",\n path: devPath,\n };\n }\n return {\n key,\n kind: \"app\",\n path: `${configDir}/${key}`,\n };\n }\n\n const runtimePlugin = runtimeConfig?.plugins?.[key];\n const pluginPath =\n runtimePlugin?.localPath ??\n resolveLocalDevelopmentPath(getPluginRef(bosConfig?.plugins?.[key])?.development, configDir);\n if (pluginPath) {\n return {\n key,\n kind: \"plugin\",\n path: pluginPath,\n };\n }\n\n return null;\n}\n\nexport function selectWorkspaceTargets(packages: string, bosConfig: BosConfig | null): string[] {\n const allPackages = [\n ...Object.keys(bosConfig?.app ?? {}),\n ...Object.keys(bosConfig?.plugins ?? {}),\n ];\n if (packages === \"all\") {\n return allPackages;\n }\n\n return packages\n .split(\",\")\n .map((pkg) => pkg.trim())\n .filter((pkg) => allPackages.includes(pkg));\n}\n\ninterface BuildAttemptResult {\n success: boolean;\n url?: string;\n error?: string;\n warnings?: string[];\n exitCode: number;\n output: string;\n deployEntries?: DeployResultEntry[];\n}\n\nasync function runBuildAttempt(\n cmd: string,\n args: string[],\n cwd: string,\n env: Record<string, string>,\n verbose: boolean,\n wsKey: string,\n): Promise<BuildAttemptResult> {\n let zephyrAuthShown = false;\n const result = await run(cmd, args, {\n cwd,\n env,\n capture: true,\n onChunk: (stream, chunk) => {\n if (verbose) {\n if (stream === \"stdout\") process.stdout.write(chunk);\n else process.stderr.write(chunk);\n }\n if (zephyrAuthShown) return;\n const text = chunk.toString(\"utf-8\");\n if (\n /Authentication required.*log in to Zephyr/i.test(text) ||\n /auth\\.zephyr-cloud\\.io\\/authorize/.test(text)\n ) {\n zephyrAuthShown = true;\n const urlMatch = text.match(/https:\\/\\/auth\\.zephyr-cloud\\.io\\/authorize\\S+/);\n console.log();\n console.log(colors.yellow(` ⚠ Zephyr authentication required for ${wsKey}`));\n if (urlMatch) {\n console.log(` ${colors.cyan(urlMatch[0])}`);\n }\n console.log(colors.dim(\" Waiting for authentication...\"));\n console.log();\n }\n },\n });\n const stdout = result?.stdout ?? \"\";\n const stderr = result?.stderr ?? \"\";\n const exitCode = result?.exitCode ?? 0;\n const output = `${stdout}\\n${stderr}`;\n\n const deployEntries = parseDeployLines(output);\n\n if (deployEntries.length > 0) {\n const result: BuildAttemptResult = {\n success: true,\n url: deployEntries[0]?.url,\n exitCode: 0,\n output,\n deployEntries,\n };\n if (exitCode !== 0) {\n const errorLines = output\n .split(\"\\n\")\n .filter((line) => /\\bERROR\\b/.test(line) || line.startsWith(\"Rspack compiled with\"))\n .slice(0, 5);\n if (errorLines.length > 0) {\n result.warnings = errorLines.map((l) => l.trim());\n if (!verbose) {\n console.log(\n ` ${colors.yellow(\"⚠\")} Build completed with errors (exit code ${exitCode}) — Zephyr deployed successfully`,\n );\n for (const line of errorLines) {\n console.log(` ${colors.dim(line.trim())}`);\n }\n }\n }\n }\n return result;\n }\n\n if (exitCode !== 0) {\n const lastLines = output.trim().split(\"\\n\").slice(-5).join(\"\\n\");\n return {\n success: false,\n error: `Build failed (exit code ${exitCode})\\n${lastLines}`,\n exitCode,\n output,\n };\n }\n\n const deployMatch = output.match(/🚀.*Deployed:\\s*(https?:\\S+)/);\n if (deployMatch) {\n return { success: true, url: deployMatch[1], exitCode: 0, output };\n }\n\n const zeMatch = output.match(/ZE\\d{4,}/);\n if (zeMatch) {\n return {\n success: false,\n error: `Zephyr upload failed (${zeMatch[0]})`,\n exitCode: 0,\n output,\n };\n }\n\n if (env.DEPLOY === \"true\") {\n return {\n success: false,\n error: \"No deploy URL found (Zephyr may have failed)\",\n exitCode: 0,\n output,\n };\n }\n return { success: true, exitCode: 0, output };\n}\n\ninterface InternalWorkspaceResult extends WorkspaceDeployResult {\n deployEntries?: DeployResultEntry[];\n}\n\nasync function buildOneWorkspace(\n ws: WorkspaceTarget,\n env: Record<string, string>,\n opts: { deploy: boolean; verbose?: boolean },\n): Promise<InternalWorkspaceResult> {\n const pkgJson = await readJsonFile<{\n scripts?: Record<string, string>;\n }>(`${ws.path}/package.json`);\n const shouldDeployScript = opts.deploy && pkgJson.scripts?.deploy;\n const buildConfig = shouldDeployScript\n ? { cmd: \"bun\", args: [\"run\", \"deploy\"] }\n : (buildCommands[ws.key] ?? { cmd: \"bun\", args: [\"run\", \"build\"] });\n\n const wsEnv = { ...env };\n\n const startTime = Date.now();\n let attempt = await runBuildAttempt(\n buildConfig.cmd,\n buildConfig.args,\n ws.path,\n wsEnv,\n opts.verbose ?? false,\n ws.key,\n );\n\n let retried = false;\n const firstAttempt: BuildAttemptResult | undefined = attempt.success ? undefined : { ...attempt };\n\n if (!attempt.success && attempt.exitCode === 0 && opts.deploy) {\n if (!opts.verbose) {\n console.log(` ${colors.yellow(\"↻\")} ${padRight(ws.key, 28)} retrying...`);\n }\n retried = true;\n attempt = await runBuildAttempt(\n buildConfig.cmd,\n buildConfig.args,\n ws.path,\n wsEnv,\n opts.verbose ?? false,\n ws.key,\n );\n\n if (!attempt.success && firstAttempt) {\n attempt.error = `First attempt: ${firstAttempt.error}\\nRetry: ${attempt.error}`;\n }\n }\n\n const durationMs = Date.now() - startTime;\n const result: InternalWorkspaceResult = {\n key: ws.key,\n kind: ws.kind,\n success: attempt.success,\n url: attempt.url,\n error: attempt.error,\n warnings: attempt.warnings,\n deployEntries: attempt.deployEntries,\n durationMs,\n retried: retried ? true : undefined,\n };\n\n if (!opts.verbose) {\n const name = padRight(ws.key, 28);\n if (result.success) {\n const duration = formatDuration(durationMs);\n const retryTag = retried ? \" (retried)\" : \"\";\n console.log(` ${colors.green(icons.ok)} ${name} ${colors.dim(duration + retryTag)}`);\n } else {\n const errorLine = (result.error ?? \"Failed\").split(\"\\n\")[0];\n console.log(` ${colors.error(icons.err)} ${name} ${errorLine}`);\n }\n }\n\n return result;\n}\n\nexport async function buildWorkspaceTargets(opts: {\n configDir: string;\n bosConfig: BosConfig | null;\n runtimeConfig: RuntimeConfig | null;\n targets: string[];\n deploy: boolean;\n verbose?: boolean;\n}): Promise<{\n built: string[];\n skipped: string[];\n deployResults?: WorkspaceDeployResult[];\n}> {\n const existing: WorkspaceTarget[] = [];\n const skipped: string[] = [];\n\n for (const target of opts.targets) {\n const resolved = resolveWorkspaceTarget(\n target,\n opts.bosConfig,\n opts.runtimeConfig,\n opts.configDir,\n );\n if (!resolved) {\n skipped.push(target);\n continue;\n }\n\n const exists = await fileExists(`${resolved.path}/package.json`);\n if (exists) existing.push(resolved);\n else skipped.push(target);\n }\n\n if (existing.length === 0) {\n return { built: [], skipped };\n }\n\n const sharedSync = await syncResolvedSharedDeps({\n configDir: opts.configDir,\n hostMode: \"local\",\n bosConfig: opts.bosConfig ?? undefined,\n extendsChain: [],\n });\n if (sharedSync.catalogChanged) {\n await run(\"bun\", [\"install\"], { cwd: opts.configDir });\n }\n\n const shouldBuildPlugin = existing.some((entry) => entry.key === \"api\");\n\n const forceRebuild = opts.deploy;\n const buildTasks: Promise<void>[] = [buildEverythingDevQuietly(opts.configDir, forceRebuild)];\n if (shouldBuildPlugin) {\n buildTasks.push(buildEveryPluginQuietly(opts.configDir, forceRebuild));\n }\n await Promise.all(buildTasks);\n\n const env: Record<string, string> = {\n ...process.env,\n NODE_ENV: opts.deploy ? \"production\" : \"development\",\n };\n if (opts.deploy) {\n env.DEPLOY = \"true\";\n } else {\n delete env.DEPLOY;\n }\n\n const bosConfigPath = join(opts.configDir, \"bos.config.json\");\n let configSnapshot: string | undefined;\n if (opts.deploy && existsSync(bosConfigPath)) {\n configSnapshot = readFileSync(bosConfigPath, \"utf-8\");\n }\n\n const orderedExisting = opts.deploy\n ? [\n ...existing.filter((entry) => entry.kind === \"app\" && entry.key !== \"host\"),\n ...existing.filter((entry) => entry.kind === \"plugin\"),\n ...existing.filter((entry) => entry.kind === \"app\" && entry.key === \"host\"),\n ]\n : existing;\n\n const parallelGroup = opts.deploy\n ? orderedExisting.filter((e) => e.key !== \"host\")\n : orderedExisting;\n const sequentialGroup = opts.deploy ? orderedExisting.filter((e) => e.key === \"host\") : [];\n\n const built: string[] = [];\n const deployResults: WorkspaceDeployResult[] = [];\n\n if (opts.deploy && parallelGroup.length > 0) {\n const total = parallelGroup.length + sequentialGroup.length;\n console.log();\n console.log(` Building ${total} workspace${total > 1 ? \"s\" : \"\"}...`);\n console.log();\n\n const results = await Promise.allSettled(\n parallelGroup.map((ws) => buildOneWorkspace(ws, env, opts)),\n );\n\n const allDeployEntries: DeployResultEntry[] = [];\n for (let i = 0; i < parallelGroup.length; i++) {\n const ws = parallelGroup[i];\n const result = results[i];\n if (result.status === \"fulfilled\") {\n if (result.value.success) {\n built.push(ws.key);\n }\n if (result.value.deployEntries) {\n allDeployEntries.push(...result.value.deployEntries);\n }\n const { deployEntries: _deployEntries, ...deployResult } = result.value;\n deployResults.push(deployResult);\n } else {\n deployResults.push({\n key: ws.key,\n kind: ws.kind,\n success: false,\n error: result.reason?.message ?? \"Unknown error\",\n });\n }\n }\n\n if (configSnapshot && allDeployEntries.length > 0) {\n const config = JSON.parse(configSnapshot) as Record<string, unknown>;\n const merged = applyDeployResults(config, allDeployEntries);\n writeFileSync(bosConfigPath, `${JSON.stringify(merged, null, 2)}\\n`);\n }\n\n for (const ws of sequentialGroup) {\n const result = await buildOneWorkspace(ws, env, opts);\n if (result.success) {\n built.push(ws.key);\n }\n if (result.deployEntries) {\n const hostEntries = result.deployEntries.filter((r) => r.urlField.startsWith(\"app.host\"));\n if (hostEntries.length > 0 && existsSync(bosConfigPath)) {\n const currentConfig = JSON.parse(readFileSync(bosConfigPath, \"utf-8\")) as Record<\n string,\n unknown\n >;\n const merged = applyDeployResults(currentConfig, hostEntries);\n writeFileSync(bosConfigPath, `${JSON.stringify(merged, null, 2)}\\n`);\n }\n }\n const { deployEntries: _deployEntries, ...sequentialResult } = result;\n deployResults.push(sequentialResult);\n }\n\n console.log();\n } else {\n for (const resolved of orderedExisting) {\n const buildConfig = buildCommands[resolved.key] ?? {\n cmd: \"bun\",\n args: [\"run\", \"build\"],\n };\n\n await run(buildConfig.cmd, buildConfig.args, {\n cwd: resolved.path,\n env,\n });\n built.push(resolved.key);\n }\n }\n\n return { built, skipped, deployResults: opts.deploy ? deployResults : undefined };\n}\n\nexport async function buildEveryPluginQuietly(cwd: string, force = false) {\n const packageDir = `${cwd}/packages/every-plugin`;\n const packageExists = await fileExists(`${packageDir}/package.json`);\n if (!packageExists) {\n return;\n }\n\n const distPath = `${cwd}/packages/every-plugin/dist/build/rspack/plugin.mjs`;\n const distExists = await fileExists(distPath);\n\n if (distExists && !force) {\n return;\n }\n\n const result = (await run(\"bun\", [\"run\", \"--cwd\", \"packages/every-plugin\", \"build\"], {\n cwd,\n capture: true,\n })) as { stdout: string; stderr: string; exitCode: number };\n\n if (result.exitCode === 0) {\n return;\n }\n\n if (result.stdout.trim()) {\n process.stdout.write(result.stdout);\n }\n\n if (result.stderr.trim()) {\n process.stderr.write(result.stderr);\n }\n\n throw new Error(\n `bun run --cwd packages/every-plugin build failed with exit code ${result.exitCode}`,\n );\n}\n\nexport async function buildEverythingDevQuietly(cwd: string, force = false) {\n const packageDir = `${cwd}/packages/everything-dev`;\n const packageExists = await fileExists(`${packageDir}/package.json`);\n if (!packageExists) {\n return;\n }\n\n const distPath = `${cwd}/packages/everything-dev/dist/index.mjs`;\n const distExists = await fileExists(distPath);\n\n if (distExists && !force) {\n return;\n }\n\n const result = (await run(\"bun\", [\"run\", \"--cwd\", \"packages/everything-dev\", \"build\"], {\n cwd,\n capture: true,\n })) as { stdout: string; stderr: string; exitCode: number };\n\n if (result.exitCode === 0) {\n return;\n }\n\n if (result.stdout.trim()) {\n process.stdout.write(result.stdout);\n }\n\n if (result.stderr.trim()) {\n process.stderr.write(result.stderr);\n }\n\n throw new Error(\n `bun run --cwd packages/everything-dev build failed with exit code ${result.exitCode}`,\n );\n}\n"],"mappings":"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"}
package/dist/cli/sync.cjs CHANGED
@@ -23,6 +23,7 @@ const FRAMEWORK_OWNED_SYNC_FILES = new Set([
23
23
  ".github/workflows/ci.yml",
24
24
  ".github/workflows/deploy.yml",
25
25
  ".github/workflows/staging.yml",
26
+ ".github/workflows/release.yml",
26
27
  "railway.toml",
27
28
  "ui/package.json",
28
29
  "ui/postcss.config.mjs",
@@ -42,7 +43,10 @@ const FRAMEWORK_OWNED_SYNC_FILES = new Set([
42
43
  "api/tsconfig.contract.json",
43
44
  "api/tsconfig.json",
44
45
  "api/src/lib/auth.ts",
45
- "api/src/lib/context.ts"
46
+ "api/src/lib/context.ts",
47
+ "api/src/db/index.ts",
48
+ "api/src/db/layer.ts",
49
+ "api/src/db/migrate.ts"
46
50
  ]);
47
51
  function computeHash(content) {
48
52
  return (0, node_crypto.createHash)("sha256").update(content).digest("hex").substring(0, 16);
@@ -261,6 +265,18 @@ async function syncTemplate(projectDir, options) {
261
265
  destToSource.set(`plugins/${pluginKey}/src/lib/${libFile}`, sourceFile);
262
266
  }
263
267
  }
268
+ for (const pluginKey of childPlugins) {
269
+ if (!(0, node_fs.existsSync)((0, node_path.join)(projectDir, "plugins", pluginKey, "src", "db"))) continue;
270
+ for (const dbFile of [
271
+ "index.ts",
272
+ "layer.ts",
273
+ "migrate.ts"
274
+ ]) {
275
+ const sourceFile = `api/src/db/${dbFile}`;
276
+ if (!(0, node_fs.existsSync)((0, node_path.join)(sourceDir, sourceFile))) continue;
277
+ destToSource.set(`plugins/${pluginKey}/src/db/${dbFile}`, sourceFile);
278
+ }
279
+ }
264
280
  for (const pluginKey of childPlugins) {
265
281
  if (!(0, node_fs.existsSync)((0, node_path.join)(projectDir, "plugins", pluginKey))) continue;
266
282
  const sourceFile = "plugins/_template/rspack.config.js";
@@ -1 +1 @@
1
- {"version":3,"file":"sync.cjs","names":["mergeBosConfigWithTemplate","isPlainObjectFromMerge","resolveExtendsRef","resolveSourceDir","extractSkillsBlock","buildChildAgentsMd","personalizeConfig","syncResolvedSharedDeps","loadResolvedConfig","writeSnapshot","runBunInstall","runTypesGen"],"sources":["../../src/cli/sync.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { glob } from \"glob\";\nimport { loadResolvedConfig } from \"../config\";\nimport type { SyncOptions, SyncResult } from \"../contract\";\nimport {\n isPlainObject as isPlainObjectFromMerge,\n mergeBosConfigWithTemplate,\n resolveExtendsRef,\n} from \"../merge\";\nimport { syncResolvedSharedDeps } from \"../shared-deps\";\nimport { writeGeneratedInfra } from \"./infra\";\nimport {\n buildChildAgentsMd,\n extractSkillsBlock,\n personalizeConfig,\n resolveSourceDir,\n runBunInstall,\n runTypesGen,\n} from \"./init\";\nimport { writeSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_OWNED_SYNC_FILES = new Set([\n \".env.example\",\n \".gitignore\",\n \"biome.json\",\n \"bos.config.json\",\n \"bunfig.toml\",\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 \"railway.toml\",\n \"ui/package.json\",\n \"ui/postcss.config.mjs\",\n \"ui/rsbuild.config.ts\",\n \"ui/tsconfig.json\",\n \"ui/src/app.ts\",\n \"ui/src/globals.d.ts\",\n \"ui/src/hydrate.tsx\",\n \"ui/src/lib/api.ts\",\n \"ui/src/lib/auth.ts\",\n \"ui/src/router.server.tsx\",\n \"ui/src/router.tsx\",\n \"ui/src/routes/__root.tsx\",\n \"api/package.json\",\n \"api/plugin.dev.ts\",\n \"api/rspack.config.js\",\n \"api/tsconfig.contract.json\",\n \"api/tsconfig.json\",\n \"api/src/lib/auth.ts\",\n \"api/src/lib/context.ts\",\n]);\n\ntype PackageJson = Record<string, unknown>;\n\nfunction computeHash(content: string | Uint8Array): string {\n return createHash(\"sha256\").update(content).digest(\"hex\").substring(0, 16);\n}\n\nexport function isFrameworkOwnedSyncFile(filePath: string): boolean {\n if (FRAMEWORK_OWNED_SYNC_FILES.has(filePath)) return true;\n if (/^plugins\\/[^/]+\\/src\\/lib\\/(auth|context)\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/rspack\\.config\\.js$/.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\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): 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 ) {\n const mergedScripts = mergeStringMaps(\n local.scripts as Record<string, string> | undefined,\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): 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);\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): 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(dest, buildSyncedFileContent(sourceDir, projectDir, filePath, destPath));\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 packageJsonPath = join(projectDir, \"package.json\");\n if (!existsSync(packageJsonPath)) return false;\n\n try {\n const pkg = JSON.parse(readFileSync(packageJsonPath, \"utf-8\")) as {\n workspaces?: { packages?: string[] } | string[];\n };\n const workspaces = pkg.workspaces;\n const packages = Array.isArray(workspaces)\n ? workspaces\n : Array.isArray(workspaces?.packages)\n ? workspaces.packages\n : [];\n return packages.includes(\"plugins/*\");\n } catch {\n return false;\n }\n}\n\nexport async function syncTemplate(projectDir: string, options: SyncOptions): Promise<SyncResult> {\n // Sync reads the raw bos.config.json (not the resolved config) because it needs\n // the user's explicit local settings: their extends ref, selected plugins, etc.\n // The resolved config is the merged result and would include inherited parent\n // values that the user didn't explicitly choose, which would break sync filtering.\n const localConfig = JSON.parse(\n 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 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 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 destToSource = new Map<string, string>();\n for (const destPath of FRAMEWORK_OWNED_SYNC_FILES) {\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 // 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 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 const updated: string[] = [];\n const skipped: string[] = [];\n const added: string[] = [];\n\n for (const [destPath, filePath] of destToSource.entries()) {\n const localHash = computeLocalHash(projectDir, destPath);\n const sourceHash = computeHash(buildSyncedFileContent(sourceDir, projectDir, filePath));\n\n if (localHash === null) {\n added.push(destPath);\n continue;\n }\n\n if (localHash !== sourceHash) {\n updated.push(destPath);\n }\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 return {\n status: \"dry-run\",\n updated,\n skipped,\n added,\n };\n }\n\n const filesToWrite = [...updated, ...added];\n\n if (filesToWrite.length > 0) {\n backupFiles(projectDir, filesToWrite);\n\n for (const destPath of filesToWrite) {\n const sourcePath = destToSource.get(destPath) ?? destPath;\n writeSyncedFile(sourceDir, projectDir, sourcePath, destPath);\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 loadResolvedConfig({ cwd: projectDir });\n if (syncedConfig?.runtime) {\n writeGeneratedInfra(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 runBunInstall(projectDir);\n await runTypesGen(projectDir);\n }\n\n return {\n status: \"synced\",\n updated,\n skipped,\n added,\n };\n } finally {\n await cleanup();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sync.cjs","names":["mergeBosConfigWithTemplate","isPlainObjectFromMerge","resolveExtendsRef","resolveSourceDir","extractSkillsBlock","buildChildAgentsMd","personalizeConfig","syncResolvedSharedDeps","loadResolvedConfig","writeSnapshot","runBunInstall","runTypesGen"],"sources":["../../src/cli/sync.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { glob } from \"glob\";\nimport { loadResolvedConfig } from \"../config\";\nimport type { SyncOptions, SyncResult } from \"../contract\";\nimport {\n isPlainObject as isPlainObjectFromMerge,\n mergeBosConfigWithTemplate,\n resolveExtendsRef,\n} from \"../merge\";\nimport { syncResolvedSharedDeps } from \"../shared-deps\";\nimport { writeGeneratedInfra } from \"./infra\";\nimport {\n buildChildAgentsMd,\n extractSkillsBlock,\n personalizeConfig,\n resolveSourceDir,\n runBunInstall,\n runTypesGen,\n} from \"./init\";\nimport { writeSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_OWNED_SYNC_FILES = new Set([\n \".env.example\",\n \".gitignore\",\n \"biome.json\",\n \"bos.config.json\",\n \"bunfig.toml\",\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/rsbuild.config.ts\",\n \"ui/tsconfig.json\",\n \"ui/src/app.ts\",\n \"ui/src/globals.d.ts\",\n \"ui/src/hydrate.tsx\",\n \"ui/src/lib/api.ts\",\n \"ui/src/lib/auth.ts\",\n \"ui/src/router.server.tsx\",\n \"ui/src/router.tsx\",\n \"ui/src/routes/__root.tsx\",\n \"api/package.json\",\n \"api/plugin.dev.ts\",\n \"api/rspack.config.js\",\n \"api/tsconfig.contract.json\",\n \"api/tsconfig.json\",\n \"api/src/lib/auth.ts\",\n \"api/src/lib/context.ts\",\n \"api/src/db/index.ts\",\n \"api/src/db/layer.ts\",\n \"api/src/db/migrate.ts\",\n]);\n\ntype PackageJson = Record<string, unknown>;\n\nfunction computeHash(content: string | Uint8Array): string {\n return createHash(\"sha256\").update(content).digest(\"hex\").substring(0, 16);\n}\n\nexport function isFrameworkOwnedSyncFile(filePath: string): boolean {\n if (FRAMEWORK_OWNED_SYNC_FILES.has(filePath)) return true;\n if (/^plugins\\/[^/]+\\/src\\/lib\\/(auth|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 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\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): 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 ) {\n const mergedScripts = mergeStringMaps(\n local.scripts as Record<string, string> | undefined,\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): 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);\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): 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(dest, buildSyncedFileContent(sourceDir, projectDir, filePath, destPath));\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 packageJsonPath = join(projectDir, \"package.json\");\n if (!existsSync(packageJsonPath)) return false;\n\n try {\n const pkg = JSON.parse(readFileSync(packageJsonPath, \"utf-8\")) as {\n workspaces?: { packages?: string[] } | string[];\n };\n const workspaces = pkg.workspaces;\n const packages = Array.isArray(workspaces)\n ? workspaces\n : Array.isArray(workspaces?.packages)\n ? workspaces.packages\n : [];\n return packages.includes(\"plugins/*\");\n } catch {\n return false;\n }\n}\n\nexport async function syncTemplate(projectDir: string, options: SyncOptions): Promise<SyncResult> {\n // Sync reads the raw bos.config.json (not the resolved config) because it needs\n // the user's explicit local settings: their extends ref, selected plugins, etc.\n // The resolved config is the merged result and would include inherited parent\n // values that the user didn't explicitly choose, which would break sync filtering.\n const localConfig = JSON.parse(\n 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 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 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 destToSource = new Map<string, string>();\n for (const destPath of FRAMEWORK_OWNED_SYNC_FILES) {\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 // 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/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 const updated: string[] = [];\n const skipped: string[] = [];\n const added: string[] = [];\n\n for (const [destPath, filePath] of destToSource.entries()) {\n const localHash = computeLocalHash(projectDir, destPath);\n const sourceHash = computeHash(buildSyncedFileContent(sourceDir, projectDir, filePath));\n\n if (localHash === null) {\n added.push(destPath);\n continue;\n }\n\n if (localHash !== sourceHash) {\n updated.push(destPath);\n }\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 return {\n status: \"dry-run\",\n updated,\n skipped,\n added,\n };\n }\n\n const filesToWrite = [...updated, ...added];\n\n if (filesToWrite.length > 0) {\n backupFiles(projectDir, filesToWrite);\n\n for (const destPath of filesToWrite) {\n const sourcePath = destToSource.get(destPath) ?? destPath;\n writeSyncedFile(sourceDir, projectDir, sourcePath, destPath);\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 loadResolvedConfig({ cwd: projectDir });\n if (syncedConfig?.runtime) {\n writeGeneratedInfra(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 runBunInstall(projectDir);\n await runTypesGen(projectDir);\n }\n\n return {\n status: \"synced\",\n updated,\n skipped,\n added,\n };\n } finally {\n await cleanup();\n }\n}\n"],"mappings":"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"}
package/dist/cli/sync.mjs CHANGED
@@ -22,6 +22,7 @@ const FRAMEWORK_OWNED_SYNC_FILES = new Set([
22
22
  ".github/workflows/ci.yml",
23
23
  ".github/workflows/deploy.yml",
24
24
  ".github/workflows/staging.yml",
25
+ ".github/workflows/release.yml",
25
26
  "railway.toml",
26
27
  "ui/package.json",
27
28
  "ui/postcss.config.mjs",
@@ -41,7 +42,10 @@ const FRAMEWORK_OWNED_SYNC_FILES = new Set([
41
42
  "api/tsconfig.contract.json",
42
43
  "api/tsconfig.json",
43
44
  "api/src/lib/auth.ts",
44
- "api/src/lib/context.ts"
45
+ "api/src/lib/context.ts",
46
+ "api/src/db/index.ts",
47
+ "api/src/db/layer.ts",
48
+ "api/src/db/migrate.ts"
45
49
  ]);
46
50
  function computeHash(content) {
47
51
  return createHash("sha256").update(content).digest("hex").substring(0, 16);
@@ -260,6 +264,18 @@ async function syncTemplate(projectDir, options) {
260
264
  destToSource.set(`plugins/${pluginKey}/src/lib/${libFile}`, sourceFile);
261
265
  }
262
266
  }
267
+ for (const pluginKey of childPlugins) {
268
+ if (!existsSync(join(projectDir, "plugins", pluginKey, "src", "db"))) continue;
269
+ for (const dbFile of [
270
+ "index.ts",
271
+ "layer.ts",
272
+ "migrate.ts"
273
+ ]) {
274
+ const sourceFile = `api/src/db/${dbFile}`;
275
+ if (!existsSync(join(sourceDir, sourceFile))) continue;
276
+ destToSource.set(`plugins/${pluginKey}/src/db/${dbFile}`, sourceFile);
277
+ }
278
+ }
263
279
  for (const pluginKey of childPlugins) {
264
280
  if (!existsSync(join(projectDir, "plugins", pluginKey))) continue;
265
281
  const sourceFile = "plugins/_template/rspack.config.js";