refactor(connectors): split client metadata from server runtime#5076
refactor(connectors): split client metadata from server runtime#5076waleedlatif1 wants to merge 6 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryMedium Risk Overview Connector architecture now mirrors blocks: each service gets a Authoring docs ( Also in this diff: new Agiloft internal tool API routes; Grafana Reviewed by Cursor Bugbot for commit 1380945. Configure here. |
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 2c91cdb. Configure here.
Greptile SummaryThis PR fixes a Turbopack
Confidence Score: 5/5Safe to merge — the refactoring is a clean structural split with no behavior change to connector metadata or runtime fns, and all consumer sites were updated consistently. Every client component was migrated to CONNECTOR_META_REGISTRY and every server consumer to CONNECTOR_REGISTRY from registry.server. The ...meta spread in each connector's main module preserves byte-for-byte parity with the original object shape. The Turbopack DNS stubs are correctly removed now that the root cause is resolved. No skipped or incorrectly mapped import sites were found. No files require special attention. The 50 new meta.ts files are mechanically consistent, the type changes are backward-compatible, and the new Agiloft/Grafana API routes follow the established contract-validation pattern used by the rest of the codebase. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant ClientUI as Client UI
participant MetaReg as registry.ts (CONNECTOR_META_REGISTRY)
participant MetaFiles as connector/meta.ts files
participant ServerAPI as Server API Routes / Sync Engine
participant SrvReg as registry.server.ts (CONNECTOR_REGISTRY)
participant ConnFiles as connector/*.ts files
ClientUI->>MetaReg: import CONNECTOR_META_REGISTRY
MetaReg->>MetaFiles: import ConnectorMeta (id, name, icon, auth, configFields)
MetaFiles-->>MetaReg: pure metadata (no runtime fns, no node:net)
MetaReg-->>ClientUI: ConnectorMeta objects
ServerAPI->>SrvReg: import CONNECTOR_REGISTRY
SrvReg->>ConnFiles: import Connector (spreads meta + adds runtime fns)
ConnFiles-->>SrvReg: ConnectorConfig (meta + listDocuments/getDocument/validateConfig)
SrvReg-->>ServerAPI: full ConnectorConfig objects
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant ClientUI as Client UI
participant MetaReg as registry.ts (CONNECTOR_META_REGISTRY)
participant MetaFiles as connector/meta.ts files
participant ServerAPI as Server API Routes / Sync Engine
participant SrvReg as registry.server.ts (CONNECTOR_REGISTRY)
participant ConnFiles as connector/*.ts files
ClientUI->>MetaReg: import CONNECTOR_META_REGISTRY
MetaReg->>MetaFiles: import ConnectorMeta (id, name, icon, auth, configFields)
MetaFiles-->>MetaReg: pure metadata (no runtime fns, no node:net)
MetaReg-->>ClientUI: ConnectorMeta objects
ServerAPI->>SrvReg: import CONNECTOR_REGISTRY
SrvReg->>ConnFiles: import Connector (spreads meta + adds runtime fns)
ConnFiles-->>SrvReg: ConnectorConfig (meta + listDocuments/getDocument/validateConfig)
SrvReg-->>ServerAPI: full ConnectorConfig objects
Reviews (5): Last reviewed commit: "fix(grafana): surface upstream error whe..." | Re-trigger Greptile |
2c91cdb to
0a0ab3b
Compare
0a0ab3b to
58d3988
Compare
|
@greptile review |
|
@cursor review |
|
@greptile review |
|
@cursor review |
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit cab90e7. Configure here.
…er node:net in client bundle The browser build broke with `Cannot find module 'node:net'`. Server-only SSRF code in `input-validation.server.ts` (`dns/promises`, and since PR #5060 `undici` → `node:net`/`node:tls`) is statically reachable from the client bundle via the tool/connector registries, which the workflow editor imports for metadata. Node networking builtins have no browser shim, so Turbopack cannot compile them for the client. Two changes: 1. Split each connector's client-safe declarative metadata into a sibling `meta.ts` (`<name>ConnectorMeta`), mirroring the `XBlockMeta` / `BLOCK_META_REGISTRY` pattern. `connectors/registry.ts` is now the client-safe `CONNECTOR_META_REGISTRY` (+ `getConnectorMeta` / `getAllConnectorMeta`); the full registry with runtime fns moves to `connectors/registry.server.ts`. Client components consume the meta registry; the sync engine and knowledge API routes consume the server registry. This removes connectors from the client's server-only graph. Connector metadata is byte-for-byte identical before/after; runtime fns are untouched. 2. Extend the existing #4899 `turbopack.resolveAlias` browser stub — which already mapped `dns`/`dns/promises` to an empty module for the browser — to also cover `net`/`tls` (+ `node:` variants), since `undici` now pulls those in. The remaining tool/provider definitions still reach `input-validation.server` server-side; the browser-only stub keeps those Node builtins out of the client bundle while the real modules stay on the server, so SSRF validation and IP pinning are unaffected. Connector authoring/validation skills updated to teach the meta.ts split.
…untime Discord defined DEFAULT_MAX_MESSAGES separately in meta.ts (config placeholder) and discord.ts (sync behavior), which could drift. Export it from meta.ts and import it in the runtime, matching the single-source pattern used by the other connectors (e.g. gmail, intercom).
…browser shim Move the server-only SSRF-pinned fetch out of the grafana (update_dashboard, update_alert_rule) and agiloft (11 record/search tools) definitions and into internal API routes, the same pattern the rest of the server-side tools (and agiloft's own attach/retrieve) already use. The tool definitions are now purely declarative (request → internal route), so they no longer import `input-validation.server` and the tools registry is fully client-safe. With connectors (meta split) and these tools no longer reaching server-only code from the client bundle, the browser no longer pulls in `dns`/`net`/`tls`: - Add `import 'server-only'` to `input-validation.server.ts` so any future client import fails loudly at build time instead of silently bloating the bundle. - Remove the `turbopack.resolveAlias` browser stub and delete `empty-node-fallback.browser.ts` — the root cause is fixed, the shim is gone. Behavior is unchanged: each route runs the exact merge/validation/fetch logic the tool ran before (every header, param branch, JSON-parse guard, error string, and SSRF pinning preserved); only the location of execution moved from the client- bundled definition to a server route.
…only guard - onedrive's tagDefinitions lived in the runtime file, so the client meta registry returned undefined for it and the add-connector tag opt-out section stopped rendering for onedrive. Move it into meta.ts like the other connectors so client and server see identical metadata (verified across all 50). - Remove the 'server-only' import from input-validation.server.ts: the meta/route split already keeps it out of the client bundle, and blocks/tools registries don't use the guard either.
Check response.ok on the existing-resource GET in both update routes and return the upstream status/body, matching how the tool framework surfaced GET errors before the move to internal routes (the framework checks response.ok before transformResponse). Without this, a failed prefetch produced a generic 'Failed to fetch existing ...' message and dropped Grafana's error detail.
| .map((t) => t.trim()) | ||
| .filter((t) => t) | ||
| } | ||
|
|
||
| if (params.panels) { |
There was a problem hiding this comment.
Silent JSON parse failure for
panels
When params.panels contains invalid JSON, the catch {} block silently swallows the error, leaves updatedDashboard.panels unchanged (keeping the existing dashboard panels), and the PUT still proceeds — returning { success: true } to the caller. Every other JSON parameter in this route (tags parsing aside) and in the alert-rule route returns a proper error response on parse failure. A caller providing malformed panel JSON will believe the update succeeded while their panel changes were silently dropped.
cab90e7 to
1380945
Compare
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1380945. Configure here.
| output: {}, | ||
| error: `Failed to fetch existing dashboard: ${errorText}`, | ||
| }) | ||
| } |
There was a problem hiding this comment.
Update routes mask failures as success
High Severity
The new Grafana update API routes answer prefetch and update failures with HTTP 200 and a JSON body where success is false. The paired Grafana update tools always set success: true in transformResponse, and the tool runner treats a 200 as success before transform when a body parser is skipped. Failed dashboard or alert rule updates can be recorded as successful in workflows.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 1380945. Configure here.


Problem
The browser threw
Cannot find module 'node:net'(Turbopack) on staging.Knowledge-connector configs fused client-facing metadata (name, icon, auth, configFields) with server-only runtime fns (
listDocuments,getDocument,validateConfig) in one object. The client knowledge UI imports the connector registry for that metadata, which dragged the runtime — and transitivelyinput-validation.server→undici→node:net— into the client bundle.node:nethas no browser shim, so Turbopack fails to compile it.This was previously masked with
dns/net/tlsTurbopack browser-stub aliases (a workaround that shipped dead server code to the browser and was whack-a-mole). This PR removes the workaround and fixes the root cause.Fix
Separate the two halves, mirroring the existing
XBlockMeta/BLOCK_META_REGISTRYpattern inblocks/:ConnectorMeta(declarative metadata);ConnectorConfig extends ConnectorMetawith the runtime fns.meta.ts(<name>ConnectorMeta); the main module spreads it in and keeps the runtime fns.connectors/registry.tsis now the client-safeCONNECTOR_META_REGISTRY(+getConnectorMeta/getAllConnectorMeta) — just likeblocks/registry.tsandtools/registry.tsare client-safe. The full registry moves toconnectors/registry.server.ts(CONNECTOR_REGISTRY).dns/net/tlsTurbopack aliases and the empty-node fallback stub.Behavior parity
This is a pure client/server separation — no behavior change:
...meta).Verification
tsc --noEmit: 0 errorsmapTags, sync-engine, connector API routes): 166 passingcheck:api-validation: passedConnector authoring/validation skills (
add-connector,validate-connector) updated to teach the meta.ts split + dual registry.