@superblocksteam/sdk 2.0.83-next.1 → 2.0.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/cli-replacement/automatic-upgrades.d.ts +6 -0
  3. package/dist/cli-replacement/automatic-upgrades.d.ts.map +1 -1
  4. package/dist/cli-replacement/automatic-upgrades.js +27 -5
  5. package/dist/cli-replacement/automatic-upgrades.js.map +1 -1
  6. package/dist/cli-replacement/dev.d.mts.map +1 -1
  7. package/dist/cli-replacement/dev.mjs +217 -260
  8. package/dist/cli-replacement/dev.mjs.map +1 -1
  9. package/dist/dev-utils/dev-server.mjs +115 -133
  10. package/dist/dev-utils/dev-server.mjs.map +1 -1
  11. package/dist/telemetry/index.d.ts +4 -4
  12. package/dist/telemetry/index.d.ts.map +1 -1
  13. package/dist/telemetry/index.js +64 -92
  14. package/dist/telemetry/index.js.map +1 -1
  15. package/dist/telemetry/util.d.ts +2 -1
  16. package/dist/telemetry/util.d.ts.map +1 -1
  17. package/dist/telemetry/util.js +4 -26
  18. package/dist/telemetry/util.js.map +1 -1
  19. package/package.json +5 -6
  20. package/src/cli-replacement/automatic-upgrades.ts +42 -10
  21. package/src/cli-replacement/dev.mts +281 -336
  22. package/src/dev-utils/dev-server.mts +127 -149
  23. package/src/telemetry/index.ts +83 -105
  24. package/src/telemetry/util.ts +4 -27
  25. package/tsconfig.tsbuildinfo +1 -1
  26. package/turbo.json +2 -20
  27. package/dist/cli-replacement/version-detection.d.ts +0 -71
  28. package/dist/cli-replacement/version-detection.d.ts.map +0 -1
  29. package/dist/cli-replacement/version-detection.js +0 -186
  30. package/dist/cli-replacement/version-detection.js.map +0 -1
  31. package/dist/cli-replacement/version-detection.test.d.ts +0 -5
  32. package/dist/cli-replacement/version-detection.test.d.ts.map +0 -1
  33. package/dist/cli-replacement/version-detection.test.js +0 -257
  34. package/dist/cli-replacement/version-detection.test.js.map +0 -1
  35. package/dist/telemetry/index.test.d.ts +0 -2
  36. package/dist/telemetry/index.test.d.ts.map +0 -1
  37. package/dist/telemetry/index.test.js +0 -93
  38. package/dist/telemetry/index.test.js.map +0 -1
  39. package/dist/telemetry/local-obs.d.ts +0 -73
  40. package/dist/telemetry/local-obs.d.ts.map +0 -1
  41. package/dist/telemetry/local-obs.js +0 -107
  42. package/dist/telemetry/local-obs.js.map +0 -1
  43. package/src/cli-replacement/version-detection.test.ts +0 -336
  44. package/src/cli-replacement/version-detection.ts +0 -220
  45. package/src/telemetry/index.test.ts +0 -130
  46. package/src/telemetry/local-obs.ts +0 -138
