@superblocksteam/sdk 2.0.130-next.2 → 2.0.130-next.4

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 (47) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/cli-replacement/dependency-install-classifier.d.mts.map +1 -1
  3. package/dist/cli-replacement/dependency-install-classifier.mjs +11 -0
  4. package/dist/cli-replacement/dependency-install-classifier.mjs.map +1 -1
  5. package/dist/cli-replacement/dependency-install-classifier.test.mjs +26 -0
  6. package/dist/cli-replacement/dependency-install-classifier.test.mjs.map +1 -1
  7. package/dist/cli-replacement/dev.d.mts.map +1 -1
  8. package/dist/cli-replacement/dev.mjs +63 -4
  9. package/dist/cli-replacement/dev.mjs.map +1 -1
  10. package/dist/cli-replacement/disk-space.d.mts +86 -0
  11. package/dist/cli-replacement/disk-space.d.mts.map +1 -0
  12. package/dist/cli-replacement/disk-space.mjs +133 -0
  13. package/dist/cli-replacement/disk-space.mjs.map +1 -0
  14. package/dist/cli-replacement/disk-space.test.d.mts +2 -0
  15. package/dist/cli-replacement/disk-space.test.d.mts.map +1 -0
  16. package/dist/cli-replacement/disk-space.test.mjs +186 -0
  17. package/dist/cli-replacement/disk-space.test.mjs.map +1 -0
  18. package/dist/dev-utils/dev-server-metrics.d.mts +11 -0
  19. package/dist/dev-utils/dev-server-metrics.d.mts.map +1 -1
  20. package/dist/dev-utils/dev-server-metrics.mjs +18 -0
  21. package/dist/dev-utils/dev-server-metrics.mjs.map +1 -1
  22. package/dist/telemetry/memory-metrics.d.ts +7 -0
  23. package/dist/telemetry/memory-metrics.d.ts.map +1 -1
  24. package/dist/telemetry/memory-metrics.js +221 -44
  25. package/dist/telemetry/memory-metrics.js.map +1 -1
  26. package/dist/telemetry/memory-metrics.test.d.ts +2 -0
  27. package/dist/telemetry/memory-metrics.test.d.ts.map +1 -0
  28. package/dist/telemetry/memory-metrics.test.js +256 -0
  29. package/dist/telemetry/memory-metrics.test.js.map +1 -0
  30. package/dist/vite-plugin-sdk-api-entry-point.d.mts +14 -1
  31. package/dist/vite-plugin-sdk-api-entry-point.d.mts.map +1 -1
  32. package/dist/vite-plugin-sdk-api-entry-point.mjs +68 -7
  33. package/dist/vite-plugin-sdk-api-entry-point.mjs.map +1 -1
  34. package/dist/vite-plugin-sdk-api-entry-point.test.mjs +53 -1
  35. package/dist/vite-plugin-sdk-api-entry-point.test.mjs.map +1 -1
  36. package/package.json +6 -6
  37. package/src/cli-replacement/dependency-install-classifier.mts +14 -0
  38. package/src/cli-replacement/dependency-install-classifier.test.mts +39 -0
  39. package/src/cli-replacement/dev.mts +81 -10
  40. package/src/cli-replacement/disk-space.mts +216 -0
  41. package/src/cli-replacement/disk-space.test.mts +246 -0
  42. package/src/dev-utils/dev-server-metrics.mts +20 -0
  43. package/src/telemetry/memory-metrics.test.ts +363 -0
  44. package/src/telemetry/memory-metrics.ts +329 -60
  45. package/src/vite-plugin-sdk-api-entry-point.mts +79 -9
  46. package/src/vite-plugin-sdk-api-entry-point.test.mts +134 -1
  47. package/tsconfig.tsbuildinfo +1 -1
@@ -1,4 +1,5 @@
1
1
  import path from "node:path";
