@superblocksteam/cli 2.0.129 → 2.0.130-next.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.
Files changed (109) hide show
  1. package/README.md +1 -1
  2. package/dist/{acorn-QSWNZOFP.js → acorn-EIVCA5KI.js} +3 -3
  3. package/dist/{angular-DHY3SEYB.js → angular-ZI3WOILR.js} +3 -3
  4. package/dist/{api-VUIRZDBP.js → api-WJS3DAJX.js} +4 -4
  5. package/dist/{babel-GASJSHSO.js → babel-HTLPYRLD.js} +3 -3
  6. package/dist/{chunk-EGM37OQF.js → chunk-6VFLSGDN.js} +2 -2
  7. package/dist/{chunk-RABHHN5M.js → chunk-A5FURMJX.js} +3 -3
  8. package/dist/{chunk-7QCZIAE3.js → chunk-D4HIK2GJ.js} +6 -6
  9. package/dist/{chunk-UNRUYGVR.js → chunk-E2SVRGEH.js} +3 -3
  10. package/dist/{chunk-CT4JPEBI.js → chunk-GOFUJ2AG.js} +4 -4
  11. package/dist/{chunk-U6O6JKMB.js → chunk-HMXDYMYV.js} +3 -3
  12. package/dist/{chunk-WC2YCWOJ.js → chunk-HR2F24F5.js} +4 -4
  13. package/dist/{chunk-HCQRUSQE.js → chunk-ILX5T2IO.js} +115 -20
  14. package/dist/{chunk-HCQRUSQE.js.map → chunk-ILX5T2IO.js.map} +1 -1
  15. package/dist/{chunk-ETHLIHQN.js → chunk-ISZCKU4B.js} +4 -4
  16. package/dist/{chunk-CH75SIZH.js → chunk-OGDGQ2PN.js} +4 -4
  17. package/dist/{chunk-EB4E42MD.js → chunk-PQ54MZVY.js} +3 -3
  18. package/dist/{chunk-ZRBMSD5I.js → chunk-QA5FLQ3P.js} +3 -3
  19. package/dist/{chunk-CLFZWWA4.js → chunk-RJATMZXQ.js} +6567 -2975
  20. package/dist/{chunk-CLFZWWA4.js.map → chunk-RJATMZXQ.js.map} +1 -1
  21. package/dist/{chunk-IAOLN6TE.js → chunk-VZBG3KKO.js} +3 -3
  22. package/dist/{chunk-VSBRAS53.js → chunk-W25HYL6C.js} +3 -3
  23. package/dist/{chunk-PBNML3U3.js → chunk-XBHQTUMW.js} +3 -3
  24. package/dist/{chunk-ZKLX2TF6.js → chunk-Z5A7GY7B.js} +3 -3
  25. package/dist/{cli-truncate-SGCWVQL7.js → cli-truncate-GHVTGJXO.js} +5 -5
  26. package/dist/commands/dev-parent.js +236 -13
  27. package/dist/commands/dev-parent.js.map +4 -4
  28. package/dist/{dd-trace-MVYTHNWK.js → dd-trace-YAWRQ5EZ.js} +7 -7
  29. package/dist/{dist-BPLLMMH5.js → dist-TXXS6BKN.js} +13 -13
  30. package/dist/{embedded-playwright-mcp-server-NX4VPFKL.js → embedded-playwright-mcp-server-4UYBA4W6.js} +3 -3
  31. package/dist/{enquirer-67ACZ6H7.js → enquirer-2MRXSM6K.js} +4 -4
  32. package/dist/{estree-6IHM4FJN.js → estree-ZBMBDQAY.js} +3 -3
  33. package/dist/{flow-QQLJLSKU.js → flow-2ZNURIEE.js} +3 -3
  34. package/dist/{getMachineId-bsd-LBVX3ZHR.js → getMachineId-bsd-DXDSHGIE.js} +5 -5
  35. package/dist/{getMachineId-darwin-JWMNMYIC.js → getMachineId-darwin-K5OI2B3N.js} +5 -5
  36. package/dist/{getMachineId-linux-X6FYAGRD.js → getMachineId-linux-7MLYPCC7.js} +4 -4
  37. package/dist/{getMachineId-unsupported-5S3Q7BMR.js → getMachineId-unsupported-IKZRQ3MK.js} +4 -4
  38. package/dist/{getMachineId-win-2UEEWMOJ.js → getMachineId-win-5IHDHKM5.js} +5 -5
  39. package/dist/{glimmer-YINHMTOC.js → glimmer-LX7HAVG6.js} +3 -3
  40. package/dist/{graphql-KAMTCTIJ.js → graphql-EHBPTXKK.js} +3 -3
  41. package/dist/{html-VKMCUGUM.js → html-MB6KSJUN.js} +3 -3
  42. package/dist/{http-LOAAFORX.js → http-RBFGWTRX.js} +12 -12
  43. package/dist/index.js +132 -75
  44. package/dist/index.js.map +1 -1
  45. package/dist/{jiti-GV55T5J6.js → jiti-Q3RXB6Y7.js} +3 -3
  46. package/dist/{log-update-G4JSB323.js → log-update-JRCOAYY2.js} +6 -6
  47. package/dist/{markdown-2TJTXEMG.js → markdown-W55LWCO3.js} +3 -3
  48. package/dist/{meriyah-HKBYUY4P.js → meriyah-YVBIMQDI.js} +3 -3
  49. package/dist/migration-templates/app-fullstack/css.d.ts +3 -0
  50. package/dist/migration-templates/app-fullstack/package.json +2 -2
  51. package/dist/{postcss-MT55EDUP.js → postcss-JBENB6QU.js} +3 -3
  52. package/dist/{read-pkg-ZFRXLQYD.js → read-pkg-3DM6HDIL.js} +5 -5
  53. package/dist/{spans-BSDMAZHA.js → spans-UZF3APNT.js} +4 -4
  54. package/dist/{src-K7B55BJR.js → src-S7DFYQDZ.js} +3 -3
  55. package/dist/{token-D4W2TY76.js → token-64CRCULC.js} +5 -5
  56. package/dist/{token-util-DE2LUHKB.js → token-util-2QIXH643.js} +5 -5
  57. package/dist/{typescript-OBOFG5TQ.js → typescript-GJ4FX6G3.js} +3 -3
  58. package/dist/{wrap-ansi-HN7FYF5E.js → wrap-ansi-H3UZAKUB.js} +5 -5
  59. package/dist/{yaml-XTRA2PRF.js → yaml-FZJ4633S.js} +3 -3
  60. package/oclif.manifest.json +1 -1
  61. package/package.json +8 -8
  62. /package/dist/{acorn-QSWNZOFP.js.map → acorn-EIVCA5KI.js.map} +0 -0
  63. /package/dist/{angular-DHY3SEYB.js.map → angular-ZI3WOILR.js.map} +0 -0
  64. /package/dist/{api-VUIRZDBP.js.map → api-WJS3DAJX.js.map} +0 -0
  65. /package/dist/{babel-GASJSHSO.js.map → babel-HTLPYRLD.js.map} +0 -0
  66. /package/dist/{chunk-EGM37OQF.js.map → chunk-6VFLSGDN.js.map} +0 -0
  67. /package/dist/{chunk-RABHHN5M.js.map → chunk-A5FURMJX.js.map} +0 -0
  68. /package/dist/{chunk-7QCZIAE3.js.map → chunk-D4HIK2GJ.js.map} +0 -0
  69. /package/dist/{chunk-UNRUYGVR.js.map → chunk-E2SVRGEH.js.map} +0 -0
  70. /package/dist/{chunk-CT4JPEBI.js.map → chunk-GOFUJ2AG.js.map} +0 -0
  71. /package/dist/{chunk-U6O6JKMB.js.map → chunk-HMXDYMYV.js.map} +0 -0
  72. /package/dist/{chunk-WC2YCWOJ.js.map → chunk-HR2F24F5.js.map} +0 -0
  73. /package/dist/{chunk-ETHLIHQN.js.map → chunk-ISZCKU4B.js.map} +0 -0
  74. /package/dist/{chunk-CH75SIZH.js.map → chunk-OGDGQ2PN.js.map} +0 -0
  75. /package/dist/{chunk-EB4E42MD.js.map → chunk-PQ54MZVY.js.map} +0 -0
  76. /package/dist/{chunk-ZRBMSD5I.js.map → chunk-QA5FLQ3P.js.map} +0 -0
  77. /package/dist/{chunk-IAOLN6TE.js.map → chunk-VZBG3KKO.js.map} +0 -0
  78. /package/dist/{chunk-VSBRAS53.js.map → chunk-W25HYL6C.js.map} +0 -0
  79. /package/dist/{chunk-PBNML3U3.js.map → chunk-XBHQTUMW.js.map} +0 -0
  80. /package/dist/{chunk-ZKLX2TF6.js.map → chunk-Z5A7GY7B.js.map} +0 -0
  81. /package/dist/{cli-truncate-SGCWVQL7.js.map → cli-truncate-GHVTGJXO.js.map} +0 -0
  82. /package/dist/{dd-trace-MVYTHNWK.js.map → dd-trace-YAWRQ5EZ.js.map} +0 -0
  83. /package/dist/{dist-BPLLMMH5.js.map → dist-TXXS6BKN.js.map} +0 -0
  84. /package/dist/{embedded-playwright-mcp-server-NX4VPFKL.js.map → embedded-playwright-mcp-server-4UYBA4W6.js.map} +0 -0
  85. /package/dist/{enquirer-67ACZ6H7.js.map → enquirer-2MRXSM6K.js.map} +0 -0
  86. /package/dist/{estree-6IHM4FJN.js.map → estree-ZBMBDQAY.js.map} +0 -0
  87. /package/dist/{flow-QQLJLSKU.js.map → flow-2ZNURIEE.js.map} +0 -0
  88. /package/dist/{getMachineId-bsd-LBVX3ZHR.js.map → getMachineId-bsd-DXDSHGIE.js.map} +0 -0
  89. /package/dist/{getMachineId-darwin-JWMNMYIC.js.map → getMachineId-darwin-K5OI2B3N.js.map} +0 -0
  90. /package/dist/{getMachineId-linux-X6FYAGRD.js.map → getMachineId-linux-7MLYPCC7.js.map} +0 -0
  91. /package/dist/{getMachineId-unsupported-5S3Q7BMR.js.map → getMachineId-unsupported-IKZRQ3MK.js.map} +0 -0
  92. /package/dist/{getMachineId-win-2UEEWMOJ.js.map → getMachineId-win-5IHDHKM5.js.map} +0 -0
  93. /package/dist/{glimmer-YINHMTOC.js.map → glimmer-LX7HAVG6.js.map} +0 -0
  94. /package/dist/{graphql-KAMTCTIJ.js.map → graphql-EHBPTXKK.js.map} +0 -0
  95. /package/dist/{html-VKMCUGUM.js.map → html-MB6KSJUN.js.map} +0 -0
  96. /package/dist/{http-LOAAFORX.js.map → http-RBFGWTRX.js.map} +0 -0
  97. /package/dist/{jiti-GV55T5J6.js.map → jiti-Q3RXB6Y7.js.map} +0 -0
  98. /package/dist/{log-update-G4JSB323.js.map → log-update-JRCOAYY2.js.map} +0 -0
  99. /package/dist/{markdown-2TJTXEMG.js.map → markdown-W55LWCO3.js.map} +0 -0
  100. /package/dist/{meriyah-HKBYUY4P.js.map → meriyah-YVBIMQDI.js.map} +0 -0
  101. /package/dist/{postcss-MT55EDUP.js.map → postcss-JBENB6QU.js.map} +0 -0
  102. /package/dist/{read-pkg-ZFRXLQYD.js.map → read-pkg-3DM6HDIL.js.map} +0 -0
  103. /package/dist/{spans-BSDMAZHA.js.map → spans-UZF3APNT.js.map} +0 -0
  104. /package/dist/{src-K7B55BJR.js.map → src-S7DFYQDZ.js.map} +0 -0
  105. /package/dist/{token-D4W2TY76.js.map → token-64CRCULC.js.map} +0 -0
  106. /package/dist/{token-util-DE2LUHKB.js.map → token-util-2QIXH643.js.map} +0 -0
  107. /package/dist/{typescript-OBOFG5TQ.js.map → typescript-GJ4FX6G3.js.map} +0 -0
  108. /package/dist/{wrap-ansi-HN7FYF5E.js.map → wrap-ansi-H3UZAKUB.js.map} +0 -0
  109. /package/dist/{yaml-XTRA2PRF.js.map → yaml-FZJ4633S.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  if (typeof process === 'object' && process !== null &&
2
2
  process.env !== null && typeof process.env === 'object') {
3
3
  process.env.DD_GIT_REPOSITORY_URL = 'https://token@github.com/superblocksteam/superblocks.git';
4
- process.env.DD_GIT_COMMIT_SHA = '3c7c52d03ca3ae1d999f785cc996a4fe7fd3e5a2';
4
+ process.env.DD_GIT_COMMIT_SHA = 'c1adb1813d85d91d7b88389107ac6cfff9ba6513';
5
5
  }
6
6
  import { createRequire as $dd_createRequire } from 'module';
7
7
  import { fileURLToPath as $dd_fileURLToPath } from 'url';
@@ -13,7 +13,7 @@ globalThis.__dirname ??= $dd_dirname(globalThis.__filename);
13
13
  import {
14
14
  __commonJS,
15
15
  init_cjs_shims
16
- } from "./chunk-EGM37OQF.js";
16
+ } from "./chunk-6VFLSGDN.js";
17
17
 
