fix(server): bundle build copies connectors next to server.bundle.mjs#739
Conversation
In prod Docker the server runs as /app/packages/server/dist/server.bundle.mjs, so connector-catalog's first candidate dir (<bundle dir>/connectors) didn't exist — the CLI build copies it for `lobu run`, but the server bundle build didn't. The scanner then fell through to /app/packages/connectors (package root, copied wholesale by the Dockerfile) which contains no top-level .ts files, so the catalog came back empty and app.lobu.ai/<org>/connectors rendered "No connectors found". Copy packages/connectors/src to packages/server/dist/connectors after both bundles build, mirroring packages/cli/scripts/build.cjs. The server bundle is now self-contained the same way `lobu run` already is.
📝 WalkthroughWalkthroughThe build script is updated to copy connector source files into the bundled output during the build process. Node filesystem utilities are imported, and post-bundling logic removes any existing ChangesBuild Connector Bundling
Estimated code review effort🎯 2 (Simple) | ⏱️ ~5 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Comment |
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/server/scripts/build-server-bundle.mjs`:
- Around line 87-96: Ensure the copy step fails fast: always remove the
destination with rmSync(connectorsDest, { recursive: true, force: true }) first
to avoid stale files, then check existsSync(connectorsSrc) and throw a
descriptive Error when the source is missing instead of silently skipping; after
confirming the source exists, recreate the parent directory
(mkdirSync(dirname(connectorsDest), { recursive: true })) and use
cpSync(connectorsSrc, connectorsDest, { recursive: true }) and console.log as
before. Use the existing symbols connectorsSrc, connectorsDest, rmSync,
existsSync, mkdirSync, and cpSync to locate and update the logic.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 0879e5d2-ce93-441f-8d5b-2dede52ec883
📒 Files selected for processing (1)
packages/server/scripts/build-server-bundle.mjs
| const connectorsSrc = join(pkgDir, '..', 'connectors', 'src'); | ||
| const connectorsDest = join(pkgDir, 'dist', 'connectors'); | ||
| if (existsSync(connectorsSrc)) { | ||
| if (existsSync(connectorsDest)) { | ||
| rmSync(connectorsDest, { recursive: true, force: true }); | ||
| } | ||
| mkdirSync(dirname(connectorsDest), { recursive: true }); | ||
| cpSync(connectorsSrc, connectorsDest, { recursive: true }); | ||
| console.log(`\n=== copied connectors: ${connectorsDest}`); | ||
| } |
There was a problem hiding this comment.
Fail fast if connector sources are missing instead of silently skipping copy.
Line 89 currently treats a missing connectors/src as success. That can ship a bundle without dist/connectors (or leave stale contents), which is exactly the failure mode this PR is fixing. Make this step deterministic: clear destination first, then throw when source is absent.
Suggested patch
const connectorsSrc = join(pkgDir, '..', 'connectors', 'src');
const connectorsDest = join(pkgDir, 'dist', 'connectors');
-if (existsSync(connectorsSrc)) {
- if (existsSync(connectorsDest)) {
- rmSync(connectorsDest, { recursive: true, force: true });
- }
- mkdirSync(dirname(connectorsDest), { recursive: true });
- cpSync(connectorsSrc, connectorsDest, { recursive: true });
- console.log(`\n=== copied connectors: ${connectorsDest}`);
-}
+if (existsSync(connectorsDest)) {
+ rmSync(connectorsDest, { recursive: true, force: true });
+}
+if (!existsSync(connectorsSrc)) {
+ throw new Error(`Missing connector sources at: ${connectorsSrc}`);
+}
+mkdirSync(dirname(connectorsDest), { recursive: true });
+cpSync(connectorsSrc, connectorsDest, { recursive: true });
+console.log(`\n=== copied connectors: ${connectorsDest}`);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/server/scripts/build-server-bundle.mjs` around lines 87 - 96, Ensure
the copy step fails fast: always remove the destination with
rmSync(connectorsDest, { recursive: true, force: true }) first to avoid stale
files, then check existsSync(connectorsSrc) and throw a descriptive Error when
the source is missing instead of silently skipping; after confirming the source
exists, recreate the parent directory (mkdirSync(dirname(connectorsDest), {
recursive: true })) and use cpSync(connectorsSrc, connectorsDest, { recursive:
true }) and console.log as before. Use the existing symbols connectorsSrc,
connectorsDest, rmSync, existsSync, mkdirSync, and cpSync to locate and update
the logic.
Symptom
app.lobu.ai/<org>/connectorsshows "No connectors found" on Lobu Cloud prod — the catalog scanner returns an empty list.Root cause
packages/server/src/utils/connector-catalog.tsresolvesDEFAULT_CONNECTOR_DIR_CANDIDATESrelative toimport.meta.dirname. In prod the server runs as/app/packages/server/dist/server.bundle.mjs, so the candidates become:/app/packages/server/dist/connectors— does not exist (the server bundle build didn't copy connectors here; only the CLI build did, inpackages/cli/scripts/build.cjs)./app/connectors/src— does not exist./app/packages/connectors— exists (the Dockerfile copies the wholepackages/connectors/dir), but it is the package root. The.tsconnector files live insrc/underneath it.getDefaultConnectorCatalogDir()returns candidate #3.listCatalogConnectorDefinitions()thenreaddirs it and filters to top-level*.ts— zero matches → empty catalog → "No connectors found".In dev (
make devviatsx watch),import.meta.dirnameis the source path, so candidate../../../connectors/srccorrectly resolves and dev works fine.Fix
Mirror the CLI build: after both bundles are emitted, copy
packages/connectors/srctopackages/server/dist/connectors. Candidate #1 now wins in prod and the server bundle is self-contained the same waylobu runalready is.Test plan
cd packages/server && bun run build:server— emitsdist/connectors/with 29.tsfilesbun run typecheck— cleanSummary by CodeRabbit