2
+ const SERVER_APIS_DIR = "server/apis";
2
3
  /**
3
4
  * Build a sourcemap `mappings` string for a simple prepend operation.
4
5
  *
@@ -18,24 +19,84 @@ function buildPrependMappings(prependLineCount, originalLineCount) {
18
19
  .join(";");
19
20
  return empty + original;
20
21
  }
22
+ function qualifyAnchoredServerApisRelative(relative) {
23
+ if (relative === `${SERVER_APIS_DIR}/index.ts`) {
24
+ return null;
25
+ }
26
+ const baseName = path.posix.basename(relative);
27
+ if (baseName === "index.ts") {
28
+ return null;
29
+ }
30
+ if (!relative.endsWith(".ts") && !relative.endsWith(".tsx")) {
31
+ return null;
32
+ }
33
+ return relative;
34
+ }
35
+ function qualifySegmentFallbackRelative(relative) {
36
+ if (!relative.startsWith(`${SERVER_APIS_DIR}/`)) {
37
+ return null;
38
+ }
39
+ // Reject false positives when appRootDir sits under a server/apis/ path.
40
+ if (relative.includes("/client/")) {
41
+ return null;
42
+ }
43
+ const baseName = path.posix.basename(relative);
44
+ if (baseName !== "api.ts" && baseName !== "api.tsx") {
45
+ return null;
46
+ }
47
+ return relative;
48
+ }
49
+ /**
50
+ * Resolve the app-root-relative entry point path for a Vite module id.
51
+ *
52
+ * Fullstack apps keep `server/apis/` at the app root while `vite.config.ts`
53
+ * often sets `root: "./client"`. Dev server and build already pass the true
54
+ * app root into the plugin; failures are intermittent and depend on how Vite
55
+ * resolves module ids for files outside the client subtree (for example
56
+ * `../server/apis/...` relatives or `/@fs/...` absolute ids). Plain absolute
57
+ * paths under `<appRoot>/server/apis/` already matched before this helper.
58
+ */
59
+ export function resolveSdkApiEntryPointRelativePath(appRootDir, moduleId) {
60
+ const normalizedId = path.normalize(moduleId);
61
+ const normalizedRoot = path.normalize(appRootDir);
62
+ const relative = path
63
+ .relative(normalizedRoot, normalizedId)
64
+ .replace(/\\/g, "/");
65
+ if (relative.startsWith(`${SERVER_APIS_DIR}/`)) {
66
+ return qualifyAnchoredServerApisRelative(relative);
67
+ }
68
+ // Plugin base is client/ or Vite passes a ../server/apis/... module id.
69
+ if (relative.startsWith(`../${SERVER_APIS_DIR}/`)) {
70
+ return qualifyAnchoredServerApisRelative(relative.slice("../".length));
71
+ }
72
+ // Fallback for module ids not matched above: /@fs/ prefixed ids, standard
73
+ // absolute paths when appRootDir is 2+ levels above server/apis/, etc.
74
+ // NOTE: unanchored to appRootDir — matches any id containing /server/apis/
75
+ // with an api.ts/api.tsx basename. lastIndexOf picks the deepest segment.
76
+ const posixId = normalizedId.replace(/\\/g, "/");
77
+ const segment = `/${SERVER_APIS_DIR}/`;
78
+ const segmentIndex = posixId.lastIndexOf(segment);
79
+ if (segmentIndex !== -1) {
80
+ return qualifySegmentFallbackRelative(posixId.slice(segmentIndex + 1));
81
+ }
82
+ return null;
83
+ }
21
84
  /**
22
85
  * Vite plugin that prepends `__setEntryPoint(relativePath)` to SDK API files
23
86
  * so that `api()` can stamp the authoritative source file
24
87
  * path onto the compiled API object.
25
88
  *
89
+ * @param appRootDir - App root (parent of `client/` and `server/`).
90
+ *
26
91
  * Runs in both dev and build. The user's source code is never modified on disk.
27
92
  */