@@ -536,167 +536,145 @@ async function startVite({
536
536
  dispose: () => void;
537
537
  routeIndex: number;
538
538
  }> {
539
- return tracer.startActiveSpan("startVite", async (startViteSpan) => {
540
- try {
541
- const logger = getLogger(loggerOverride);
542
- logger.info("Creating dev server...");
543
- const viteLogger = createLogger();
544
- viteLogger.info = (msg: string) => logger.info(msg);
545
- viteLogger.warn = (msg: string) => {
546
- logger.warn(msg);
547
- };
548
- viteLogger.warnOnce = (msg: string) => {
549
- logger.warn(msg);
550
- };
551
- viteLogger.error = (msg: string) => {
552
- logger.error(msg);
553
- };
539
+ const logger = getLogger(loggerOverride);
540
+ logger.info("Creating dev server...");
541
+ const viteLogger = createLogger();
542
+ viteLogger.info = (msg: string) => logger.info(msg);
543
+ viteLogger.warn = (msg: string) => {
544
+ logger.warn(msg);
545
+ };
546
+ viteLogger.warnOnce = (msg: string) => {
547
+ logger.warn(msg);
548
+ };
549
+ viteLogger.error = (msg: string) => {
550
+ logger.error(msg);
551
+ };
554
552
 
555
- viteLogger.clearScreen = () => {};
553
+ viteLogger.clearScreen = () => {};
556
554
 
557
- const isCustomBuildEnabled = await isCustomComponentsEnabled();
558
- logger.debug(
559
- `Custom components ${isCustomBuildEnabled ? "enabled" : "disabled"}`,
560
- );
561
- const customFolder = path.join(root, "custom");
562
- const draftsFolder = path.join(root, ".superblocks");
555
+ const isCustomBuildEnabled = await isCustomComponentsEnabled();
556
+ logger.debug(
557
+ `Custom components ${isCustomBuildEnabled ? "enabled" : "disabled"}`,
558
+ );
559
+ const customFolder = path.join(root, "custom");
560
+ const draftsFolder = path.join(root, ".superblocks");
563
561
 
564
- const env = loadEnv(mode, root, "");
562
+ const env = loadEnv(mode, root, "");
565
563
 
566
- const hmrPort = await getFreePort();
567
- logger.debug(`Allocated HMR port: ${hmrPort}`);
564
+ const hmrPort = await getFreePort();
565
+ logger.debug(`Allocated HMR port: ${hmrPort}`);
568
566
 
569
- const hmrOptions: HmrOptions = {
570
- port: hmrPort,
571
- clientPort: port,
572
- server: httpServer,
573
- overlay: false,
574
- };
567
+ const hmrOptions: HmrOptions = {
568
+ port: hmrPort,
569
+ clientPort: port,
570
+ server: httpServer,
571
+ overlay: false,
572
+ };
575
573
 
576
- // https://codesandbox.io/docs/learn/environment/preview-urls#using-environment-variables
577
- if (process.env.CSB_BASE_PREVIEW_HOST) {
578
- const hmrHost = `${os.hostname()}-${port}.${process.env.CSB_BASE_PREVIEW_HOST}`;
579
- hmrOptions.host = hmrHost;
580
- hmrOptions.clientPort = 443; // tells client to use default ssl port
581
- logger.debug(
582
- `CSB environment detected, HMR configured for host: ${hmrHost}`,
583
- );
584
- }
574
+ // https://codesandbox.io/docs/learn/environment/preview-urls#using-environment-variables
575
+ if (process.env.CSB_BASE_PREVIEW_HOST) {
576
+ const hmrHost = `${os.hostname()}-${port}.${process.env.CSB_BASE_PREVIEW_HOST}`;
577
+ hmrOptions.host = hmrHost;
578
+ hmrOptions.clientPort = 443; // tells client to use default ssl port
579
+ logger.debug(
580
+ `CSB environment detected, HMR configured for host: ${hmrHost}`,
581
+ );
582
+ }
585
583
 
586
- if (process.env.SABS_LIVE_EDIT_HOSTNAME) {
587
- hmrOptions.host = process.env.SABS_LIVE_EDIT_HOSTNAME;
588
- hmrOptions.clientPort = 443; // tells client to use default ssl port
589
- logger.debug(
590
- `SABS environment detected, HMR configured for host: ${hmrOptions.host}`,
591
- );
592
- }
584
+ if (process.env.SABS_LIVE_EDIT_HOSTNAME) {
585
+ hmrOptions.host = process.env.SABS_LIVE_EDIT_HOSTNAME;
586
+ hmrOptions.clientPort = 443; // tells client to use default ssl port
587
+ logger.debug(
588
+ `SABS environment detected, HMR configured for host: ${hmrOptions.host}`,
589
+ );
590
+ }
593
591
 
594
- const fileSyncPluginCreator = fileSyncVitePlugin(
595
- {
596
- fsOperationQueue,
597
- syncService,
598
- lockService,
599
- aiService,
600
- httpServer,
601
- checkAuthorization,
602
- tracer,
603
- logger,
604
- features,
605
- },
606
- { isCustomBuildEnabled },
607
- );
608
-
609
- logger.debug("Configuring dev server with plugins and options");
610
- const viteServer = await tracer.startActiveSpan(
611
- "viteCreateServer",
612
- async (viteCreateSpan) => {
613
- try {
614
- const server = await createServer({
615
- root,
616
- mode,
617
- clearScreen: process.env.SUPERBLOCKS_CLI_ENV !== "local",
618
- customLogger: viteLogger,
619
- server: {
620
- middlewareMode: true,
621
- watch: {
622
- ignored: [`${customFolder}/**/*`, `${draftsFolder}/**/*`],
623
- },
624
- hmr: hmrOptions,
625
- cors: {
626
- origin: true,
627
- credentials: true,
628
- },
629
- },
630
- build: {
631
- rollupOptions: {
632
- external: [`${customFolder}/**/*`],
633
- },
634
- },
635
- define: {
636
- // this replaces a string in @superblocksteam/shared
637
- "process.env.SUPERBLOCKS_PUBLIC_INTEGRATIONS_CDN_URL": process
638
- .env.SUPERBLOCKS_PUBLIC_INTEGRATIONS_CDN_URL
639
- ? JSON.stringify(
640
- process.env.SUPERBLOCKS_PUBLIC_INTEGRATIONS_CDN_URL,
641
- )
642
- : "undefined",
592
+ const fileSyncPluginCreator = fileSyncVitePlugin(
593
+ {
594
+ fsOperationQueue,
595
+ syncService,
596
+ lockService,
597
+ aiService,
598
+ httpServer,
599
+ checkAuthorization,
600
+ tracer,
601
+ logger,
602
+ features,
603
+ },
604
+ { isCustomBuildEnabled },
605
+ );
606
+
607
+ logger.debug("Configuring dev server with plugins and options");
608
+ const viteServer = await createServer({
609
+ root,
610
+ mode,
611
+ clearScreen: process.env.SUPERBLOCKS_CLI_ENV !== "local",
612
+ customLogger: viteLogger,
613
+ server: {
614
+ middlewareMode: true,
615
+ watch: {
616
+ ignored: [`${customFolder}/**/*`, `${draftsFolder}/**/*`],
617
+ },
618
+ hmr: hmrOptions,
619
+ cors: {
620
+ origin: true,
621
+ credentials: true,
622
+ },
623
+ },
624
+ build: {
625
+ rollupOptions: {
626
+ external: [`${customFolder}/**/*`],
627
+ },
628
+ },
629
+ define: {
630
+ // this replaces a string in @superblocksteam/shared
631
+ "process.env.SUPERBLOCKS_PUBLIC_INTEGRATIONS_CDN_URL": process.env
632
+ .SUPERBLOCKS_PUBLIC_INTEGRATIONS_CDN_URL
633
+ ? JSON.stringify(process.env.SUPERBLOCKS_PUBLIC_INTEGRATIONS_CDN_URL)
634
+ : "undefined",
635
+ },
636
+ plugins: [
637
+ tsconfigPaths(),
638
+ customComponentsPlugin(),
639
+ fileSyncPluginCreator.plugin,
640
+ // Add a virtual "stub" module for the build manifest
641
+ buildManifestStubPlugin(),
642
+ react({
643
+ babel: {
644
+ plugins: [
645
+ // We will bring this back later
646
+ // "babel-plugin-react-compiler",
647
+ [
648
+ import.meta.resolve("@babel/plugin-proposal-decorators"),
649
+ {
650
+ version: "2023-11",
643
651
  },
644
- plugins: [
645
- tsconfigPaths(),
646
- customComponentsPlugin(),
647
- fileSyncPluginCreator.plugin,
648
- // Add a virtual "stub" module for the build manifest
649
- buildManifestStubPlugin(),
650
- react({
651
- babel: {
652
- plugins: [
653
- // We will bring this back later
654
- // "babel-plugin-react-compiler",
655
- [
656
- import.meta
657
- .resolve("@babel/plugin-proposal-decorators"),
658
- {
659
- version: "2023-11",
660
- },
661
- ],
662
- ],
663
- },
664
- }),
665
- createLucideReactImportOptimizer(),
666
- ddRumPlugin({
667
- clientToken: env.SUPERBLOCKS_LIBRARY_DD_CLIENT_TOKEN ?? "",
668
- applicationId:
669
- env.SUPERBLOCKS_LIBRARY_DD_APPLICATION_ID ?? "",
670
- env: env.SUPERBLOCKS_LIBRARY_ENV ?? "prod",
671
- // TODO: This version refers to the LIBRARY version for Datadog RUM, not the CLI version.
672
- // CLI auto-upgrade still works - the caching changes in this PR only affect detection speed.
673
- // Replace with dynamic library version injection once available.
674
- version: "1.0.0",
675
- }),
676
- ],
677
- });
678
- return server;
679
- } finally {
680
- viteCreateSpan.end();
681
- }
652
+ ],
653
+ ],
682
654
  },
683
- );
655
+ }),
656
+ createLucideReactImportOptimizer(),
657
+ ddRumPlugin({
658
+ clientToken: env.SUPERBLOCKS_LIBRARY_DD_CLIENT_TOKEN ?? "",
659
+ applicationId: env.SUPERBLOCKS_LIBRARY_DD_APPLICATION_ID ?? "",
660
+ env: env.SUPERBLOCKS_LIBRARY_ENV ?? "prod",
661
+ // TODO: Version should be injected from the library. Replace once we have the autoupgrade feature.
662
+ version: "1.0.0",
663
+ }),
664
+ ],
665
+ });
684
666
 
685
- const routeIndex = (app._router as IRouter).stack.length;
686
- app.use(viteServer.middlewares);
687
- logger.info("Dev server created and middleware attached successfully");
667
+ const routeIndex = (app._router as IRouter).stack.length;
668
+ app.use(viteServer.middlewares);
669
+ logger.info("Dev server created and middleware attached successfully");
688
670
 
689
- return {
690
- viteServer,
691
- routeIndex,
692
- dispose: () => {
693
- fileSyncPluginCreator.dispose();
694
- },
695
- };
696
- } finally {
697
- startViteSpan.end();
698
- }
699
- });
671
+ return {
672
+ viteServer,
673
+ routeIndex,
674
+ dispose: () => {
675
+ fileSyncPluginCreator.dispose();
676
+ },
677
+ };
700
678
  }
701
679
 
702
680
  const DEFAULT_HMR_PORT = 24678;
@@ -1,8 +1,16 @@
1
1
  import os from "node:os";
2
- import { trace, type Tracer } from "@opentelemetry/api";
3
- import { logs, type Logger } from "@opentelemetry/api-logs";
2
+ import { logs as logsAPI } from "@opentelemetry/api-logs";
3
+ import { AsyncLocalStorageContextManager } from "@opentelemetry/context-async-hooks";
4
+ import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
5
+ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
4
6
  import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
5
7
  import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
8
+ import { Resource } from "@opentelemetry/resources";
9
+ import { NodeSDK, logs, api } from "@opentelemetry/sdk-node";
10
+ import {
11
+ ATTR_SERVICE_NAME,
12
+ ATTR_SERVICE_VERSION,
13
+ } from "@opentelemetry/semantic-conventions";
6
14
  import {
7
15
  DeploymentTypeEnum,
8
16
  OBS_TAG_APPLICATION_ID,
@@ -10,18 +18,10 @@ import {
10
18
  OBS_TAG_ORG_ID,
11
19
  OBS_TAG_USER_EMAIL,
12
20
  } from "@superblocksteam/shared";
13
- import {
14
- initNodeTelemetry,
15
- getTelemetryInstance,
16
- isTelemetryInitialized,
17
- parseDeploymentType,
18
- resetTelemetry,
19
- getDefaultPolicy,
20
- } from "@superblocksteam/telemetry";
21
- // Note: dd-trace kept for LLMObs until Epic 07 completes
22
21
  import ddTrace from "dd-trace";
23
22
  import packageJson from "../../package.json" with { type: "json" };
24
23
  import {
24
+ ATTR_DEPLOYMENT_ENVIRONMENT,
25
25
  ATTR_SUPERBLOCKS_BASE_URL,
26
26
  ATTR_SUPERBLOCKS_CLI_TOKEN,
27
27
  ATTR_SUPERBLOCKS_CSB_ID,
@@ -29,34 +29,44 @@ import {
29
29
  ATTR_SUPERBLOCKS_USER_ID,
30
30
  getEnvironmentFromHostname,
31
31
  } from "./attributes.js";
32
- import { applyLocalObsEnvVars, isLocalObsEnabled } from "./local-obs.js";
33
32
  import { getLogger as getStandardLogger } from "./logging.js";
34
33
  import { getConfiguration, SERVICE_NAME } from "./util.js";
35
34
  import type { ApplicationConfigWithTokenConfigAndUserInfo } from "../types/index.js";
35
+ import type { Tracer } from "@opentelemetry/api";
36
+ import type { Logger } from "@opentelemetry/api-logs";
36
37
 
37
- // Apply local observability env vars early, before dd-trace auto-init
38
- applyLocalObsEnvVars();
39
-
40
- // Configuration state
41
- let config: Awaited<ReturnType<typeof getConfiguration>> | undefined =
42
- undefined;
38
+ let config = undefined;
43
39
  let configured = false;
40
+ let sdkInstance: NodeSDK | undefined = undefined;
44
41
 
45
42
  /**
46
- * Current deployment type based on SUPERBLOCKS_DEPLOYMENT_TYPE env var.
47
- * Defaults to CLOUD if not specified or invalid.
43
+ * Validate and return a valid DeploymentTypeEnum value.
44
+ * Returns CLOUD if not specified or if an invalid value is provided.
48
45
  */
49
- export const deploymentType = (() => {
50
- try {
51
- return parseDeploymentType(process.env.SUPERBLOCKS_DEPLOYMENT_TYPE);
52
- } catch (error) {
46
+ function getValidDeploymentType(value: string | undefined): DeploymentTypeEnum {
47
+ if (!value || value === "") {
48
+ return DeploymentTypeEnum.CLOUD;
49
+ }
50
+ if (
51
+ !Object.values(DeploymentTypeEnum).includes(value as DeploymentTypeEnum)
52
+ ) {
53
53
  console.warn(
54
- "[Telemetry] Invalid SUPERBLOCKS_DEPLOYMENT_TYPE, defaulting to CLOUD:",
55
- error,
54
+ `Invalid SUPERBLOCKS_DEPLOYMENT_TYPE: "${value}". ` +
55
+ `Valid values are: ${Object.values(DeploymentTypeEnum).join(", ")}. ` +
56
+ `Defaulting to "${DeploymentTypeEnum.CLOUD}".`,
56
57
  );
57
58
  return DeploymentTypeEnum.CLOUD;
58
59
  }
59
- })();
60
+ return value as DeploymentTypeEnum;
61
+ }
62
+
63
+ /**
64
+ * Current deployment type based on SUPERBLOCKS_DEPLOYMENT_TYPE env var.
65
+ * Defaults to CLOUD if not specified. Throws if an invalid value is provided.
66
+ */
67
+ export const deploymentType = getValidDeploymentType(
68
+ process.env.SUPERBLOCKS_DEPLOYMENT_TYPE,
69
+ );
60
70
 
61
71
  /**
62
72
  * Whether the current deployment is CLOUD_PREM.
@@ -67,21 +77,16 @@ export const deploymentType = (() => {
67
77
  export const isCloudPrem = deploymentType === DeploymentTypeEnum.CLOUD_PREM;
68
78
 
69
79
  async function shutdownTelemetry(): Promise<void> {
70
- if (isTelemetryInitialized()) {
71
- try {
72
- await getTelemetryInstance().shutdown();
73
- } catch (error) {
74
- console.error("Error during telemetry shutdown:", error);
75
- } finally {
76
- resetTelemetry();
77
- configured = false;
78
- }
80
+ if (sdkInstance) {
81
+ await sdkInstance.shutdown();
82
+ sdkInstance = undefined;
83
+ configured = false;
79
84
  }
80
85
  }
81
86
 
82
87
  export async function configureTelemetry(
83
88
  applicationConfig?: ApplicationConfigWithTokenConfigAndUserInfo,
84
- ): Promise<boolean> {
89
+ ) {
85
90
  const logger = getStandardLogger();
86
91
  if (configured) {
87
92
  await shutdownTelemetry();
@@ -94,28 +99,21 @@ export async function configureTelemetry(
94
99
  } catch (error) {
95
100
  console.error(error);
96
101
  configured = false;
97
- return false;
102
+ return;
98
103
  }
99
104
 
100
105
  logger.info(
101
106
  `[INIT] Initializing telemetry for service ${config.serviceName} at Superblocks instance ${config.superblocksHostname}`,
102
107
  );
103
108
 
104
- // Check for local observability mode (SUPERBLOCKS_LOCAL_OBS=true)
105
- const isLocalObs = isLocalObsEnabled();
106
-
107
- // Allow env var override for local development testing (AGENT-1048)
108
- // Local obs mode always enables LLMObs
109
109
  const llmobsEnabled =
110
- isLocalObs ||
111
- process.env.SUPERBLOCKS_LLMOBS_ENABLED === "true" ||
112
- (applicationConfig?.featureFlags.devServerLlmobsEnabled() ?? false);
110
+ applicationConfig?.featureFlags.devServerLlmobsEnabled() ?? false;
113
111
 
114
112
  logger.debug(
115
- `[INIT] superblocks.dev-server.llmobs.enabled=${llmobsEnabled} (localObs=${isLocalObs}) for service ${config.serviceName}`,
113
+ `[INIT] superblocks.dev-server.llmobs.enabled=${llmobsEnabled} for service ${config.serviceName}`,
116
114
  );
117
115
 
118
- // Configure dd-trace for LLMObs (migrated to OTEL in Epic 07)
116
+ // Configure dd-trace for APM and LLM tracing
119
117
  process.env.DD_SITE = "datadoghq.com";
120
118
  // stop ddTrace from trying to get remote configuration
121
119
  process.env.DD_REMOTE_CONFIGURATION_ENABLED = "false";
@@ -151,68 +149,48 @@ export async function configureTelemetry(
151
149
  } for service ${config.serviceName}`,
152
150
  );
153
151
 
154
- // Configure OpenTelemetry for APM traces and logs via shared telemetry package
155
- const policy = getDefaultPolicy(deploymentType);
156
-
157
- try {
158
- initNodeTelemetry(
159
- {
160
- serviceName: config.serviceName,
161
- serviceVersion: packageJson.version,
162
- environment: getEnvironmentFromHostname(config.superblocksHostname),
163
- otlpUrl: config.otlpBaseUrl,
164
- resourceAttributes: {
165
- [ATTR_SUPERBLOCKS_BASE_URL]: config.superblocksHostname,
166
- [ATTR_SUPERBLOCKS_CLI_TOKEN]: config.token,
167
- [ATTR_SUPERBLOCKS_IS_CSB]: String(!!process.env.SUPERBLOCKS_IS_CSB),
168
- ...(process.env.SUPERBLOCKS_IS_CSB && {
169
- [ATTR_SUPERBLOCKS_CSB_ID]: os.hostname(),
170
- }),
171
- ...(applicationConfig?.id && {
172
- [OBS_TAG_APPLICATION_ID]: applicationConfig.id,
173
- }),
174
- ...(applicationConfig?.branchName && {
175
- [OBS_TAG_BRANCH]: applicationConfig.branchName,
176
- }),
177
- ...(applicationConfig?.userEmail && {
178
- [OBS_TAG_USER_EMAIL]: applicationConfig.userEmail,
179
- }),
180
- ...(applicationConfig?.userId && {
181
- [ATTR_SUPERBLOCKS_USER_ID]: applicationConfig.userId,
182
- }),
183
- ...(applicationConfig?.organizationId && {
184
- [OBS_TAG_ORG_ID]: applicationConfig.organizationId,
185
- }),
186
- },
187
- instrumentations: [
188
- new HttpInstrumentation(),
189
- new ExpressInstrumentation(),
190
- ],
191
- logsEnabled: true,
192
- },
193
- policy,
194
- );
195
- } catch (error) {
196
- console.error("[Telemetry] Failed to initialize OpenTelemetry:", error);
197
- configured = false;
198
- return false;
199
- }
152
+ // Configure OpenTelemetry for APM traces and logs
153
+ sdkInstance = new NodeSDK({
154
+ resource: Resource.default().merge(
155
+ new Resource({
156
+ [ATTR_SERVICE_NAME]: config.serviceName,
157
+ [ATTR_SERVICE_VERSION]: packageJson.version,
158
+ [ATTR_DEPLOYMENT_ENVIRONMENT]: getEnvironmentFromHostname(
159
+ config.superblocksHostname,
160
+ ),
161
+ [ATTR_SUPERBLOCKS_BASE_URL]: config.superblocksHostname,
162
+ [ATTR_SUPERBLOCKS_CLI_TOKEN]: config.token,
163
+ [ATTR_SUPERBLOCKS_IS_CSB]: !!process.env.SUPERBLOCKS_IS_CSB,
164
+ [ATTR_SUPERBLOCKS_CSB_ID]: process.env.SUPERBLOCKS_IS_CSB
165
+ ? os.hostname()
166
+ : undefined,
167
+ [OBS_TAG_APPLICATION_ID]: applicationConfig?.id,
168
+ [OBS_TAG_BRANCH]: applicationConfig?.branchName,
169
+ [OBS_TAG_USER_EMAIL]: applicationConfig?.userEmail,
170
+ [ATTR_SUPERBLOCKS_USER_ID]: applicationConfig?.userId,
171
+ [OBS_TAG_ORG_ID]: applicationConfig?.organizationId,
172
+ }),
173
+ ),
174
+ // APM traces exported via OTEL
175
+ traceExporter: new OTLPTraceExporter({
176
+ url: config.superblocksTracesUrl,
177
+ }),
178
+ logRecordProcessors: [
179
+ new logs.SimpleLogRecordProcessor(
180
+ new OTLPLogExporter({ url: config.superblocksLogsUrl }),
181
+ ),
182
+ ],
183
+ contextManager: new AsyncLocalStorageContextManager(),
184
+ instrumentations: [new HttpInstrumentation(), new ExpressInstrumentation()],
185
+ });
200
186
 
201
- return true;
187
+ sdkInstance.start();
202
188
  }
203
189
 
204
190
  export function getLogger(): Logger {
205
- if (isTelemetryInitialized()) {
206
- return getTelemetryInstance().getLogger(SERVICE_NAME);
207
- }
208
- // Fallback to global API if telemetry not initialized
209
- return logs.getLogger(SERVICE_NAME, packageJson.version);
191
+ return logsAPI.getLogger(SERVICE_NAME, packageJson.version);
210
192
  }
211
193
 
212
194
  export function getTracer(): Tracer {
213
- if (isTelemetryInitialized()) {
214
- return getTelemetryInstance().getTracer(SERVICE_NAME);
215
- }
216
- // Fallback to global API if telemetry not initialized
217
- return trace.getTracer(SERVICE_NAME, packageJson.version);
195
+ return api.trace.getTracer(SERVICE_NAME, packageJson.version);
218
196
  }
@@ -2,36 +2,12 @@ import { getLocalTokenWithUrl } from "@superblocksteam/util";
2
2
 
3
3
  export const SERVICE_NAME = "sdk-dev-server";
4
4
 
5
- /**
6
- * Get the OTLP base URL for telemetry export.
7
- *
8
- * Priority:
9
- * 1. SUPERBLOCKS_OTEL_COLLECTOR_URL env var (for local obs mode)
10
- * 2. Superblocks API endpoint derived from base URL
11
- *
12
- * When SUPERBLOCKS_OTEL_COLLECTOR_URL is set (e.g., http://localhost:24318),
13
- * telemetry is sent directly to the local OTEL collector.
14
- *
15
- * Note: This returns the BASE URL. The telemetry library appends /v1/traces,
16
- * /v1/metrics, /v1/logs to this URL.
17
- */
18
- function getOtlpBaseUrl(superblocksBaseUrl: URL): string {
19
- const localOtelUrl = process.env.SUPERBLOCKS_OTEL_COLLECTOR_URL;
20
- if (localOtelUrl) {
21
- // Remove trailing /v1/traces etc. if present (just use base URL)
22
- return localOtelUrl.replace(/\/v1\/(traces|metrics|logs)$/, "");
23
- }
24
- // Default: Superblocks API proxies OTLP requests
25
- // The server expects /api/v1/traces but the telemetry lib adds /v1/traces,
26
- // so we return /api and let telemetry lib append /v1/traces
27
- return superblocksBaseUrl.origin + "/api";
28
- }
29
-
30
5
  export async function getConfiguration() {
31
6
  try {
32
7
  const tokenWithUrl = await getLocalTokenWithUrl();
33
8
  const superblocksBaseUrl = new URL(tokenWithUrl.superblocksBaseUrl);
34
- const otlpBaseUrl = getOtlpBaseUrl(superblocksBaseUrl);
9
+ const superblocksTracesUrl = superblocksBaseUrl.origin + "/api/v1/traces";
10
+ const superblocksLogsUrl = superblocksBaseUrl.origin + "/api/v1/logs";
35
11
  const superblocksHostname = superblocksBaseUrl.hostname;
36
12
  let token = "";
37
13
  if ("token" in tokenWithUrl) {
@@ -39,7 +15,8 @@ export async function getConfiguration() {
39
15
  }
40
16
  return {
41
17
  superblocksBaseUrl,
42
- otlpBaseUrl,
18
+ superblocksTracesUrl,
19
+ superblocksLogsUrl,
43
20
  superblocksHostname,
44
21
  serviceName: SERVICE_NAME,
45
22
  token,