18
18
  // ../../../../node_modules/.pnpm/lru-cache@10.4.3/node_modules/lru-cache/dist/commonjs/index.js
19
19
  var require_commonjs = __commonJS({
@@ -1396,4 +1396,4 @@ var require_commonjs = __commonJS({
1396
1396
  export {
1397
1397
  require_commonjs
1398
1398
  };
1399
- //# sourceMappingURL=chunk-IAOLN6TE.js.map
1399
+ //# sourceMappingURL=chunk-VZBG3KKO.js.map
@@ -1,7 +1,7 @@
1
1
  if (typeof process === 'object' && process !== null &&
2
2
  process.env !== null && typeof process.env === 'object') {
3
3
  process.env.DD_GIT_REPOSITORY_URL = 'https://token@github.com/superblocksteam/superblocks.git';
4
- process.env.DD_GIT_COMMIT_SHA = '3c7c52d03ca3ae1d999f785cc996a4fe7fd3e5a2';
4
+ process.env.DD_GIT_COMMIT_SHA = 'c1adb1813d85d91d7b88389107ac6cfff9ba6513';
5
5
  }
6
6
  import { createRequire as $dd_createRequire } from 'module';
7
7
  import { fileURLToPath as $dd_fileURLToPath } from 'url';
@@ -14,7 +14,7 @@ import {
14
14
  __commonJS,
15
15
  __toESM,
16
16
  init_cjs_shims
17
- } from "./chunk-EGM37OQF.js";
17
+ } from "./chunk-6VFLSGDN.js";
18
18
 
19
19
  // ../../../../node_modules/.pnpm/eastasianwidth@0.2.0/node_modules/eastasianwidth/eastasianwidth.js
20
20
  var require_eastasianwidth = __commonJS({
@@ -371,4 +371,4 @@ export {
371
371
  stringWidth,
372
372
  ansi_styles_default
373
373
  };
374
- //# sourceMappingURL=chunk-VSBRAS53.js.map
374
+ //# sourceMappingURL=chunk-W25HYL6C.js.map
@@ -1,7 +1,7 @@
1
1
  if (typeof process === 'object' && process !== null &&
2
2
  process.env !== null && typeof process.env === 'object') {
3
3
  process.env.DD_GIT_REPOSITORY_URL = 'https://token@github.com/superblocksteam/superblocks.git';
4
- process.env.DD_GIT_COMMIT_SHA = '3c7c52d03ca3ae1d999f785cc996a4fe7fd3e5a2';
4
+ process.env.DD_GIT_COMMIT_SHA = 'c1adb1813d85d91d7b88389107ac6cfff9ba6513';
5
5
  }
6
6
  import { createRequire as $dd_createRequire } from 'module';
7
7
  import { fileURLToPath as $dd_fileURLToPath } from 'url';
@@ -13,7 +13,7 @@ globalThis.__dirname ??= $dd_dirname(globalThis.__filename);
13
13
  import {
14
14
  __commonJS,
15
15
  init_cjs_shims
16
- } from "./chunk-EGM37OQF.js";
16
+ } from "./chunk-6VFLSGDN.js";
17
17
 
18
18
  // ../../../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js
19
19
  var require_picocolors = __commonJS({
@@ -1025,4 +1025,4 @@ export {
1025
1025
  require_valid,
1026
1026
  require_clean
1027
1027
  };
1028
- //# sourceMappingURL=chunk-PBNML3U3.js.map
1028
+ //# sourceMappingURL=chunk-XBHQTUMW.js.map
@@ -1,7 +1,7 @@
1
1
  if (typeof process === 'object' && process !== null &&
2
2
  process.env !== null && typeof process.env === 'object') {
3
3
  process.env.DD_GIT_REPOSITORY_URL = 'https://token@github.com/superblocksteam/superblocks.git';
4
- process.env.DD_GIT_COMMIT_SHA = '3c7c52d03ca3ae1d999f785cc996a4fe7fd3e5a2';
4
+ process.env.DD_GIT_COMMIT_SHA = 'c1adb1813d85d91d7b88389107ac6cfff9ba6513';
5
5
  }
6
6
  import { createRequire as $dd_createRequire } from 'module';
7
7
  import { fileURLToPath as $dd_fileURLToPath } from 'url';
@@ -15,7 +15,7 @@ import {
15
15
  __esm,
16
16
  __require,
17
17
  init_cjs_shims
18
- } from "./chunk-EGM37OQF.js";
18
+ } from "./chunk-6VFLSGDN.js";
19
19
 
20
20
  // ../../../../node_modules/.pnpm/universalify@2.0.1/node_modules/universalify/index.js
21
21
  var require_universalify = __commonJS({
@@ -12941,4 +12941,4 @@ lodash-es/lodash.js:
12941
12941
  * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
12942
12942
  *)
12943
12943
  */
12944
- //# sourceMappingURL=chunk-ZKLX2TF6.js.map
12944
+ //# sourceMappingURL=chunk-Z5A7GY7B.js.map
@@ -1,7 +1,7 @@
1
1
  if (typeof process === 'object' && process !== null &&
2
2
  process.env !== null && typeof process.env === 'object') {
3
3
  process.env.DD_GIT_REPOSITORY_URL = 'https://token@github.com/superblocksteam/superblocks.git';
4
- process.env.DD_GIT_COMMIT_SHA = '3c7c52d03ca3ae1d999f785cc996a4fe7fd3e5a2';
4
+ process.env.DD_GIT_COMMIT_SHA = 'c1adb1813d85d91d7b88389107ac6cfff9ba6513';
5
5
  }
6
6
  import { createRequire as $dd_createRequire } from 'module';
7
7
  import { fileURLToPath as $dd_fileURLToPath } from 'url';
@@ -12,13 +12,13 @@ globalThis.__dirname ??= $dd_dirname(globalThis.__filename);
12
12
 
13
13
  import {
14
14
  sliceAnsi
15
- } from "./chunk-ETHLIHQN.js";
15
+ } from "./chunk-ISZCKU4B.js";
16
16
  import {
17
17
  stringWidth
18
- } from "./chunk-VSBRAS53.js";
18
+ } from "./chunk-W25HYL6C.js";
19
19
  import {
20
20
  init_cjs_shims
21
- } from "./chunk-EGM37OQF.js";
21
+ } from "./chunk-6VFLSGDN.js";
22
22
 
23
23
  // ../../../../node_modules/.pnpm/cli-truncate@3.1.0/node_modules/cli-truncate/index.js
24
24
  init_cjs_shims();
@@ -99,4 +99,4 @@ function cliTruncate(text, columns, options) {
99
99
  export {
100
100
  cliTruncate as default
101
101
  };
102
- //# sourceMappingURL=cli-truncate-SGCWVQL7.js.map
102
+ //# sourceMappingURL=cli-truncate-GHVTGJXO.js.map
@@ -1,7 +1,7 @@
1
1
  if (typeof process === 'object' && process !== null &&
2
2
  process.env !== null && typeof process.env === 'object') {
3
3
  process.env.DD_GIT_REPOSITORY_URL = 'https://token@github.com/superblocksteam/superblocks.git';
4
- process.env.DD_GIT_COMMIT_SHA = '3c7c52d03ca3ae1d999f785cc996a4fe7fd3e5a2';
4
+ process.env.DD_GIT_COMMIT_SHA = 'c1adb1813d85d91d7b88389107ac6cfff9ba6513';
5
5
  }
6
6
  import { createRequire as $dd_createRequire } from 'module';
7
7
  import { fileURLToPath as $dd_fileURLToPath } from 'url';
@@ -12,20 +12,210 @@ globalThis.__dirname ??= $dd_dirname(globalThis.__filename);
12
12
 
13
13
  import {
14
14
  init_cjs_shims
15
- } from "../chunk-EGM37OQF.js";
15
+ } from "../chunk-6VFLSGDN.js";
16
16
 
17
17
  // src/commands/dev-parent.mts
18
18
  init_cjs_shims();
19
19
  import * as child_process from "node:child_process";
20
- import * as fs from "node:fs";
20
+ import * as fs2 from "node:fs";
21
21
  import * as os from "node:os";
22
22
  import { resolve } from "node:path";
23
+
24
+ // src/commands/restart-template-env.mts
25
+ init_cjs_shims();
26
+ import fs from "node:fs";
27
+ import path from "node:path";
28
+ var RESTART_SUPERVISED_ENV = "SUPERBLOCKS_RESTART_SUPERVISED";
29
+ var RESTART_REASON_ENV = "SUPERBLOCKS_RESTART_REASON";
30
+ var RESTART_REASON_FLIP_RESTART = "flip_restart";
31
+ function readTemplateMarker(appRootDir) {
32
+ try {
33
+ const value = fs.readFileSync(path.join(appRootDir, ".sb_template"), "utf-8").trim();
34
+ return value || null;
35
+ } catch {
36
+ return null;
37
+ }
38
+ }
39
+ function resolveRestartChildEnv(baseEnv, templateName) {
40
+ const next = { ...baseEnv };
41
+ const currentTemplate = baseEnv.SUPERBLOCKS_APP_TEMPLATE_NAME ?? baseEnv.TEMPLATE_NAME;
42
+ if (templateName && templateName !== currentTemplate) {
43
+ next.SUPERBLOCKS_APP_TEMPLATE_NAME = templateName;
44
+ next.TEMPLATE_NAME = templateName;
45
+ delete next.SUPERBLOCKS_APP_ENTRY_POINT;
46
+ }
47
+ return next;
48
+ }
49
+
50
+ // src/commands/parent-otlp-metric.mts
51
+ init_cjs_shims();
52
+ import * as http from "node:http";
53
+ import * as https from "node:https";
54
+ var SERVICE_NAME = "sdk-dev-server";
55
+ var SCOPE_NAME = "superblocks.cli.dev-parent";
56
+ var DEV_SERVER_RESTART_COMPLETED_METRIC = "dev_server_child_respawn_completed_total";
57
+ var DEV_SERVER_RESTART_COMPLETED_DESCRIPTION = "Count of dev-server child respawns that reached boot after an in-place restart, by reason.";
58
+ var DEFAULT_TIMEOUT_MS = 1e3;
59
+ function resolveOtlpMetricsUrl(env = process.env) {
60
+ const collector = env.SUPERBLOCKS_OTEL_COLLECTOR_URL;
61
+ if (collector) {
62
+ const base = collector.replace(/\/v1\/(traces|metrics|logs)$/, "").replace(/\/+$/, "");
63
+ return `${base}/v1/metrics`;
64
+ }
65
+ const baseUrl = env.SUPERBLOCKS_BASE_URL;
66
+ if (baseUrl) {
67
+ try {
68
+ return `${new URL(baseUrl).origin}/api/v1/metrics`;
69
+ } catch {
70
+ return null;
71
+ }
72
+ }
73
+ return null;
74
+ }
75
+ function deploymentEnvironmentFromBaseUrl(env = process.env) {
76
+ const baseUrl = env.SUPERBLOCKS_BASE_URL;
77
+ if (!baseUrl) {
78
+ return "other";
79
+ }
80
+ let hostname;
81
+ try {
82
+ hostname = new URL(baseUrl).hostname;
83
+ } catch {
84
+ return "other";
85
+ }
86
+ if (hostname.match(/^app\.superblocks(?:hq)?\.com/)) return "prod";
87
+ if (hostname.match(/^eu\.superblocks(?:hq)?\.com/)) return "prod-eu";
88
+ if (hostname.match(/^staging\.superblocks(?:hq)?\.com/)) return "staging";
89
+ if (hostname.match(/^dev\.superblocks(?:hq)?\.com/)) return "dev";
90
+ if (hostname.match(/^pr-[0-9]+\.superblocks(?:hq)?\.dev/)) return "ephemeral";
91
+ if (hostname.match(/^localhost/)) return "local";
92
+ return "other";
93
+ }
94
+ function toAttributeArray(attributes) {
95
+ return Object.entries(attributes).map(([key, value]) => ({
96
+ key,
97
+ value: { stringValue: value }
98
+ }));
99
+ }
100
+ function buildDeltaCounterPayload(opts) {
101
+ const nowNano = BigInt(opts.nowMs ?? Date.now()) * 1000000n;
102
+ const startNano = nowNano - 1000000n;
103
+ return {
104
+ resourceMetrics: [
105
+ {
106
+ resource: {
107
+ attributes: toAttributeArray({
108
+ "service.name": opts.serviceName ?? SERVICE_NAME,
109
+ "deployment.environment.name": opts.environment
110
+ })
111
+ },
112
+ scopeMetrics: [
113
+ {
114
+ scope: { name: opts.scopeName ?? SCOPE_NAME },
115
+ metrics: [
116
+ {
117
+ name: opts.name,
118
+ description: opts.description,
119
+ sum: {
120
+ aggregationTemporality: 1,
121
+ // AGGREGATION_TEMPORALITY_DELTA
122
+ isMonotonic: true,
123
+ dataPoints: [
124
+ {
125
+ attributes: toAttributeArray(opts.attributes),
126
+ startTimeUnixNano: startNano.toString(),
127
+ timeUnixNano: nowNano.toString(),
128
+ asInt: "1"
129
+ }
130
+ ]
131
+ }
132
+ }
133
+ ]
134
+ }
135
+ ]
136
+ }
137
+ ]
138
+ };
139
+ }
140
+ function emitOtlpCounter(opts) {
141
+ const env = opts.env ?? process.env;
142
+ const url = resolveOtlpMetricsUrl(env);
143
+ if (!url) {
144
+ return Promise.resolve();
145
+ }
146
+ let parsed;
147
+ try {
148
+ parsed = new URL(url);
149
+ } catch {
150
+ return Promise.resolve();
151
+ }
152
+ const body = JSON.stringify(
153
+ buildDeltaCounterPayload({
154
+ name: opts.name,
155
+ description: opts.description,
156
+ attributes: opts.attributes,
157
+ environment: deploymentEnvironmentFromBaseUrl(env)
158
+ })
159
+ );
160
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
161
+ const unref = opts.unref ?? true;
162
+ const transport = parsed.protocol === "https:" ? https : http;
163
+ return new Promise((resolve2) => {
164
+ let settled = false;
165
+ const done = () => {
166
+ if (settled) return;
167
+ settled = true;
168
+ resolve2();
169
+ };
170
+ const req = transport.request(
171
+ {
172
+ protocol: parsed.protocol,
173
+ hostname: parsed.hostname,
174
+ port: parsed.port,
175
+ path: parsed.pathname + parsed.search,
176
+ method: "POST",
177
+ headers: {
178
+ "content-type": "application/json",
179
+ "content-length": Buffer.byteLength(body)
180
+ }
181
+ },
182
+ (res) => {
183
+ res.on("data", () => {
184
+ });
185
+ res.on("end", done);
186
+ res.on("error", done);
187
+ }
188
+ );
189
+ req.on("error", done);
190
+ req.setTimeout(timeoutMs, () => {
191
+ req.destroy();
192
+ done();
193
+ });
194
+ if (unref) {
195
+ req.on("socket", (socket) => socket.unref());
196
+ }
197
+ req.end(body);
198
+ });
199
+ }
200
+ function emitFlipRestartCompletedMetric(opts) {
201
+ return emitOtlpCounter({
202
+ name: DEV_SERVER_RESTART_COMPLETED_METRIC,
203
+ description: DEV_SERVER_RESTART_COMPLETED_DESCRIPTION,
204
+ attributes: { reason: RESTART_REASON_FLIP_RESTART },
205
+ env: opts?.env,
206
+ timeoutMs: opts?.timeoutMs,
207
+ unref: opts?.unref
208
+ });
209
+ }
210
+
211
+ // src/commands/dev-parent.mts
23
212
  var RESTART_EXIT_CODE = 98;
24
213
  var AUTO_UPGRADE_EXIT_CODE = 99;
25
214
  var signalHandlers = {};
26
215
  var isCSB = process.env.SUPERBLOCKS_IS_CSB === "true";
27
216
  var PARENT_INFO_LOG = {
28
217
  childReadyForToken: "Child is ready to receive token",
218
+ childBootedAfterRestart: "Dev server child booted after in-place restart",
29
219
  devServerCompletedAutoUpgrade: "Dev server completed: auto-upgrade",
30
220
  devServerCompletedExit: "Dev server completed: exit",
31
221
  devServerCompletedFailure: "Dev server completed: failure",
@@ -34,6 +224,7 @@ var PARENT_INFO_LOG = {
34
224
  devServerExitedWithFailure: "Dev server exited with failure",
35
225
  devServerExitedSuccessfully: "Dev server exited successfully",
36
226
  devServerRestarting: "Dev server restarting",
227
+ devServerRestartingWithoutTemplateOverride: "Dev server restarting \u2014 .sb_template not found, pod env unchanged",
37
228
  noTokenAwaitAuthHotReload: "No token available, child will need to wait for auth hot-reload",
38
229
  sendingInitialTokenToChild: "Sending initial token to child",
39
230
  tokenUpdatedFromChild: "Token updated from child process"
@@ -131,16 +322,18 @@ function getParentAuthFilePath() {
131
322
  function readTokenFromAuthFile() {
132
323
  try {
133
324
  const authFilePath = getParentAuthFilePath();
134
- if (fs.existsSync(authFilePath)) {
135
- const authData = JSON.parse(fs.readFileSync(authFilePath, "utf-8"));
325
+ if (fs2.existsSync(authFilePath)) {
326
+ const authData = JSON.parse(fs2.readFileSync(authFilePath, "utf-8"));
136
327
  return authData.token || "";
137
328
  }
138
329
  } catch {
139
330
  }
140
331
  return "";
141
332
  }
142
- async function spawnAndWaitForChild(previousRunResult, options, currentToken) {
333
+ async function spawnAndWaitForChild(previousRunResult, previousRestartReason, options, currentToken) {
143
334
  let token = currentToken;
335
+ let childRestartReason = null;
336
+ const isFlipRespawn = previousRunResult === "restart" && previousRestartReason === RESTART_REASON_FLIP_RESTART;
144
337
  return new Promise((resolvePromise) => {
145
338
  const originalArgs = process.argv.slice(1);
146
339
  let processArgs;
@@ -165,17 +358,31 @@ async function spawnAndWaitForChild(previousRunResult, options, currentToken) {
165
358
  } else {
166
359
  processArgs = [...originalArgs, "--child"];
167
360
  }
361
+ const templateMarker = readTemplateMarker(process.cwd());
362
+ if (isFlipRespawn && templateMarker === null) {
363
+ log(PARENT_INFO_LOG.devServerRestartingWithoutTemplateOverride);
364
+ }
365
+ const supervisedEnv = {
366
+ ...process.env,
367
+ [RESTART_SUPERVISED_ENV]: "1"
368
+ };
369
+ if (isFlipRespawn) {
370
+ supervisedEnv[RESTART_REASON_ENV] = RESTART_REASON_FLIP_RESTART;
371
+ } else {
372
+ delete supervisedEnv[RESTART_REASON_ENV];
373
+ }
374
+ const childEnv = resolveRestartChildEnv(supervisedEnv, templateMarker);
168
375
  const child = child_process.spawn(process.execPath, processArgs, {
169
376
  detached: false,
170
377
  stdio: ["inherit", "inherit", "inherit", "ipc"],
171
- env: { ...process.env }
378
+ env: childEnv
172
379
  });
173
380
  let spawnErrorOccurred = false;
174
381
  child.on("error", (error) => {
175
382
  spawnErrorOccurred = true;
176
383
  cleanupSignalHandlers();
177
384
  logError(PARENT_ERROR_LOG.failedToSpawnChildProcess, error);
178
- resolvePromise({ result: "failure", token });
385
+ resolvePromise({ result: "failure", token, restartReason: null });
179
386
  });
180
387
  child.on("message", (message) => {
181
388
  if (message.type === "ready") {
@@ -193,6 +400,13 @@ async function spawnAndWaitForChild(previousRunResult, options, currentToken) {
193
400
  } else if (message.type === "tokenUpdate" && message.token) {
194
401
  token = message.token;
195
402
  log(PARENT_INFO_LOG.tokenUpdatedFromChild);
403
+ } else if (message.type === "devServerStarted") {
404
+ if (isFlipRespawn) {
405
+ log(PARENT_INFO_LOG.childBootedAfterRestart);
406
+ void emitFlipRestartCompletedMetric();
407
+ }
408
+ } else if (message.type === "restartReason" && message.reason) {
409
+ childRestartReason = message.reason;
196
410
  }
197
411
  });
198
412
  setupSignalHandlers(child);
@@ -204,16 +418,20 @@ async function spawnAndWaitForChild(previousRunResult, options, currentToken) {
204
418
  const result = classifyChildExit(code);
205
419
  if (result === "restart") {
206
420
  log(PARENT_INFO_LOG.devServerRestarting);
207
- resolvePromise({ result: "restart", token });
421
+ resolvePromise({
422
+ result: "restart",
423
+ token,
424
+ restartReason: childRestartReason
425
+ });
208
426
  } else if (result === "auto-upgrade") {
209
427
  log(PARENT_INFO_LOG.devServerExitedForAutoUpgrade);
210
- resolvePromise({ result: "auto-upgrade", token });
428
+ resolvePromise({ result: "auto-upgrade", token, restartReason: null });
211
429
  } else if (result === "exit") {
212
430
  log(PARENT_INFO_LOG.devServerExitedSuccessfully);
213
- resolvePromise({ result: "exit", token });
431
+ resolvePromise({ result: "exit", token, restartReason: null });
214
432
  } else {
215
433
  log(PARENT_INFO_LOG.devServerExitedWithFailure);
216
- resolvePromise({ result: "failure", token });
434
+ resolvePromise({ result: "failure", token, restartReason: null });
217
435
  }
218
436
  });
219
437
  });
@@ -231,19 +449,23 @@ async function runAsLightweightParent(options) {
231
449
  }
232
450
  let currentToken = readTokenFromAuthFile();
233
451
  let previousRunResult = null;
452
+ let previousRestartReason = null;
234
453
  do {
235
454
  try {
236
- const { result, token } = await spawnAndWaitForChild(
455
+ const { result, token, restartReason } = await spawnAndWaitForChild(
237
456
  previousRunResult,
457
+ previousRestartReason,
238
458
  options,
239
459
  currentToken
240
460
  );
241
461
  logDevServerCompleted(result);
242
462
  previousRunResult = result;
463
+ previousRestartReason = restartReason;
243
464
  currentToken = token;
244
465
  } catch (error) {
245
466
  logError(PARENT_ERROR_LOG.errorInParentProcess, error);
246
467
  previousRunResult = "failure";
468
+ previousRestartReason = null;
247
469
  }
248
470
  } while (previousRunResult === "restart" || previousRunResult === "auto-upgrade");
249
471
  if (previousRunResult === "failure") {
@@ -251,6 +473,7 @@ async function runAsLightweightParent(options) {
251
473
  }
252
474
  }
253
475
  export {
476
+ RESTART_EXIT_CODE,
254
477
  classifyChildExit,
255
478
  runAsLightweightParent
256
479
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/commands/dev-parent.mts"],
4
- "sourcesContent": ["/**\n * Lightweight parent process wrapper for the dev command.\n *\n * CRITICAL: This file must NOT import from @superblocksteam/sdk or any heavy modules.\n * It uses only Node.js builtins to keep memory under 100MB. That constraint exists so\n * the parent stays small and fast (the full CLI + SDK would cost on the order of GBs\n * of memory if loaded here).\n *\n * Because of that, we **cannot** depend on the shared telemetry package and its safe\n * logger / redaction pipeline \u2014 pulling it in would defeat the purpose of this wrapper.\n * CSB / live-edit still ship parent lines on stdout for log collectors, so we enforce\n * **static strings only**: add new parent log text only as entries in\n * `PARENT_INFO_LOG` / `PARENT_ERROR_LOG` and pass those constants into `log` /\n * `logError`, which TypeScript types so accidental interpolation is a compile error.\n * For CSB JSON errors we also omit dynamic `error.message` / `stack` (Datadog path);\n * local non-CSB runs keep printing the real `Error` on stderr for debugging.\n *\n * The parent process only needs to:\n * 1. Spawn child with --child flag\n * 2. Forward signals\n * 3. Handle IPC for token management\n * 4. Handle restart/auto-upgrade exit codes\n */\n\nimport * as child_process from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport { resolve } from \"node:path\";\n\n// Exit codes must match @superblocksteam/sdk values\nconst RESTART_EXIT_CODE = 98;\nconst AUTO_UPGRADE_EXIT_CODE = 99;\n\ntype ChildToParentMessage =\n | { type: \"ready\" }\n | { type: \"tokenUpdate\"; token: string };\n\ntype ParentToChildMessage =\n | { type: \"initialToken\"; token: string }\n | { type: \"noToken\" };\n\ntype RunResult = null | \"restart\" | \"auto-upgrade\" | \"exit\" | \"failure\";\n\ninterface ParentOptions {\n port?: number;\n uploadFirst?: boolean;\n downloadFirst?: boolean;\n forceTakeover?: boolean;\n skipAutoUpgrade?: boolean;\n forceAutoUpgrade?: boolean;\n}\n\nlet signalHandlers: Record<string, NodeJS.SignalsListener> = {};\n\nconst isCSB = process.env.SUPERBLOCKS_IS_CSB === \"true\";\n\n/** Fixed parent info lines \u2014 only these may be shipped to CSB log collectors (Datadog). */\nconst PARENT_INFO_LOG = {\n childReadyForToken: \"Child is ready to receive token\",\n devServerCompletedAutoUpgrade: \"Dev server completed: auto-upgrade\",\n devServerCompletedExit: \"Dev server completed: exit\",\n devServerCompletedFailure: \"Dev server completed: failure\",\n devServerCompletedRestart: \"Dev server completed: restart\",\n devServerExitedForAutoUpgrade: \"Dev server exited due to automatic upgrade\",\n devServerExitedWithFailure: \"Dev server exited with failure\",\n devServerExitedSuccessfully: \"Dev server exited successfully\",\n devServerRestarting: \"Dev server restarting\",\n noTokenAwaitAuthHotReload:\n \"No token available, child will need to wait for auth hot-reload\",\n sendingInitialTokenToChild: \"Sending initial token to child\",\n tokenUpdatedFromChild: \"Token updated from child process\",\n} as const;\n\ntype ParentInfoLog = (typeof PARENT_INFO_LOG)[keyof typeof PARENT_INFO_LOG];\n\n/** Fixed parent error lines \u2014 never interpolate dynamic values into these strings. */\nconst PARENT_ERROR_LOG = {\n errorInParentProcess: \"Error in parent process:\",\n errorMissingUploadOrDownloadFirst:\n \"Error: This command requires either the --upload-first or --download-first flag\",\n errorSkipAndForceAutoUpgrade:\n \"Error: Use either --skip-auto-upgrade or --force-auto-upgrade flag, but not both\",\n failedToSpawnChildProcess: \"Failed to spawn child process\",\n} as const;\n\ntype ParentErrorLog = (typeof PARENT_ERROR_LOG)[keyof typeof PARENT_ERROR_LOG];\n\nfunction log(message: ParentInfoLog): void {\n if (isCSB) {\n console.log(\n JSON.stringify({\n level: \"info\",\n message: `[dev] ${message}`,\n timestamp: new Date().toISOString(),\n process: \"parent\",\n }),\n );\n } else {\n console.log(`[dev] ${message}`);\n }\n}\n\n/**\n * CSB / live-edit: emit only fixed `message` fields to stdout (no error text or stack)\n * so log pipelines never receive free-form strings that could contain secrets or PII.\n * Local dev (`!isCSB`) still prints the real Error to stderr for debugging.\n */\nfunction logError(message: ParentErrorLog, error?: unknown): void {\n if (isCSB) {\n console.error(\n JSON.stringify({\n level: \"error\",\n message,\n timestamp: new Date().toISOString(),\n process: \"parent\",\n }),\n );\n } else if (typeof error !== \"undefined\") {\n console.error(message, error);\n } else {\n console.error(message);\n }\n}\n\nfunction logDevServerCompleted(result: Exclude<RunResult, null>): void {\n switch (result) {\n case \"auto-upgrade\":\n log(PARENT_INFO_LOG.devServerCompletedAutoUpgrade);\n return;\n case \"exit\":\n log(PARENT_INFO_LOG.devServerCompletedExit);\n return;\n case \"failure\":\n log(PARENT_INFO_LOG.devServerCompletedFailure);\n return;\n case \"restart\":\n log(PARENT_INFO_LOG.devServerCompletedRestart);\n return;\n default:\n result satisfies never;\n }\n}\n\nexport function classifyChildExit(\n code: number | null,\n): Exclude<RunResult, null> {\n if (code === RESTART_EXIT_CODE) {\n return \"restart\";\n }\n if (code === AUTO_UPGRADE_EXIT_CODE) {\n return \"auto-upgrade\";\n }\n if (code === 0) {\n return \"exit\";\n }\n return \"failure\";\n}\n\nfunction setupSignalHandlers(child: child_process.ChildProcess): void {\n // Remove old handlers first to prevent accumulation\n for (const [signal, handler] of Object.entries(signalHandlers)) {\n process.off(signal as NodeJS.Signals, handler);\n }\n\n signalHandlers = {\n SIGINT: () => child.kill(\"SIGINT\"),\n SIGHUP: () => child.kill(\"SIGHUP\"),\n SIGTERM: () => child.kill(\"SIGTERM\"),\n SIGQUIT: () => child.kill(\"SIGQUIT\"),\n SIGABRT: () => child.kill(\"SIGABRT\"),\n };\n\n for (const [signal, handler] of Object.entries(signalHandlers)) {\n process.on(signal as NodeJS.Signals, handler);\n }\n}\n\nfunction cleanupSignalHandlers(): void {\n for (const [signal, handler] of Object.entries(signalHandlers)) {\n process.off(signal as NodeJS.Signals, handler);\n }\n signalHandlers = {};\n}\n\nfunction getParentAuthFilePath(): string {\n return process.env.SUPERBLOCKS_AUTH_FILE\n ? resolve(process.env.SUPERBLOCKS_AUTH_FILE)\n : resolve(os.homedir(), \".superblocks\", \"auth.json\");\n}\n\nfunction readTokenFromAuthFile(): string {\n try {\n const authFilePath = getParentAuthFilePath();\n if (fs.existsSync(authFilePath)) {\n const authData = JSON.parse(fs.readFileSync(authFilePath, \"utf-8\"));\n return authData.token || \"\";\n }\n } catch {\n // Ignore errors reading auth file\n }\n return \"\";\n}\n\nasync function spawnAndWaitForChild(\n previousRunResult: RunResult,\n options: ParentOptions,\n currentToken: string,\n): Promise<{ result: Exclude<RunResult, null>; token: string }> {\n let token = currentToken;\n\n return new Promise((resolvePromise) => {\n const originalArgs = process.argv.slice(1);\n let processArgs: string[];\n\n if (previousRunResult === \"restart\") {\n const sliceUntil = originalArgs.findIndex((arg) => arg === \"dev\");\n if (sliceUntil === -1) {\n throw new Error(\"dev command not found in args\");\n }\n const baseArgs = originalArgs.slice(0, sliceUntil + 1);\n processArgs = [\n ...baseArgs,\n \"--child\",\n \"--download-first\",\n ...(typeof options.port === \"number\" && !Number.isNaN(options.port)\n ? [`--port=${options.port}`]\n : []),\n ];\n } else if (previousRunResult === \"auto-upgrade\") {\n processArgs = [\n ...originalArgs.filter((arg) => arg !== \"--child\"),\n \"--child\",\n \"--skip-auto-upgrade\",\n ];\n } else {\n processArgs = [...originalArgs, \"--child\"];\n }\n\n const child = child_process.spawn(process.execPath, processArgs, {\n detached: false,\n stdio: [\"inherit\", \"inherit\", \"inherit\", \"ipc\"],\n env: { ...process.env },\n });\n\n let spawnErrorOccurred = false;\n\n // Handle spawn errors to prevent hanging\n child.on(\"error\", (error) => {\n spawnErrorOccurred = true;\n cleanupSignalHandlers();\n logError(PARENT_ERROR_LOG.failedToSpawnChildProcess, error);\n resolvePromise({ result: \"failure\", token });\n });\n\n // IPC message handling\n child.on(\"message\", (message: ChildToParentMessage) => {\n if (message.type === \"ready\") {\n log(PARENT_INFO_LOG.childReadyForToken);\n if (token) {\n log(PARENT_INFO_LOG.sendingInitialTokenToChild);\n child.send({\n type: \"initialToken\",\n token,\n } satisfies ParentToChildMessage);\n } else {\n log(PARENT_INFO_LOG.noTokenAwaitAuthHotReload);\n child.send({ type: \"noToken\" } satisfies ParentToChildMessage);\n }\n } else if (message.type === \"tokenUpdate\" && message.token) {\n token = message.token;\n log(PARENT_INFO_LOG.tokenUpdatedFromChild);\n }\n });\n\n setupSignalHandlers(child);\n\n child.on(\"exit\", (code) => {\n cleanupSignalHandlers();\n if (spawnErrorOccurred) {\n return;\n }\n\n const result = classifyChildExit(code);\n\n if (result === \"restart\") {\n log(PARENT_INFO_LOG.devServerRestarting);\n resolvePromise({ result: \"restart\", token });\n } else if (result === \"auto-upgrade\") {\n log(PARENT_INFO_LOG.devServerExitedForAutoUpgrade);\n resolvePromise({ result: \"auto-upgrade\", token });\n } else if (result === \"exit\") {\n log(PARENT_INFO_LOG.devServerExitedSuccessfully);\n resolvePromise({ result: \"exit\", token });\n } else {\n log(PARENT_INFO_LOG.devServerExitedWithFailure);\n resolvePromise({ result: \"failure\", token });\n }\n });\n });\n}\n\nexport async function runAsLightweightParent(\n options: ParentOptions,\n): Promise<void> {\n // Validate flags\n if (!options.uploadFirst && !options.downloadFirst) {\n logError(PARENT_ERROR_LOG.errorMissingUploadOrDownloadFirst);\n process.exitCode = 1;\n return;\n }\n if (options.skipAutoUpgrade && options.forceAutoUpgrade) {\n logError(PARENT_ERROR_LOG.errorSkipAndForceAutoUpgrade);\n process.exitCode = 1;\n return;\n }\n\n let currentToken = readTokenFromAuthFile();\n let previousRunResult: RunResult = null;\n\n do {\n try {\n const { result, token } = await spawnAndWaitForChild(\n previousRunResult,\n options,\n currentToken,\n );\n logDevServerCompleted(result);\n previousRunResult = result;\n currentToken = token;\n } catch (error) {\n logError(PARENT_ERROR_LOG.errorInParentProcess, error);\n previousRunResult = \"failure\";\n }\n } while (\n previousRunResult === \"restart\" ||\n previousRunResult === \"auto-upgrade\"\n );\n\n if (previousRunResult === \"failure\") {\n process.exitCode = 1;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
3
+ "sources": ["../../src/commands/dev-parent.mts", "../../src/commands/restart-template-env.mts", "../../src/commands/parent-otlp-metric.mts"],
4
+ "sourcesContent": ["/**\n * Lightweight parent process wrapper for the dev command.\n *\n * CRITICAL: This file must NOT import from @superblocksteam/sdk or any heavy modules.\n * It uses only Node.js builtins to keep memory under 100MB. That constraint exists so\n * the parent stays small and fast (the full CLI + SDK would cost on the order of GBs\n * of memory if loaded here).\n *\n * Because of that, we **cannot** depend on the shared telemetry package and its safe\n * logger / redaction pipeline \u2014 pulling it in would defeat the purpose of this wrapper.\n * CSB / live-edit still ship parent lines on stdout for log collectors, so we enforce\n * **static strings only**: add new parent log text only as entries in\n * `PARENT_INFO_LOG` / `PARENT_ERROR_LOG` and pass those constants into `log` /\n * `logError`, which TypeScript types so accidental interpolation is a compile error.\n * For CSB JSON errors we also omit dynamic `error.message` / `stack` (Datadog path);\n * local non-CSB runs keep printing the real `Error` on stderr for debugging.\n *\n * The parent process only needs to:\n * 1. Spawn child with --child flag\n * 2. Forward signals\n * 3. Handle IPC for token management\n * 4. Handle restart/auto-upgrade exit codes\n */\n\nimport * as child_process from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport { resolve } from \"node:path\";\n\n// `restart-template-env.mjs` depends only on `node:fs` / `node:path`, so it is\n// safe to import here without violating the lightweight-parent constraint above.\nimport {\n readTemplateMarker,\n resolveRestartChildEnv,\n RESTART_REASON_ENV,\n RESTART_REASON_FLIP_RESTART,\n RESTART_SUPERVISED_ENV,\n} from \"./restart-template-env.mjs\";\n// `parent-otlp-metric.mjs` depends only on `node:http`/`node:https` and\n// `restart-template-env.mjs`, so it is safe to import here without violating the\n// lightweight-parent constraint above.\nimport { emitFlipRestartCompletedMetric } from \"./parent-otlp-metric.mjs\";\n\n/**\n * Dev-server process exit-code contract\n * =====================================\n *\n * `superblocks dev` runs as a two-process tree: this lightweight parent\n * supervises a single `--child` process that hosts the real dev server (Vite +\n * Express). The child has no lifecycle back-channel other than its **process\n * exit code** \u2014 the parent reads it in the child `\"exit\"` handler below and\n * either respawns the child or stops the supervision loop.\n *\n * 0 Success. The dev server shut down gracefully (e.g.\n * inactivity timeout, /_sb_disconnect). Parent stops;\n * no respawn.\n * 98 RESTART_EXIT_CODE Restart in place. Emitted by the dev-server runtime\n * after an in-place v2->v3 template flip so the same\n * pod can boot the new template. Parent respawns the\n * child (with `--download-first`) in the same cwd.\n * 99 AUTO_UPGRADE_EXIT_CODE\n * Re-exec after self-upgrade. Emitted once the CLI has\n * upgraded its own on-disk binary. Parent respawns the\n * child with `--skip-auto-upgrade` so it runs on the\n * new binary without re-entering the upgrade path.\n * other (incl. 1) Fatal/uncaught error. Parent treats it as terminal\n * and stops; no respawn.\n *\n * Only 98 and 99 trigger a respawn; 0 and every other non-zero code end the\n * loop. The oclif `Dev` command carries a second copy of this supervision loop\n * (`spawnAndWaitForChild` in dev.mts) whose exit-code handling MUST stay in sync\n * with the table above. `RESTART_EXIT_CODE` is canonically defined in\n * `@superblocksteam/library-shared/restart-contract` and `AUTO_UPGRADE_EXIT_CODE`\n * in cli-replacement/automatic-upgrades.ts; this file must stay on `node:`\n * builtins only (see the memory note above), so it re-declares them here and\n * they MUST match. `RESTART_EXIT_CODE` is exported solely so a drift-guard test\n * can assert this copy still equals the canonical contract value.\n */\nexport const RESTART_EXIT_CODE = 98;\nconst AUTO_UPGRADE_EXIT_CODE = 99;\n\ntype ChildToParentMessage =\n | { type: \"ready\" }\n | { type: \"tokenUpdate\"; token: string }\n // Sent by the child once it reaches dev-server boot (createDevServer). The\n // parent uses this \u2014 not exit 98, which only proves the *previous* child asked\n // to restart \u2014 to record that an in-place restart actually completed.\n | { type: \"devServerStarted\" }\n // Sent by the migration self-restart seam (vite-plugin-file-sync\n // migration-routes) just before it exits RESTART_EXIT_CODE, declaring that\n // THIS exit 98 is a template flip. Exit 98 is NOT unique to flips \u2014 the\n // editor-driven /_sb_disconnect restart uses the same code \u2014 so the parent\n // labels a respawn `flip_restart` (and emits the completion metric) only when\n // the previous child sent this with reason `flip_restart`. A bare exit 98\n // surfaces as `cold_start`.\n | { type: \"restartReason\"; reason: string };\n\ntype ParentToChildMessage =\n | { type: \"initialToken\"; token: string }\n | { type: \"noToken\" };\n\ntype RunResult = null | \"restart\" | \"auto-upgrade\" | \"exit\" | \"failure\";\n\ninterface ParentOptions {\n port?: number;\n uploadFirst?: boolean;\n downloadFirst?: boolean;\n forceTakeover?: boolean;\n skipAutoUpgrade?: boolean;\n forceAutoUpgrade?: boolean;\n}\n\nlet signalHandlers: Record<string, NodeJS.SignalsListener> = {};\n\nconst isCSB = process.env.SUPERBLOCKS_IS_CSB === \"true\";\n\n/** Fixed parent info lines \u2014 only these may be shipped to CSB log collectors (Datadog). */\nconst PARENT_INFO_LOG = {\n childReadyForToken: \"Child is ready to receive token\",\n childBootedAfterRestart: \"Dev server child booted after in-place restart\",\n devServerCompletedAutoUpgrade: \"Dev server completed: auto-upgrade\",\n devServerCompletedExit: \"Dev server completed: exit\",\n devServerCompletedFailure: \"Dev server completed: failure\",\n devServerCompletedRestart: \"Dev server completed: restart\",\n devServerExitedForAutoUpgrade: \"Dev server exited due to automatic upgrade\",\n devServerExitedWithFailure: \"Dev server exited with failure\",\n devServerExitedSuccessfully: \"Dev server exited successfully\",\n devServerRestarting: \"Dev server restarting\",\n devServerRestartingWithoutTemplateOverride:\n \"Dev server restarting \u2014 .sb_template not found, pod env unchanged\",\n noTokenAwaitAuthHotReload:\n \"No token available, child will need to wait for auth hot-reload\",\n sendingInitialTokenToChild: \"Sending initial token to child\",\n tokenUpdatedFromChild: \"Token updated from child process\",\n} as const;\n\ntype ParentInfoLog = (typeof PARENT_INFO_LOG)[keyof typeof PARENT_INFO_LOG];\n\n/** Fixed parent error lines \u2014 never interpolate dynamic values into these strings. */\nconst PARENT_ERROR_LOG = {\n errorInParentProcess: \"Error in parent process:\",\n errorMissingUploadOrDownloadFirst:\n \"Error: This command requires either the --upload-first or --download-first flag\",\n errorSkipAndForceAutoUpgrade:\n \"Error: Use either --skip-auto-upgrade or --force-auto-upgrade flag, but not both\",\n failedToSpawnChildProcess: \"Failed to spawn child process\",\n} as const;\n\ntype ParentErrorLog = (typeof PARENT_ERROR_LOG)[keyof typeof PARENT_ERROR_LOG];\n\nfunction log(message: ParentInfoLog): void {\n if (isCSB) {\n console.log(\n JSON.stringify({\n level: \"info\",\n message: `[dev] ${message}`,\n timestamp: new Date().toISOString(),\n process: \"parent\",\n }),\n );\n } else {\n console.log(`[dev] ${message}`);\n }\n}\n\n/**\n * CSB / live-edit: emit only fixed `message` fields to stdout (no error text or stack)\n * so log pipelines never receive free-form strings that could contain secrets or PII.\n * Local dev (`!isCSB`) still prints the real Error to stderr for debugging.\n */\nfunction logError(message: ParentErrorLog, error?: unknown): void {\n if (isCSB) {\n console.error(\n JSON.stringify({\n level: \"error\",\n message,\n timestamp: new Date().toISOString(),\n process: \"parent\",\n }),\n );\n } else if (typeof error !== \"undefined\") {\n console.error(message, error);\n } else {\n console.error(message);\n }\n}\n\nfunction logDevServerCompleted(result: Exclude<RunResult, null>): void {\n switch (result) {\n case \"auto-upgrade\":\n log(PARENT_INFO_LOG.devServerCompletedAutoUpgrade);\n return;\n case \"exit\":\n log(PARENT_INFO_LOG.devServerCompletedExit);\n return;\n case \"failure\":\n log(PARENT_INFO_LOG.devServerCompletedFailure);\n return;\n case \"restart\":\n log(PARENT_INFO_LOG.devServerCompletedRestart);\n return;\n default:\n result satisfies never;\n }\n}\n\nexport function classifyChildExit(\n code: number | null,\n): Exclude<RunResult, null> {\n if (code === RESTART_EXIT_CODE) {\n return \"restart\";\n }\n if (code === AUTO_UPGRADE_EXIT_CODE) {\n return \"auto-upgrade\";\n }\n if (code === 0) {\n return \"exit\";\n }\n return \"failure\";\n}\n\nfunction setupSignalHandlers(child: child_process.ChildProcess): void {\n // Remove old handlers first to prevent accumulation\n for (const [signal, handler] of Object.entries(signalHandlers)) {\n process.off(signal as NodeJS.Signals, handler);\n }\n\n signalHandlers = {\n SIGINT: () => child.kill(\"SIGINT\"),\n SIGHUP: () => child.kill(\"SIGHUP\"),\n SIGTERM: () => child.kill(\"SIGTERM\"),\n SIGQUIT: () => child.kill(\"SIGQUIT\"),\n SIGABRT: () => child.kill(\"SIGABRT\"),\n };\n\n for (const [signal, handler] of Object.entries(signalHandlers)) {\n process.on(signal as NodeJS.Signals, handler);\n }\n}\n\nfunction cleanupSignalHandlers(): void {\n for (const [signal, handler] of Object.entries(signalHandlers)) {\n process.off(signal as NodeJS.Signals, handler);\n }\n signalHandlers = {};\n}\n\nfunction getParentAuthFilePath(): string {\n return process.env.SUPERBLOCKS_AUTH_FILE\n ? resolve(process.env.SUPERBLOCKS_AUTH_FILE)\n : resolve(os.homedir(), \".superblocks\", \"auth.json\");\n}\n\nfunction readTokenFromAuthFile(): string {\n try {\n const authFilePath = getParentAuthFilePath();\n if (fs.existsSync(authFilePath)) {\n const authData = JSON.parse(fs.readFileSync(authFilePath, \"utf-8\"));\n return authData.token || \"\";\n }\n } catch {\n // Ignore errors reading auth file\n }\n return \"\";\n}\n\nasync function spawnAndWaitForChild(\n previousRunResult: RunResult,\n previousRestartReason: string | null,\n options: ParentOptions,\n currentToken: string,\n): Promise<{\n result: Exclude<RunResult, null>;\n token: string;\n restartReason: string | null;\n}> {\n let token = currentToken;\n // Restart reason the *current* child announced over IPC before exiting (only\n // the migration self-restart seam sends it). Threaded back through the\n // resolved value so the NEXT spawn can tell a genuine template flip from a\n // bare exit 98 (which the editor /_sb_disconnect restart also produces).\n let childRestartReason: string | null = null;\n\n // A respawn counts as an in-place template flip only when the PREVIOUS child\n // both exited with RESTART_EXIT_CODE *and* explicitly announced reason\n // `flip_restart` over IPC. Keying off the exit code alone would mislabel\n // editor-driven /_sb_disconnect restarts (same code) as flip_restart and emit\n // a phantom completion metric.\n const isFlipRespawn =\n previousRunResult === \"restart\" &&\n previousRestartReason === RESTART_REASON_FLIP_RESTART;\n\n return new Promise((resolvePromise) => {\n const originalArgs = process.argv.slice(1);\n let processArgs: string[];\n\n if (previousRunResult === \"restart\") {\n const sliceUntil = originalArgs.findIndex((arg) => arg === \"dev\");\n if (sliceUntil === -1) {\n throw new Error(\"dev command not found in args\");\n }\n const baseArgs = originalArgs.slice(0, sliceUntil + 1);\n processArgs = [\n ...baseArgs,\n \"--child\",\n \"--download-first\",\n ...(typeof options.port === \"number\" && !Number.isNaN(options.port)\n ? [`--port=${options.port}`]\n : []),\n ];\n } else if (previousRunResult === \"auto-upgrade\") {\n processArgs = [\n ...originalArgs.filter((arg) => arg !== \"--child\"),\n \"--child\",\n \"--skip-auto-upgrade\",\n ];\n } else {\n processArgs = [...originalArgs, \"--child\"];\n }\n\n // Mark every supervised child so the dev-server runtime knows this parent\n // will respawn it on RESTART_EXIT_CODE, enabling in-place restart after a\n // template flip (see the exit-code contract above). Warm-claimed pods run\n // the CLI as a single process with no parent loop, so they never get this\n // marker and keep today's pod-swap behavior.\n //\n // Re-resolve the template from the on-disk marker (`.sb_template`) on every\n // spawn. `resolveRestartChildEnv` only overrides the template env when the\n // marker names a different template than the pod-creation env, so a normal\n // restart is left untouched while any respawn after a flip \u2014 including a\n // later auto-upgrade \u2014 boots the flipped template instead of the\n // pre-migration one baked into the pod.\n const templateMarker = readTemplateMarker(process.cwd());\n if (isFlipRespawn && templateMarker === null) {\n // A flip respawn expected the flipped template but the marker is gone\n // (deleted/empty between flip and respawn): the child boots the stale\n // pod-baked env. Surface a signal so this isn't a silent fallback. Gated\n // on the explicit flip signal so a non-flip exit-98 (editor restart) does\n // not log a misleading \"template not found\" line.\n log(PARENT_INFO_LOG.devServerRestartingWithoutTemplateOverride);\n }\n // On a respawn after a confirmed in-place template flip, stamp the restart\n // reason so the new child can tag its boot metric `flip_restart` instead of\n // `cold_start`. This is what makes the in-place restart measurable in\n // Datadog: the server-side decision metric only proves we *chose* to\n // self-restart, while this proves the child actually booted back up\n // afterward. Gated on the explicit flip signal (not exit 98 alone) so first\n // boots, auto-upgrade respawns, and editor /_sb_disconnect restarts all\n // correctly surface as `cold_start`.\n const supervisedEnv: NodeJS.ProcessEnv = {\n ...process.env,\n [RESTART_SUPERVISED_ENV]: \"1\",\n };\n if (isFlipRespawn) {\n supervisedEnv[RESTART_REASON_ENV] = RESTART_REASON_FLIP_RESTART;\n } else {\n // The child tags its boot metric from this env var, so it must be present\n // ONLY on a confirmed flip respawn. Spreading `process.env` could carry a\n // stale value into a cold/editor/auto-upgrade respawn; drop it so those\n // children correctly record `cold_start`.\n delete supervisedEnv[RESTART_REASON_ENV];\n }\n const childEnv = resolveRestartChildEnv(supervisedEnv, templateMarker);\n\n const child = child_process.spawn(process.execPath, processArgs, {\n detached: false,\n stdio: [\"inherit\", \"inherit\", \"inherit\", \"ipc\"],\n env: childEnv,\n });\n\n let spawnErrorOccurred = false;\n\n // Handle spawn errors to prevent hanging\n child.on(\"error\", (error) => {\n spawnErrorOccurred = true;\n cleanupSignalHandlers();\n logError(PARENT_ERROR_LOG.failedToSpawnChildProcess, error);\n resolvePromise({ result: \"failure\", token, restartReason: null });\n });\n\n // IPC message handling\n child.on(\"message\", (message: ChildToParentMessage) => {\n if (message.type === \"ready\") {\n log(PARENT_INFO_LOG.childReadyForToken);\n if (token) {\n log(PARENT_INFO_LOG.sendingInitialTokenToChild);\n child.send({\n type: \"initialToken\",\n token,\n } satisfies ParentToChildMessage);\n } else {\n log(PARENT_INFO_LOG.noTokenAwaitAuthHotReload);\n child.send({ type: \"noToken\" } satisfies ParentToChildMessage);\n }\n } else if (message.type === \"tokenUpdate\" && message.token) {\n token = message.token;\n log(PARENT_INFO_LOG.tokenUpdatedFromChild);\n } else if (message.type === \"devServerStarted\") {\n // Only count it as a completed restart when THIS spawn was a respawn\n // after a confirmed template flip (previous child exited 98 *and*\n // announced reason flip_restart). A first/cold boot, an auto-upgrade\n // respawn, or an editor /_sb_disconnect restart reaching boot is not the\n // signal we're tracking. Fire-and-forget: telemetry must never stall the\n // supervision loop, and the helper swallows all errors and unrefs its\n // socket in production.\n if (isFlipRespawn) {\n log(PARENT_INFO_LOG.childBootedAfterRestart);\n void emitFlipRestartCompletedMetric();\n }\n } else if (message.type === \"restartReason\" && message.reason) {\n // The current child is telling us why it is about to exit (the migration\n // self-restart seam sends this just before exit 98). Remember it so the\n // exit handler can thread it back to the next spawn, which uses it to\n // decide whether the respawn is a genuine flip_restart.\n childRestartReason = message.reason;\n }\n });\n\n setupSignalHandlers(child);\n\n child.on(\"exit\", (code) => {\n cleanupSignalHandlers();\n if (spawnErrorOccurred) {\n return;\n }\n\n const result = classifyChildExit(code);\n\n if (result === \"restart\") {\n log(PARENT_INFO_LOG.devServerRestarting);\n // Pass the reason the child announced (if any) so the next spawn can\n // tell a template flip from a bare exit-98 editor restart.\n resolvePromise({\n result: \"restart\",\n token,\n restartReason: childRestartReason,\n });\n } else if (result === \"auto-upgrade\") {\n log(PARENT_INFO_LOG.devServerExitedForAutoUpgrade);\n resolvePromise({ result: \"auto-upgrade\", token, restartReason: null });\n } else if (result === \"exit\") {\n log(PARENT_INFO_LOG.devServerExitedSuccessfully);\n resolvePromise({ result: \"exit\", token, restartReason: null });\n } else {\n log(PARENT_INFO_LOG.devServerExitedWithFailure);\n resolvePromise({ result: \"failure\", token, restartReason: null });\n }\n });\n });\n}\n\nexport async function runAsLightweightParent(\n options: ParentOptions,\n): Promise<void> {\n // Validate flags\n if (!options.uploadFirst && !options.downloadFirst) {\n logError(PARENT_ERROR_LOG.errorMissingUploadOrDownloadFirst);\n process.exitCode = 1;\n return;\n }\n if (options.skipAutoUpgrade && options.forceAutoUpgrade) {\n logError(PARENT_ERROR_LOG.errorSkipAndForceAutoUpgrade);\n process.exitCode = 1;\n return;\n }\n\n let currentToken = readTokenFromAuthFile();\n let previousRunResult: RunResult = null;\n // Reason the previous child announced before exiting (only the migration\n // self-restart seam sends one). Gates whether the next respawn is labeled a\n // flip_restart, keeping editor /_sb_disconnect restarts (same exit code) out.\n let previousRestartReason: string | null = null;\n\n do {\n try {\n const { result, token, restartReason } = await spawnAndWaitForChild(\n previousRunResult,\n previousRestartReason,\n options,\n currentToken,\n );\n logDevServerCompleted(result);\n previousRunResult = result;\n previousRestartReason = restartReason;\n currentToken = token;\n } catch (error) {\n logError(PARENT_ERROR_LOG.errorInParentProcess, error);\n previousRunResult = \"failure\";\n previousRestartReason = null;\n }\n } while (\n previousRunResult === \"restart\" ||\n previousRunResult === \"auto-upgrade\"\n );\n\n if (previousRunResult === \"failure\") {\n process.exitCode = 1;\n }\n}\n", "// Keep this module dependency-light: it is imported by the lightweight dev\n// parent (`dev-parent.mts`) and must not pull in `@superblocksteam/sdk` or any\n// other heavy module \u2014 only `node:` builtins.\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\n/**\n * Env var the CLI parent sets on every supervised child it spawns. Its presence\n * tells the dev-server runtime (vite-plugin-file-sync migration routes) that a\n * supervisor is watching for `RESTART_EXIT_CODE` and will respawn the child, so\n * it is safe to self-restart in place after a template flip.\n *\n * Warm-claimed pods run the CLI as a single process with no parent loop and\n * `RestartPolicy: Never`, so they never see this marker and keep today's\n * pod-swap behavior \u2014 this is the merge-independence guard that lets the\n * cold-start restart land before the warm-mode supervisor.\n *\n * Canonically defined in `@superblocksteam/library-shared/restart-contract`;\n * re-declared here because this module must stay on `node:` builtins only. Keep\n * the value in sync with the canonical contract.\n */\nexport const RESTART_SUPERVISED_ENV = \"SUPERBLOCKS_RESTART_SUPERVISED\";\n\n/**\n * Env var the CLI parent stamps on a child it respawns after the previous child\n * exited with `RESTART_EXIT_CODE` (an in-place v2->v3 template flip), set to\n * `RESTART_REASON_FLIP_RESTART`. The respawned dev-server reads it once at boot\n * to tag its boot metric, so a post-flip in-place restart is distinguishable\n * from a cold start in Datadog. Absent on a first/cold boot.\n *\n * Canonically defined in `@superblocksteam/library-shared/restart-contract`;\n * re-declared here because this module is imported by the lightweight dev parent\n * and must stay on `node:` builtins only. Keep in sync with the canonical\n * contract (the restart-contract drift test enforces this).\n */\nexport const RESTART_REASON_ENV = \"SUPERBLOCKS_RESTART_REASON\";\n\n/** Value the parent writes into `RESTART_REASON_ENV` for a post-flip respawn. */\nexport const RESTART_REASON_FLIP_RESTART = \"flip_restart\";\n\n/**\n * Reads the runtime template marker (`.sb_template`) that the migration\n * restructure step writes into the app root after a v2->v3 flip. Returns the\n * trimmed template name, or null when the marker is absent, empty, or\n * unreadable.\n *\n * The `.sb_template` contract has one writer (`migration/restructure.ts`) and\n * several readers across packages: `getTemplateNameFromDisk` in\n * `vite-plugin-file-sync/src/inject-index-vite-plugin.ts` and the csb-mock\n * server (`app-manager.ts` / `routes/sabs.ts`). This copy stays standalone\n * because it is imported by the lightweight dev parent and may only depend on\n * `node:` builtins; keep these readers in sync if the marker format changes.\n */\nexport function readTemplateMarker(appRootDir: string): string | null {\n try {\n const value = fs\n .readFileSync(path.join(appRootDir, \".sb_template\"), \"utf-8\")\n .trim();\n return value || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Builds the child environment for a supervised dev-server spawn, applying the\n * on-disk template marker only when it names a *different* template than the one\n * already in the env (i.e. a flip actually happened):\n * - override `SUPERBLOCKS_APP_TEMPLATE_NAME` / `TEMPLATE_NAME`\n * - drop a stale `SUPERBLOCKS_APP_ENTRY_POINT` so the entry point re-derives\n * from the new template (e.g. `app-fullstack` -> `client/root.tsx`) rather\n * than reusing the pre-migration root\n *\n * Comparing the marker to the current env (rather than keying off \"is this a\n * restart?\") makes this safe to call on every spawn:\n * - a non-flip restart (e.g. the editor-driven `/_sb_disconnect`) leaves the\n * env \u2014 and the pod's entry point \u2014 untouched instead of dropping\n * `SUPERBLOCKS_APP_ENTRY_POINT` on every restart; and\n * - a post-flip respawn re-applies the flipped template for any exit code,\n * including a later auto-upgrade, not just the first restart.\n *\n * Always returns a shallow copy; the input env is never mutated and the\n * returned reference is never the input (callers cannot use `result === baseEnv`\n * to detect a no-op). When `templateName` is null (no marker on disk) or matches\n * the current env template, the copy is returned with no modifications applied.\n */\nexport function resolveRestartChildEnv(\n baseEnv: NodeJS.ProcessEnv,\n templateName: string | null,\n): NodeJS.ProcessEnv {\n const next: NodeJS.ProcessEnv = { ...baseEnv };\n const currentTemplate =\n baseEnv.SUPERBLOCKS_APP_TEMPLATE_NAME ?? baseEnv.TEMPLATE_NAME;\n if (templateName && templateName !== currentTemplate) {\n next.SUPERBLOCKS_APP_TEMPLATE_NAME = templateName;\n next.TEMPLATE_NAME = templateName;\n delete next.SUPERBLOCKS_APP_ENTRY_POINT;\n }\n return next;\n}\n", "/**\n * Lightweight OTLP/HTTP metric emitter for the dev-server CLI parent.\n *\n * The lightweight parent (`dev-parent.mts`) supervises the dev-server child and\n * is the ONE process that reliably survives an in-place restart: it observes the\n * child exit `RESTART_EXIT_CODE` (98) after a v2->v3 template flip, respawns it,\n * and then receives the new child's `devServerStarted` IPC once that child\n * actually reaches dev-server boot. That makes the parent the reliable place to\n * record \"the in-place restart completed\", because the child's own\n * `dev_server_boot_total` is buffered through the SDK telemetry pipeline and is\n * lost if telemetry never initializes (the failure we observed in Datadog: the\n * respawned child went dark before its boot metric was ever flushed).\n *\n * CRITICAL: like `dev-parent.mts` and `restart-template-env.mts`, this module\n * must depend ONLY on `node:` builtins. It must NOT import `@superblocksteam/sdk`\n * or the OTel SDK \u2014 pulling those into the parent would defeat the lightweight\n * (<100MB) parent constraint. We therefore hand-roll a minimal OTLP/HTTP JSON\n * export instead of using `@opentelemetry/exporter-metrics-otlp-http`. The wire\n * format mirrors that exporter (JSON body, no auth header, DELTA temporality) so\n * the metric lands in the same Datadog stream as the child's metrics.\n */\n\nimport * as http from \"node:http\";\nimport * as https from \"node:https\";\n\nimport { RESTART_REASON_FLIP_RESTART } from \"./restart-template-env.mjs\";\n\n/**\n * Service name for the dev-server telemetry stream. Mirrors `SERVICE_NAME` in\n * `@superblocksteam/sdk`'s `telemetry/util.ts` so parent-emitted metrics share\n * the child's `service.name` resource attribute. Keep in sync.\n */\nconst SERVICE_NAME = \"sdk-dev-server\";\n\n/** OTel instrument scope for parent-emitted metrics (distinct from the child). */\nconst SCOPE_NAME = \"superblocks.cli.dev-parent\";\n\n/**\n * Parent-owned completion metric for an in-place restart. Distinct from the\n * child's `dev_server_boot_total` on purpose: this counts respawns that reached\n * dev-server boot as observed by the supervisor, so the two can be compared in\n * Datadog (server \"decided to self-restart\" vs parent \"restart completed\" vs\n * child \"booted\"). Labels are kept to a closed `reason` enum \u2014 no namespace,\n * pod, branch, or app labels \u2014 to keep cardinality bounded across EE namespaces.\n */\nexport const DEV_SERVER_RESTART_COMPLETED_METRIC =\n \"dev_server_child_respawn_completed_total\";\n\nconst DEV_SERVER_RESTART_COMPLETED_DESCRIPTION =\n \"Count of dev-server child respawns that reached boot after an in-place restart, by reason.\";\n\n/** Default fire-and-forget POST budget. Telemetry must never delay the parent. */\nconst DEFAULT_TIMEOUT_MS = 1000;\n\n/**\n * Resolves the OTLP metrics endpoint the parent should POST to, mirroring the\n * SDK's `getOtlpBaseUrl` (telemetry/util.ts):\n * 1. `SUPERBLOCKS_OTEL_COLLECTOR_URL` (local obs / direct collector), with any\n * trailing `/v1/{traces,metrics,logs}` stripped so we append `/v1/metrics`\n * exactly once.\n * 2. `<SUPERBLOCKS_BASE_URL origin>/api` \u2014 the Superblocks API proxies OTLP.\n * Returns null when neither is set or the base URL is unparseable, so callers\n * can silently skip emission rather than crash the parent.\n */\nexport function resolveOtlpMetricsUrl(\n env: NodeJS.ProcessEnv = process.env,\n): string | null {\n const collector = env.SUPERBLOCKS_OTEL_COLLECTOR_URL;\n if (collector) {\n const base = collector\n .replace(/\\/v1\\/(traces|metrics|logs)$/, \"\")\n .replace(/\\/+$/, \"\");\n return `${base}/v1/metrics`;\n }\n\n const baseUrl = env.SUPERBLOCKS_BASE_URL;\n if (baseUrl) {\n try {\n return `${new URL(baseUrl).origin}/api/v1/metrics`;\n } catch {\n return null;\n }\n }\n\n return null;\n}\n\n/**\n * Derives the `deployment.environment.name` resource attribute from\n * `SUPERBLOCKS_BASE_URL`, mirroring `getEnvironmentFromHostname`\n * (telemetry/attributes.ts) so parent metrics carry the same environment tag as\n * the child. Defaults to `\"other\"` when the host is unknown or unavailable.\n */\nexport function deploymentEnvironmentFromBaseUrl(\n env: NodeJS.ProcessEnv = process.env,\n): string {\n const baseUrl = env.SUPERBLOCKS_BASE_URL;\n if (!baseUrl) {\n return \"other\";\n }\n let hostname: string;\n try {\n hostname = new URL(baseUrl).hostname;\n } catch {\n return \"other\";\n }\n if (hostname.match(/^app\\.superblocks(?:hq)?\\.com/)) return \"prod\";\n if (hostname.match(/^eu\\.superblocks(?:hq)?\\.com/)) return \"prod-eu\";\n if (hostname.match(/^staging\\.superblocks(?:hq)?\\.com/)) return \"staging\";\n if (hostname.match(/^dev\\.superblocks(?:hq)?\\.com/)) return \"dev\";\n if (hostname.match(/^pr-[0-9]+\\.superblocks(?:hq)?\\.dev/)) return \"ephemeral\";\n if (hostname.match(/^localhost/)) return \"local\";\n return \"other\";\n}\n\nfunction toAttributeArray(\n attributes: Record<string, string>,\n): Array<{ key: string; value: { stringValue: string } }> {\n return Object.entries(attributes).map(([key, value]) => ({\n key,\n value: { stringValue: value },\n }));\n}\n\n/**\n * Builds a minimal OTLP/HTTP `ExportMetricsServiceRequest` body for a single\n * monotonic DELTA counter increment (value 1). Timestamps are nanosecond\n * decimal strings built with BigInt so JS number precision can't corrupt them;\n * `startTimeUnixNano <= timeUnixNano` is required by the protocol.\n */\nexport function buildDeltaCounterPayload(opts: {\n name: string;\n description: string;\n attributes: Record<string, string>;\n environment: string;\n serviceName?: string;\n scopeName?: string;\n nowMs?: number;\n}): unknown {\n const nowNano = BigInt(opts.nowMs ?? Date.now()) * 1_000_000n;\n // A 1ms window keeps start strictly <= time without implying real duration.\n const startNano = nowNano - 1_000_000n;\n\n return {\n resourceMetrics: [\n {\n resource: {\n attributes: toAttributeArray({\n \"service.name\": opts.serviceName ?? SERVICE_NAME,\n \"deployment.environment.name\": opts.environment,\n }),\n },\n scopeMetrics: [\n {\n scope: { name: opts.scopeName ?? SCOPE_NAME },\n metrics: [\n {\n name: opts.name,\n description: opts.description,\n sum: {\n aggregationTemporality: 1, // AGGREGATION_TEMPORALITY_DELTA\n isMonotonic: true,\n dataPoints: [\n {\n attributes: toAttributeArray(opts.attributes),\n startTimeUnixNano: startNano.toString(),\n timeUnixNano: nowNano.toString(),\n asInt: \"1\",\n },\n ],\n },\n },\n ],\n },\n ],\n },\n ],\n };\n}\n\n/**\n * Fire-and-forget POST of a single counter increment as OTLP/HTTP JSON.\n *\n * Never throws and never rejects: any failure (no endpoint, DNS, timeout,\n * non-2xx) resolves quietly so telemetry cannot break or delay the parent's\n * supervision loop or shutdown. In production the request socket and timeout are\n * `unref`'d so a slow collector can't keep the parent alive; tests pass\n * `unref: false` and `await` to observe the request deterministically.\n */\nexport function emitOtlpCounter(opts: {\n name: string;\n description: string;\n attributes: Record<string, string>;\n env?: NodeJS.ProcessEnv;\n timeoutMs?: number;\n unref?: boolean;\n}): Promise<void> {\n const env = opts.env ?? process.env;\n const url = resolveOtlpMetricsUrl(env);\n if (!url) {\n return Promise.resolve();\n }\n\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return Promise.resolve();\n }\n\n const body = JSON.stringify(\n buildDeltaCounterPayload({\n name: opts.name,\n description: opts.description,\n attributes: opts.attributes,\n environment: deploymentEnvironmentFromBaseUrl(env),\n }),\n );\n\n const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const unref = opts.unref ?? true;\n const transport = parsed.protocol === \"https:\" ? https : http;\n\n return new Promise<void>((resolve) => {\n let settled = false;\n const done = (): void => {\n if (settled) return;\n settled = true;\n resolve();\n };\n\n const req = transport.request(\n {\n protocol: parsed.protocol,\n hostname: parsed.hostname,\n port: parsed.port,\n path: parsed.pathname + parsed.search,\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"content-length\": Buffer.byteLength(body),\n },\n },\n (res) => {\n // Drain so the socket can close; the status is irrelevant to the parent.\n res.on(\"data\", () => {});\n res.on(\"end\", done);\n res.on(\"error\", done);\n },\n );\n\n req.on(\"error\", done);\n req.setTimeout(timeoutMs, () => {\n req.destroy();\n done();\n });\n if (unref) {\n req.on(\"socket\", (socket) => socket.unref());\n }\n req.end(body);\n });\n}\n\n/**\n * Records that an in-place flip-restart completed (the supervisor saw the\n * respawned child reach dev-server boot). Fire-and-forget; safe to `void`.\n */\nexport function emitFlipRestartCompletedMetric(opts?: {\n env?: NodeJS.ProcessEnv;\n timeoutMs?: number;\n unref?: boolean;\n}): Promise<void> {\n return emitOtlpCounter({\n name: DEV_SERVER_RESTART_COMPLETED_METRIC,\n description: DEV_SERVER_RESTART_COMPLETED_DESCRIPTION,\n attributes: { reason: RESTART_REASON_FLIP_RESTART },\n env: opts?.env,\n timeoutMs: opts?.timeoutMs,\n unref: opts?.unref,\n });\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["fs", "resolve"]
7
7
  }