28
- export function sdkApiEntryPointPlugin(root) {
93
+ export function sdkApiEntryPointPlugin(appRootDir) {
29
94
  return {
30
95
  name: "sb-sdk-api-entry-point",
31
96
  enforce: "pre",
32
97
  transform(code, id) {
33
- const relative = path.relative(root, id).replace(/\\/g, "/");
34
- if (!relative.startsWith("server/apis/") ||
35
- relative === "server/apis/index.ts") {
36
- return null;
37
- }
38
- if (!relative.endsWith(".ts") && !relative.endsWith(".tsx")) {
98
+ const relative = resolveSdkApiEntryPointRelativePath(appRootDir, id);
99
+ if (!relative) {
39
100
  return null;
40
101
  }
41
102
  const prependLines = [
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin-sdk-api-entry-point.mjs","sourceRoot":"","sources":["../src/vite-plugin-sdk-api-entry-point.mts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B;;;;;;;;;GASG;AACH,SAAS,oBAAoB,CAC3B,gBAAwB,EACxB,iBAAyB;IAEzB,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAC3C,IAAI,iBAAiB,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC;SACtB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAC9D,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,OAAO,KAAK,GAAG,QAAQ,CAAC;AAC1B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO;QACL,IAAI,EAAE,wBAAwB;QAC9B,OAAO,EAAE,KAAK;QAEd,SAAS,CAAC,IAAI,EAAE,EAAE;YAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC7D,IACE,CAAC,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC;gBACpC,QAAQ,KAAK,sBAAsB,EACnC,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5D,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,YAAY,GAAG;gBACnB,4EAA4E;gBAC5E,eAAe,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI;gBAC3C,EAAE;aACH,CAAC;YACF,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxC,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;YAElD,MAAM,mBAAmB,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;YAEpD,OAAO;gBACL,IAAI,EAAE,OAAO,GAAG,IAAI;gBACpB,GAAG,EAAE;oBACH,OAAO,EAAE,CAAC;oBACV,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,CAAC,EAAE,CAAC;oBACb,cAAc,EAAE,CAAC,IAAI,CAAC;oBACtB,KAAK,EAAE,EAAE;oBACT,QAAQ,EAAE,oBAAoB,CAC5B,mBAAmB,EACnB,iBAAiB,CAClB;iBACF;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"vite-plugin-sdk-api-entry-point.mjs","sourceRoot":"","sources":["../src/vite-plugin-sdk-api-entry-point.mts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import path from "node:path";
2
2
  import { describe, it, expect } from "vitest";
3
- import { sdkApiEntryPointPlugin } from "./vite-plugin-sdk-api-entry-point.mjs";
3
+ import { resolveSdkApiEntryPointRelativePath, sdkApiEntryPointPlugin, } from "./vite-plugin-sdk-api-entry-point.mjs";
4
4
  function createPlugin(root) {
5
5
  const plugin = sdkApiEntryPointPlugin(root);
6
6
  const transform = plugin.transform;
@@ -60,6 +60,38 @@ function expectValidSourcemap(result, originalCode) {
60
60
  expect(sourceLine).toBe(i);
61
61
  });
62
62
  }
63
+ describe("resolveSdkApiEntryPointRelativePath", () => {
64
+ it("resolves server API paths from the true app root", () => {
65
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/app/server/apis/GetUsers/api.ts")).toBe("server/apis/GetUsers/api.ts");
66
+ });
67
+ it("resolves server API paths when the base dir is vite client/", () => {
68
+ expect(resolveSdkApiEntryPointRelativePath("/app/client", "/app/server/apis/GetPastAnalyses/api.ts")).toBe("server/apis/GetPastAnalyses/api.ts");
69
+ });
70
+ it("resolves server API paths from absolute /@fs module ids", () => {
71
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/@fs/Users/me/app/server/apis/GetFeedback/api.ts")).toBe("server/apis/GetFeedback/api.ts");
72
+ });
73
+ it("returns null for the registry barrel file", () => {
74
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/app/server/apis/index.ts")).toBeNull();
75
+ });
76
+ it("returns null when app root contains server/apis and module is a client file", () => {
77
+ expect(resolveSdkApiEntryPointRelativePath("/home/server/apis/myapp", "/home/server/apis/myapp/client/components/Button.tsx")).toBeNull();
78
+ });
79
+ it("uses the deepest server/apis segment in /@fs fallback", () => {
80
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/@fs/home/server/apis/decoy/server/apis/GetReal/api.ts")).toBe("server/apis/GetReal/api.ts");
81
+ });
82
+ it("resolves server API paths for api.tsx entry points", () => {
83
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/app/server/apis/Render/api.tsx")).toBe("server/apis/Render/api.tsx");
84
+ });
85
+ it("resolves Clark-style API entry points that are not named api.ts", () => {
86
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/app/server/apis/issues/list-issues.ts")).toBe("server/apis/issues/list-issues.ts");
87
+ });
88
+ it("resolves helper modules under server/apis/ on anchored paths", () => {
89
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/app/server/apis/GetFoo/helper.ts")).toBe("server/apis/GetFoo/helper.ts");
90
+ });
91
+ it("returns null for index.ts under an API directory", () => {
92
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/app/server/apis/GetFoo/index.ts")).toBeNull();
93
+ });
94
+ });
63
95
  describe("sdkApiEntryPointPlugin", () => {
64
96
  const root = "/app";
65
97
  it("has the correct plugin name and enforce order", () => {
@@ -68,6 +100,12 @@ describe("sdkApiEntryPointPlugin", () => {
68
100
  expect(plugin.enforce).toBe("pre");
69
101
  });
70
102
  describe("transform", () => {
103
+ it("prepends __setEntryPoint for Clark-style list-issues.ts entry points", () => {
104
+ const { transform } = createPlugin(root);
105
+ const result = transform('export default api({ name: "ListIssues" });', path.join(root, "server/apis/issues/list-issues.ts"));
106
+ expect(result).not.toBeNull();
107
+ expect(result.code).toContain('__sb_set_ep("server/apis/issues/list-issues.ts");');
108
+ });
71
109
  it("prepends __setEntryPoint for a standard API file", () => {
72
110
  const { transform } = createPlugin(root);
73
111
  const result = transform('export default api({ name: "GetUsers" });', path.join(root, "server/apis/GetUsers/api.ts"));
@@ -103,6 +141,20 @@ describe("sdkApiEntryPointPlugin", () => {
103
141
  expect(result).not.toBeNull();
104
142
  expect(result.code).toContain('__sb_set_ep("server/apis/v2/GetUsers/api.ts");');
105
143
  });
144
+ it("prepends __setEntryPoint when plugin root is vite client/ subdir (fullstack)", () => {
145
+ const appRoot = "/app";
146
+ const viteRoot = path.join(appRoot, "client");
147
+ const { transform } = createPlugin(viteRoot);
148
+ const result = transform('export default api({ name: "GetPastAnalyses" });', path.join(appRoot, "server/apis/GetPastAnalyses/api.ts"));
149
+ expect(result).not.toBeNull();
150
+ expect(result.code).toContain('__sb_set_ep("server/apis/GetPastAnalyses/api.ts");');
151
+ });
152
+ it("prepends __setEntryPoint for /@fs/ module ids", () => {
153
+ const { transform } = createPlugin(root);
154
+ const result = transform('export default api({ name: "GetFeedback" });', "/@fs/Users/me/app/server/apis/GetFeedback/api.ts");
155
+ expect(result).not.toBeNull();
156
+ expect(result.code).toContain('__sb_set_ep("server/apis/GetFeedback/api.ts");');
157
+ });
106
158
  it("preserves original code after the prepend", () => {
107
159
  const { transform } = createPlugin(root);
108
160
  const originalCode = [
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin-sdk-api-entry-point.test.mjs","sourceRoot":"","sources":["../src/vite-plugin-sdk-api-entry-point.test.mts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vite-plugin-sdk-api-entry-point.test.mjs","sourceRoot":"","sources":["../src/vite-plugin-sdk-api-entry-point.test.mts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superblocksteam/sdk",
3
- "version": "2.0.130-next.2",
3
+ "version": "2.0.130-next.4",
4
4
  "description": "Superblocks JS SDK",
5
5
  "homepage": "https://www.superblocks.com",
6
6
  "license": "Superblocks Community Software License",
@@ -48,11 +48,11 @@
48
48
  "vite-tsconfig-paths": "^6.0.4",
49
49
  "winston": "^3.17.0",
50
50
  "yaml": "^2.7.1",
51
- "@superblocksteam/shared": "0.9591.2",
52
- "@superblocksteam/library-shared": "2.0.130-next.2",
53
- "@superblocksteam/telemetry": "2.0.130-next.2",
54
- "@superblocksteam/util": "2.0.130-next.2",
55
- "@superblocksteam/vite-plugin-file-sync": "2.0.130-next.2"
51
+ "@superblocksteam/library-shared": "2.0.130-next.4",
52
+ "@superblocksteam/shared": "0.9592.0",
53
+ "@superblocksteam/telemetry": "2.0.130-next.4",
54
+ "@superblocksteam/util": "2.0.130-next.4",
55
+ "@superblocksteam/vite-plugin-file-sync": "2.0.130-next.4"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@eslint/js": "^9.39.2",
@@ -9,6 +9,8 @@ import {
9
9
  type ParseContext,
10
10
  } from "@superblocksteam/vite-plugin-file-sync/npm-registry";
11
11
 
12
+ import { isDiskFullError } from "./disk-space.mjs";
13
+
12
14
  /** Marker thrown by the INITIAL verification install so the dev.mts catch can
13
15
  * degrade by ORIGIN (never on classifiability). Carries the classified error. */
14
16
  export class InitialInstallFailed extends Error {
@@ -90,6 +92,18 @@ export function classifyInitialInstallError(
90
92
  if (blockedFromJson) return fromBlocked(blockedFromJson, rawError);
91
93
 
92
94
  const combined = `${stdout}\n${stderr}`;
95
+
96
+ if (isDiskFullError({ stdout, stderr, message: failure.message })) {
97
+ return {
98
+ type: "dev-server/dependency-install",
99
+ timestamp: new Date().toISOString(),
100
+ category: "disk_full",
101
+ npmErrorCode: "ENOSPC",
102
+ hasAnyRegistryConfigured: ctx.hasAnyRegistryConfigured,
103
+ rawError,
104
+ };
105
+ }
106
+
93
107
  const codeMatch = combined.match(DEP_CONFLICT_CODES);
94
108
  if (codeMatch) {
95
109
  return {
@@ -47,6 +47,45 @@ describe("classifyInitialInstallError", () => {
47
47
  expect(e.registryHost).toBe("reg.corp");
48
48
  });
49
49
 
50
+ it("classifies an ENOSPC --json envelope as disk_full", () => {
51
+ const ENOSPC_JSON = JSON.stringify({
52
+ error: {
53
+ code: "ENOSPC",
54
+ summary: "ENOSPC: no space left on device, write",
55
+ detail: "nospc ENOSPC: no space left on device, write",
56
+ },
57
+ });
58
+ const e = classifyInitialInstallError(
59
+ { stdout: ENOSPC_JSON, stderr: "npm error code ENOSPC", message: "x" },
60
+ { hasAnyRegistryConfigured: true, requestedPackages: [] },
61
+ );
62
+ expect(e.category).toBe("disk_full");
63
+ expect(e.npmErrorCode).toBe("ENOSPC");
64
+ });
65
+
66
+ it("classifies a bare 'no space left on device' stderr as disk_full", () => {
67
+ const e = classifyInitialInstallError(
68
+ {
69
+ stdout: "not json",
70
+ stderr:
71
+ "npm error code ENOSPC\nnpm error syscall write\nnpm error errno -28\nnpm error nospc ENOSPC: no space left on device, write",
72
+ message: "Command failed",
73
+ },
74
+ {},
75
+ );
76
+ expect(e.category).toBe("disk_full");
77
+ expect(e.npmErrorCode).toBe("ENOSPC");
78
+ });
79
+
80
+ it("classifies a bare 'errno -28' (no ENOSPC code name) as disk_full", () => {
81
+ const e = classifyInitialInstallError(
82
+ { stdout: "", stderr: "npm error errno -28", message: "Command failed" },
83
+ {},
84
+ );
85
+ expect(e.category).toBe("disk_full");
86
+ expect(e.npmErrorCode).toBe("ENOSPC");
87
+ });
88
+
50
89
  it("falls back to unknown for an unmapped code (still a DependencyInstallError)", () => {
51
90
  const e = classifyInitialInstallError(
52
91
  {
@@ -70,6 +70,7 @@ import {
70
70
  classifyInitialInstallError,
71
71
  InitialInstallFailed,
72
72
  } from "./dependency-install-classifier.mjs";
73
+ import { getDiskSpace, recoverFromDiskFull } from "./disk-space.mjs";
73
74
  import {
74
75
  ensureRemoteHasDefaultBranch,
75
76
  getGitErrorFields,
@@ -342,6 +343,12 @@ export async function installPackages(
342
343
  logger: Logger,
343
344
  npmRegistryClient?: NpmRegistryClient,
344
345
  ) {
346
+ // Hoisted so the catch's ENOSPC recovery can re-run the EXACT same install
347
+ // (same agent, args, env, --ignore-scripts policy) after reclaiming disk
348
+ // space, rather than reconstructing — and risking diverging from — it.
349
+ let runInstall:
350
+ | (() => Promise<{ stdout: string; stderr: string }>)
351
+ | undefined;
345
352
  try {
346
353
  const pm = await detect({
347
354
  strategies: [
@@ -445,25 +452,89 @@ export async function installPackages(
445
452
  // (`category: "unknown"`, `npmErrorCode: undefined` from real npm against a
446
453
  // missing `/tmp/app`).
447
454
  const exec = promisify(child_process.exec);
448
- const { stdout } = await exec(`${command} ${args.join(" ")}`, {
449
- cwd,
450
- env: buildInstallEnv(superblocksNpmrcPath(), logsDir),
451
- });
455
+ // Re-runnable so the ENOSPC recovery path below can retry the EXACT same
456
+ // install after reclaiming disk space.
457
+ runInstall = () =>
458
+ exec(`${command} ${args.join(" ")}`, {
459
+ cwd,
460
+ env: buildInstallEnv(superblocksNpmrcPath(), logsDir),
461
+ });
462
+
463
+ // Cheap `df` snapshot before the install (statfs only — no directory walk
464
+ // on the happy path). On a 3Gi live-edit PVC this is the baseline that
465
+ // makes an ENOSPC mid-install interpretable after the fact.
466
+ const diskBefore = await getDiskSpace(cwd);
467
+ if (diskBefore) {
468
+ logger.info(
469
+ `Disk usage before package install [freeBytes=${diskBefore.freeBytes} totalBytes=${diskBefore.totalBytes} percentUsed=${diskBefore.percentUsed}] cwd=${cwd}`,
470
+ { disk: diskBefore },
471
+ );
472
+ } else {
473
+ logger.warn(
474
+ `Could not read disk usage before package install (statfs failed) cwd=${cwd}`,
475
+ );
476
+ }
477
+
478
+ const { stdout } = await runInstall();
452
479
  logger.info("Package installation completed successfully");
453
480
  logger.info(stdout);
454
481
  } catch (error) {
455
- logger.error("Error during package installation", getErrorMeta(error));
456
482
  // `util.promisify(child_process.exec)` preserves `.stdout`/`.stderr` on
457
483
  // the rejected error separately; with `--json`, the structured npm error
458
484
  // envelope lands on `.stdout`. Classify it into a DependencyInstallError
459
485
  // and throw the `InitialInstallFailed` marker so the `dev()` catch can
460
486
  // degrade by origin rather than crash-looping the dev-server pod.
461
487
  const ctx = await buildInstallParseContext(cwd, npmRegistryClient);
462
- const f = error as { stdout?: string; stderr?: string; message?: string };
463
- const serverError = classifyInitialInstallError(
464
- { stdout: f.stdout, stderr: f.stderr, message: f.message },
465
- ctx,
466
- );
488
+ const toFailure = (e: unknown) => {
489
+ const f = e as { stdout?: string; stderr?: string; message?: string };
490
+ return { stdout: f.stdout, stderr: f.stderr, message: f.message };
491
+ };
492
+ let serverError = classifyInitialInstallError(toFailure(error), ctx);
493
+ // The error whose meta we log on the way out — kept in lockstep with the
494
+ // (possibly reclassified) `serverError` we throw, so operational logs and
495
+ // the user-visible error never disagree.
496
+ let errorToLog: unknown = error;
497
+
498
+ // ENOSPC: the live-edit volume filled up mid-install. Try to recover by
499
+ // reclaiming regenerable build artifacts (and, if that's not enough, the
500
+ // half-written node_modules) and retrying the install before giving up.
501
+ // The recovery logs each tier's df + freed bytes, which doubles as the
502
+ // only autopsy we can get of a PVC that `reclaimPolicy: Delete` destroys
503
+ // at teardown. `runInstall` is only set once the command was resolved; if
504
+ // the failure happened before that, there's nothing to retry.
505
+ if (serverError.category === "disk_full" && runInstall) {
506
+ let recovery: Awaited<ReturnType<typeof recoverFromDiskFull>> | undefined;
507
+ try {
508
+ recovery = await recoverFromDiskFull(cwd, runInstall, logger);
509
+ } catch (recoveryErr) {
510
+ // Recovery is best-effort; an unexpected throw must never escape as a
511
+ // raw error (that would bypass the InitialInstallFailed contract the
512
+ // dev() catch relies on). Swallow it and surface the original failure.
513
+ logger.warn("Disk recovery threw unexpectedly", {
514
+ error: String(recoveryErr),
515
+ });
516
+ }
517
+ if (recovery) {
518
+ devServerMetrics.recordDiskRecovery({ recovered: recovery.recovered });
519
+ if (recovery.recovered) {
520
+ logger.info(
521
+ "Package installation completed successfully after disk recovery",
522
+ );
523
+ return;
524
+ }
525
+ // Reclassify the final attempt so the surfaced error reflects the last
526
+ // npm output (still disk_full if genuinely out of space).
527
+ if (recovery.lastError !== undefined) {
528
+ errorToLog = recovery.lastError;
529
+ serverError = classifyInitialInstallError(
530
+ toFailure(recovery.lastError),
531
+ ctx,
532
+ );
533
+ }
534
+ }
535
+ }
536
+
537
+ logger.error("Error during package installation", getErrorMeta(errorToLog));
467
538
  throw new InitialInstallFailed(serverError);
468
539
  }
469
540
  }