@superblocksteam/sdk 2.0.123 → 2.0.124-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 (115) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/cli-replacement/automatic-upgrades.d.ts +37 -1
  3. package/dist/cli-replacement/automatic-upgrades.d.ts.map +1 -1
  4. package/dist/cli-replacement/automatic-upgrades.js +162 -10
  5. package/dist/cli-replacement/automatic-upgrades.js.map +1 -1
  6. package/dist/cli-replacement/automatic-upgrades.test.js +377 -8
  7. package/dist/cli-replacement/automatic-upgrades.test.js.map +1 -1
  8. package/dist/cli-replacement/dependency-install-classifier.d.mts +21 -0
  9. package/dist/cli-replacement/dependency-install-classifier.d.mts.map +1 -0
  10. package/dist/cli-replacement/dependency-install-classifier.mjs +83 -0
  11. package/dist/cli-replacement/dependency-install-classifier.mjs.map +1 -0
  12. package/dist/cli-replacement/dependency-install-classifier.test.d.mts +2 -0
  13. package/dist/cli-replacement/dependency-install-classifier.test.d.mts.map +1 -0
  14. package/dist/cli-replacement/dependency-install-classifier.test.mjs +51 -0
  15. package/dist/cli-replacement/dependency-install-classifier.test.mjs.map +1 -0
  16. package/dist/cli-replacement/dev-s3-restore.test.mjs +170 -14
  17. package/dist/cli-replacement/dev-s3-restore.test.mjs.map +1 -1
  18. package/dist/cli-replacement/dev-startup-git-before-dbfs-order.test.mjs +33 -2
  19. package/dist/cli-replacement/dev-startup-git-before-dbfs-order.test.mjs.map +1 -1
  20. package/dist/cli-replacement/dev-token-priming.test.d.mts +31 -0
  21. package/dist/cli-replacement/dev-token-priming.test.d.mts.map +1 -0
  22. package/dist/cli-replacement/dev-token-priming.test.mjs +87 -0
  23. package/dist/cli-replacement/dev-token-priming.test.mjs.map +1 -0
  24. package/dist/cli-replacement/dev.d.mts +36 -0
  25. package/dist/cli-replacement/dev.d.mts.map +1 -1
  26. package/dist/cli-replacement/dev.interception.test.d.mts +2 -0
  27. package/dist/cli-replacement/dev.interception.test.d.mts.map +1 -0
  28. package/dist/cli-replacement/dev.interception.test.mjs +68 -0
  29. package/dist/cli-replacement/dev.interception.test.mjs.map +1 -0
  30. package/dist/cli-replacement/dev.mjs +396 -62
  31. package/dist/cli-replacement/dev.mjs.map +1 -1
  32. package/dist/cli-replacement/home-npmrc.d.mts +180 -0
  33. package/dist/cli-replacement/home-npmrc.d.mts.map +1 -0
  34. package/dist/cli-replacement/home-npmrc.mjs +283 -0
  35. package/dist/cli-replacement/home-npmrc.mjs.map +1 -0
  36. package/dist/cli-replacement/home-npmrc.test.d.mts +10 -0
  37. package/dist/cli-replacement/home-npmrc.test.d.mts.map +1 -0
  38. package/dist/cli-replacement/home-npmrc.test.mjs +582 -0
  39. package/dist/cli-replacement/home-npmrc.test.mjs.map +1 -0
  40. package/dist/cli-replacement/install-packages.classify.test.d.mts +2 -0
  41. package/dist/cli-replacement/install-packages.classify.test.d.mts.map +1 -0
  42. package/dist/cli-replacement/install-packages.classify.test.mjs +125 -0
  43. package/dist/cli-replacement/install-packages.classify.test.mjs.map +1 -0
  44. package/dist/cli-replacement/install-packages.npm-registry.test.d.mts +2 -0
  45. package/dist/cli-replacement/install-packages.npm-registry.test.d.mts.map +1 -0
  46. package/dist/cli-replacement/install-packages.npm-registry.test.mjs +260 -0
  47. package/dist/cli-replacement/install-packages.npm-registry.test.mjs.map +1 -0
  48. package/dist/cli-replacement/post-upgrade-lockfile-strip.d.mts +58 -0
  49. package/dist/cli-replacement/post-upgrade-lockfile-strip.d.mts.map +1 -0
  50. package/dist/cli-replacement/post-upgrade-lockfile-strip.mjs +224 -0
  51. package/dist/cli-replacement/post-upgrade-lockfile-strip.mjs.map +1 -0
  52. package/dist/cli-replacement/post-upgrade-lockfile-strip.test.d.mts +11 -0
  53. package/dist/cli-replacement/post-upgrade-lockfile-strip.test.d.mts.map +1 -0
  54. package/dist/cli-replacement/post-upgrade-lockfile-strip.test.mjs +317 -0
  55. package/dist/cli-replacement/post-upgrade-lockfile-strip.test.mjs.map +1 -0
  56. package/dist/cli-replacement/userconfig-env.integration.test.d.mts +26 -0
  57. package/dist/cli-replacement/userconfig-env.integration.test.d.mts.map +1 -0
  58. package/dist/cli-replacement/userconfig-env.integration.test.mjs +148 -0
  59. package/dist/cli-replacement/userconfig-env.integration.test.mjs.map +1 -0
  60. package/dist/dev-utils/dev-server-metrics.d.mts +25 -0
  61. package/dist/dev-utils/dev-server-metrics.d.mts.map +1 -1
  62. package/dist/dev-utils/dev-server-metrics.mjs +84 -0
  63. package/dist/dev-utils/dev-server-metrics.mjs.map +1 -1
  64. package/dist/dev-utils/dev-server-metrics.test.d.mts +2 -0
  65. package/dist/dev-utils/dev-server-metrics.test.d.mts.map +1 -0
  66. package/dist/dev-utils/dev-server-metrics.test.mjs +26 -0
  67. package/dist/dev-utils/dev-server-metrics.test.mjs.map +1 -0
  68. package/dist/dev-utils/dev-server.d.mts +23 -1
  69. package/dist/dev-utils/dev-server.d.mts.map +1 -1
  70. package/dist/dev-utils/dev-server.mjs +21 -9
  71. package/dist/dev-utils/dev-server.mjs.map +1 -1
  72. package/dist/dev-utils/dev-server.status.test.d.mts +2 -0
  73. package/dist/dev-utils/dev-server.status.test.d.mts.map +1 -0
  74. package/dist/dev-utils/dev-server.status.test.mjs +41 -0
  75. package/dist/dev-utils/dev-server.status.test.mjs.map +1 -0
  76. package/dist/dev-utils/token-manager.d.ts +31 -0
  77. package/dist/dev-utils/token-manager.d.ts.map +1 -1
  78. package/dist/dev-utils/token-manager.js +34 -0
  79. package/dist/dev-utils/token-manager.js.map +1 -1
  80. package/dist/telemetry/local-obs.js +1 -1
  81. package/dist/telemetry/local-obs.js.map +1 -1
  82. package/dist/telemetry/util.js +1 -1
  83. package/dist/types/scoped-jwt-token-payload.d.ts +1 -0
  84. package/dist/types/scoped-jwt-token-payload.d.ts.map +1 -1
  85. package/dist/version-control.d.mts.map +1 -1
  86. package/dist/version-control.mjs +6 -7
  87. package/dist/version-control.mjs.map +1 -1
  88. package/package.json +12 -12
  89. package/src/cli-replacement/automatic-upgrades.test.ts +530 -8
  90. package/src/cli-replacement/automatic-upgrades.ts +179 -7
  91. package/src/cli-replacement/dependency-install-classifier.mts +118 -0
  92. package/src/cli-replacement/dependency-install-classifier.test.mts +72 -0
  93. package/src/cli-replacement/dev-s3-restore.test.mts +210 -14
  94. package/src/cli-replacement/dev-startup-git-before-dbfs-order.test.mts +35 -2
  95. package/src/cli-replacement/dev-token-priming.test.mts +103 -0
  96. package/src/cli-replacement/dev.interception.test.mts +80 -0
  97. package/src/cli-replacement/dev.mts +495 -92
  98. package/src/cli-replacement/home-npmrc.mts +409 -0
  99. package/src/cli-replacement/home-npmrc.test.mts +757 -0
  100. package/src/cli-replacement/install-packages.classify.test.mts +168 -0
  101. package/src/cli-replacement/install-packages.npm-registry.test.mts +345 -0
  102. package/src/cli-replacement/post-upgrade-lockfile-strip.mts +296 -0
  103. package/src/cli-replacement/post-upgrade-lockfile-strip.test.mts +482 -0
  104. package/src/cli-replacement/userconfig-env.integration.test.mts +189 -0
  105. package/src/dev-utils/dev-server-metrics.mts +96 -0
  106. package/src/dev-utils/dev-server-metrics.test.mts +38 -0
  107. package/src/dev-utils/dev-server.mts +48 -8
  108. package/src/dev-utils/dev-server.status.test.mts +58 -0
  109. package/src/dev-utils/token-manager.ts +36 -0
  110. package/src/telemetry/local-obs.ts +1 -1
  111. package/src/telemetry/util.ts +1 -1
  112. package/src/types/scoped-jwt-token-payload.ts +1 -0
  113. package/src/version-control.mts +8 -6
  114. package/tsconfig.tsbuildinfo +1 -1
  115. package/.turbo/turbo-publish-package.log +0 -0
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Failure-classification coverage for the dev-server startup `installPackages`
3
+ * (APPS-4450). When the verification install fails, `installPackages` no longer
4
+ * rethrows the raw `exec` rejection — it classifies the npm `--json` envelope
5
+ * into a structured `DependencyInstallError` and throws the
6
+ * `InitialInstallFailed` marker so the `dev()` catch can degrade by origin.
7
+ *
8
+ * Mirrors the mock style of the sibling `install-packages.npm-registry.test.mts`
9
+ * (stub `node:child_process`, `package-manager-detector`, `node:fs/promises`,
10
+ * and the logging module; hand a fake `NpmRegistryClient`). The one new wrinkle
11
+ * is the failure path: the promisified `exec` rejects with an error object that
12
+ * carries the ERESOLVE `--json` payload on `.stdout` and the npm error-code
13
+ * banner on `.stderr`, exactly as `util.promisify(child_process.exec)` does in
14
+ * production (it preserves stdout/stderr on the rejected error).
15
+ */
16
+ import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
17
+ const execMock = vi.fn();
18
+ const execFileMock = vi.fn();
19
+ vi.mock("node:child_process", () => ({
20
+ default: { exec: execMock, execFile: execFileMock },
21
+ exec: execMock,
22
+ execFile: execFileMock,
23
+ }));
24
+ const detectMock = vi.fn();
25
+ vi.mock("package-manager-detector/detect", () => ({
26
+ detect: (...args) => detectMock(...args),
27
+ }));
28
+ const resolveCommandMock = vi.fn();
29
+ vi.mock("package-manager-detector", () => ({
30
+ resolveCommand: (...args) => resolveCommandMock(...args),
31
+ }));
32
+ vi.mock("node:fs/promises", () => ({
33
+ readFile: vi.fn(async () => "{}"),
34
+ writeFile: vi.fn(async () => undefined),
35
+ // `installPackages` ensures `<app>/.superblocks/logs` exists (npm's
36
+ // `logs-dir` target) before spawning the install; without this stub the
37
+ // real `mkdir` is undefined and throws before the exec mock, misclassifying
38
+ // the failure as `unknown`. Mirrors the sibling npm-registry test.
39
+ mkdir: vi.fn(async () => undefined),
40
+ }));
41
+ const mockLogger = {
42
+ info: vi.fn(),
43
+ warn: vi.fn(),
44
+ error: vi.fn(),
45
+ debug: vi.fn(),
46
+ };
47
+ vi.mock("../telemetry/logging.js", () => ({
48
+ getLogger: () => mockLogger,
49
+ getErrorMeta: (err) => ({
50
+ error: { kind: "Error", message: err instanceof Error ? err.message : "" },
51
+ }),
52
+ }));
53
+ function fakeRegistryClient(result) {
54
+ return {
55
+ getConfig: vi.fn(async () => typeof result === "function" ? result() : result),
56
+ };
57
+ }
58
+ function notConfigured() {
59
+ return { source: "not-configured", config: { configured: false } };
60
+ }
61
+ /**
62
+ * The ERESOLVE `--json` envelope npm writes to stdout when a peer-dependency
63
+ * conflict aborts the install. `util.promisify(exec)` rejects with an Error
64
+ * whose `.stdout` carries this body and whose `.stderr` carries the
65
+ * `npm error code ERESOLVE` banner — both preserved separately on the
66
+ * rejected error (the contract the classifier relies on).
67
+ */
68
+ const ERESOLVE_JSON_STDOUT = JSON.stringify({
69
+ error: {
70
+ code: "ERESOLVE",
71
+ summary: "unable to resolve dependency tree",
72
+ detail: "Found: react@17.0.2\nCould not resolve dependency:\npeer react@^18.0.0 from @some/pkg@1.0.0",
73
+ },
74
+ });
75
+ const ERESOLVE_STDERR = [
76
+ "npm error code ERESOLVE",
77
+ "npm error ERESOLVE unable to resolve dependency tree",
78
+ ].join("\n");
79
+ beforeAll(async () => {
80
+ await import("./dev.mjs");
81
+ });
82
+ beforeEach(() => {
83
+ vi.clearAllMocks();
84
+ detectMock.mockResolvedValue({
85
+ name: "npm",
86
+ agent: "npm",
87
+ version: "10.0.0",
88
+ });
89
+ resolveCommandMock.mockImplementation((_agent, _action, args) => ({
90
+ command: "npm",
91
+ args: ["install", ...args],
92
+ }));
93
+ });
94
+ describe("installPackages classifies install failures (APPS-4450)", () => {
95
+ it("throws InitialInstallFailed(dependency_conflict) on an ERESOLVE install", async () => {
96
+ const { installPackages } = await import("./dev.mjs");
97
+ const client = fakeRegistryClient(notConfigured());
98
+ // Reject exactly the way `util.promisify(child_process.exec)` does: the
99
+ // rejected value is an Error with `.stdout` and `.stderr` preserved
100
+ // separately. The ERESOLVE `--json` body lives on `.stdout`.
101
+ execMock.mockImplementation((_cmd, _opts, cb) => {
102
+ const callback = (typeof _opts === "function" ? _opts : cb);
103
+ const err = Object.assign(new Error("Command failed: npm install --fund=false --audit=false"), {
104
+ stdout: ERESOLVE_JSON_STDOUT,
105
+ stderr: ERESOLVE_STDERR,
106
+ code: 1,
107
+ });
108
+ callback(err);
109
+ });
110
+ await expect(installPackages("/tmp/app", mockLogger, client)).rejects.toMatchObject({
111
+ name: "InitialInstallFailed",
112
+ serverError: {
113
+ category: "dependency_conflict",
114
+ npmErrorCode: "ERESOLVE",
115
+ },
116
+ });
117
+ // Guard against the mock being silently bypassed: if `dev.mjs` ever binds
118
+ // `exec` to the REAL `child_process.exec` (a module-scope capture before
119
+ // this file's mock is live), real npm runs against the missing `/tmp/app`
120
+ // and the classification quietly degrades to unknown/undefined. Asserting
121
+ // the stub fired turns that into an explicit failure instead. (APPS-4450)
122
+ expect(execMock).toHaveBeenCalledTimes(1);
123
+ });
124
+ });
125
+ //# sourceMappingURL=install-packages.classify.test.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-packages.classify.test.mjs","sourceRoot":"","sources":["../../src/cli-replacement/install-packages.classify.test.mts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=install-packages.npm-registry.test.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-packages.npm-registry.test.d.mts","sourceRoot":"","sources":["../../src/cli-replacement/install-packages.npm-registry.test.mts"],"names":[],"mappings":""}
@@ -0,0 +1,260 @@
1
+ /**
2
+ * Argv-matrix coverage for the dev-server startup `installPackages` honoring
3
+ * the per-org `allow_install_scripts` policy (APPS-4251).
4
+ *
5
+ * Mirrors the structure of
6
+ * `packages/vite-plugin-file-sync/src/ai-service/app-interface/shell.npm-registry.test.ts`
7
+ * (the AppShell-side coverage): we stub `package-manager-detector`, capture
8
+ * the args handed to `resolveCommand`, drive a fake `NpmRegistryClient`, and
9
+ * assert whether `--ignore-scripts` made it onto the install argv.
10
+ *
11
+ * Why exercise this here rather than via the full `dev()` test surface:
12
+ * `installPackages` is the unit that picked up the new policy plumbing.
13
+ * Testing through `dev()` would need ~250 lines of mock setup unrelated to
14
+ * the policy decision, and the test would still be asserting the same
15
+ * `resolveCommand`-args invariant. The function is intentionally exported
16
+ * from `dev.mts` for this purpose.
17
+ */
18
+ import { beforeAll, beforeEach, describe, expect, it, vi, } from "vitest";
19
+ const execMock = vi.fn();
20
+ const execFileMock = vi.fn();
21
+ vi.mock("node:child_process", () => ({
22
+ default: { exec: execMock, execFile: execFileMock },
23
+ exec: execMock,
24
+ execFile: execFileMock,
25
+ }));
26
+ const detectMock = vi.fn();
27
+ vi.mock("package-manager-detector/detect", () => ({
28
+ detect: (...args) => detectMock(...args),
29
+ }));
30
+ const resolveCommandMock = vi.fn();
31
+ vi.mock("package-manager-detector", () => ({
32
+ resolveCommand: (...args) => resolveCommandMock(...args),
33
+ }));
34
+ vi.mock("node:fs/promises", () => ({
35
+ readFile: vi.fn(async () => "{}"),
36
+ writeFile: vi.fn(async () => undefined),
37
+ // `installPackages` ensures the `<app>/.superblocks/logs` dir exists
38
+ // before spawning the install (npm's `logs-dir` target).
39
+ mkdir: vi.fn(async () => undefined),
40
+ }));
41
+ const mockLogger = {
42
+ info: vi.fn(),
43
+ warn: vi.fn(),
44
+ error: vi.fn(),
45
+ debug: vi.fn(),
46
+ };
47
+ vi.mock("../telemetry/logging.js", () => ({
48
+ getLogger: () => mockLogger,
49
+ getErrorMeta: (err) => ({
50
+ error: { kind: "Error", message: err instanceof Error ? err.message : "" },
51
+ }),
52
+ }));
53
+ function fakeRegistryClient(result) {
54
+ return {
55
+ getConfig: vi.fn(async () => typeof result === "function" ? result() : result),
56
+ // The dev-server install path only calls `getConfig()`; the rest of the
57
+ // `NpmRegistryClient` surface (JWT refresh, cache TTL) is exercised by
58
+ // the vite-plugin-file-sync side. Casting through `unknown` lets us
59
+ // hand this minimal stub to a parameter typed `NpmRegistryClient`
60
+ // without dragging the full class into the test.
61
+ };
62
+ }
63
+ function notConfigured(allowInstallScripts) {
64
+ return {
65
+ source: "not-configured",
66
+ config: {
67
+ configured: false,
68
+ ...(allowInstallScripts !== undefined ? { allowInstallScripts } : {}),
69
+ },
70
+ };
71
+ }
72
+ // Pre-import `./dev.mjs` once so the heavy module-load cost (it transitively
73
+ // pulls in `vite-plugin-file-sync/git-service`, `AiService`, etc.) is paid
74
+ // outside any test's per-test timeout. Under turbo parallelism (CI runs the
75
+ // `cli` unit-test job alongside ai-service-templates, cli, mcp-server, and
76
+ // sdk in the same worker pool), the first dynamic `await import("./dev.mjs")`
77
+ // inside a test was being CPU-starved past the default 5s testTimeout — the
78
+ // test that owned the cold import then timed out, leaked its in-flight
79
+ // `resolveCommand` call past the `beforeEach` `clearAllMocks`, and the *next*
80
+ // test observed two recorded calls instead of one. Hoisting to `beforeAll`
81
+ // keeps the per-test surface fast and order-independent. The repeated
82
+ // `await import("./dev.mjs")` lines below remain as cheap cached lookups —
83
+ // no behavioural change.
84
+ beforeAll(async () => {
85
+ await import("./dev.mjs");
86
+ });
87
+ beforeEach(() => {
88
+ vi.clearAllMocks();
89
+ // Default: npm package manager, install resolves to a real command so we
90
+ // can read back the args the call site passed in.
91
+ detectMock.mockResolvedValue({
92
+ name: "npm",
93
+ agent: "npm",
94
+ version: "10.0.0",
95
+ });
96
+ resolveCommandMock.mockImplementation((_agent, _action, args) => ({
97
+ command: "npm",
98
+ args: ["install", ...args],
99
+ }));
100
+ execMock.mockImplementation((_cmd, _opts, cb) => {
101
+ if (typeof _opts === "function") {
102
+ _opts(null, {
103
+ stdout: "ok",
104
+ });
105
+ }
106
+ else if (cb) {
107
+ cb(null, { stdout: "ok" });
108
+ }
109
+ });
110
+ });
111
+ function getResolveCommandArgs() {
112
+ expect(resolveCommandMock).toHaveBeenCalledTimes(1);
113
+ const [, , args] = resolveCommandMock.mock.calls[0];
114
+ return args;
115
+ }
116
+ /** Pull the exec options (incl. `env`) out of the spawned subprocess
117
+ * call. We assert against the env-overlay because that is the mechanism
118
+ * userconfig pinning uses for npm AND pnpm (pnpm rejects `--userconfig=`
119
+ * as a CLI flag — pnpm/pnpm#6036). */
120
+ function getExecOptions() {
121
+ const lastCall = execMock.mock.calls.at(-1);
122
+ return lastCall[1];
123
+ }
124
+ describe("installPackages honors allow_install_scripts policy", () => {
125
+ it("appends --ignore-scripts when allow_install_scripts === false", async () => {
126
+ const { installPackages } = await import("./dev.mjs");
127
+ const client = fakeRegistryClient(notConfigured(false));
128
+ await installPackages("/tmp/app", mockLogger, client);
129
+ const args = getResolveCommandArgs();
130
+ expect(args).toContain("--ignore-scripts");
131
+ // Existing baseline npm flags must survive.
132
+ expect(args).toContain("--fund=false");
133
+ expect(args).toContain("--audit=false");
134
+ });
135
+ it("does NOT append --ignore-scripts when allow_install_scripts === true", async () => {
136
+ const { installPackages } = await import("./dev.mjs");
137
+ const client = fakeRegistryClient(notConfigured(true));
138
+ await installPackages("/tmp/app", mockLogger, client);
139
+ expect(getResolveCommandArgs()).not.toContain("--ignore-scripts");
140
+ });
141
+ it("does NOT append --ignore-scripts when allow_install_scripts is unset", async () => {
142
+ const { installPackages } = await import("./dev.mjs");
143
+ const client = fakeRegistryClient(notConfigured(undefined));
144
+ await installPackages("/tmp/app", mockLogger, client);
145
+ expect(getResolveCommandArgs()).not.toContain("--ignore-scripts");
146
+ });
147
+ it("does NOT append --ignore-scripts when no client is wired in (test/opt-out path)", async () => {
148
+ const { installPackages } = await import("./dev.mjs");
149
+ await installPackages("/tmp/app", mockLogger);
150
+ expect(getResolveCommandArgs()).not.toContain("--ignore-scripts");
151
+ });
152
+ it("swallows policy-resolution errors and proceeds without --ignore-scripts", async () => {
153
+ // A transient registry-endpoint outage with no cache must not abort the
154
+ // user's startup install. The client surfaces the throw; we log and
155
+ // fall back to "scripts allowed" (today's behaviour). The 404 /
156
+ // last-known-good preservation that prevents this in practice is
157
+ // covered by `npm-registry.test.ts` on the vite-plugin-file-sync side.
158
+ const { installPackages } = await import("./dev.mjs");
159
+ const client = fakeRegistryClient(async () => {
160
+ throw new Error("registry endpoint unreachable");
161
+ });
162
+ await installPackages("/tmp/app", mockLogger, client);
163
+ expect(getResolveCommandArgs()).not.toContain("--ignore-scripts");
164
+ expect(mockLogger.warn).toHaveBeenCalledWith(expect.stringContaining("Could not resolve npm install-scripts policy"), expect.objectContaining({ error: expect.any(Object) }));
165
+ });
166
+ it("appends --ignore-scripts under pnpm too (no npm-only baseline flags)", async () => {
167
+ detectMock.mockResolvedValue({
168
+ name: "pnpm",
169
+ agent: "pnpm",
170
+ version: "9.0.0",
171
+ });
172
+ resolveCommandMock.mockImplementation((_agent, _action, args) => ({
173
+ command: "pnpm",
174
+ args: ["install", ...args],
175
+ }));
176
+ const { installPackages } = await import("./dev.mjs");
177
+ const client = fakeRegistryClient(notConfigured(false));
178
+ await installPackages("/tmp/app", mockLogger, client);
179
+ const args = getResolveCommandArgs();
180
+ expect(args).toContain("--ignore-scripts");
181
+ expect(args).not.toContain("--fund=false");
182
+ expect(args).not.toContain("--audit=false");
183
+ });
184
+ });
185
+ // ---------------------------------------------------------------------------
186
+ // Userconfig plumbing for the dev-server startup install.
187
+ //
188
+ // `installPackages` points npm/pnpm at the Superblocks-owned userconfig
189
+ // (`~/.superblocks/npmrc`) so the user-app install resolves
190
+ // `@superblocksteam/library`, `@superblocksteam/sdk-api`, and any private
191
+ // scope through the same registry config the CLI auto-upgrade uses.
192
+ //
193
+ // The mechanism is the spawned subprocess env overlay (both
194
+ // `NPM_CONFIG_USERCONFIG` and `PNPM_CONFIG_USERCONFIG`), not a CLI flag.
195
+ // pnpm rejects `--userconfig=` (pnpm/pnpm#6036), and pnpm 11+ stopped
196
+ // honouring the `npm_config_*` env vars — setting both forms covers
197
+ // npm, pnpm <= 10, and pnpm 11+ uniformly.
198
+ // `userconfig-env.integration.test.mts` in this directory exercises the
199
+ // real npm + pnpm binaries to pin that contract.
200
+ // ---------------------------------------------------------------------------
201
+ const USERCONFIG_PATTERN = /[/\\]\.superblocks[/\\]npmrc$/;
202
+ describe("installPackages userconfig env plumbing", () => {
203
+ it("sets both NPM_CONFIG_USERCONFIG and PNPM_CONFIG_USERCONFIG under npm", async () => {
204
+ const { installPackages } = await import("./dev.mjs");
205
+ const client = fakeRegistryClient(notConfigured(undefined));
206
+ await installPackages("/tmp/app", mockLogger, client);
207
+ const opts = getExecOptions();
208
+ expect(opts.env?.NPM_CONFIG_USERCONFIG).toMatch(USERCONFIG_PATTERN);
209
+ expect(opts.env?.PNPM_CONFIG_USERCONFIG).toMatch(USERCONFIG_PATTERN);
210
+ // npm's debug log is routed into `<app>/.superblocks/logs` so a failed
211
+ // install in the live-edit pod leaves a collectable log.
212
+ expect(opts.env?.NPM_CONFIG_LOGS_DIR).toBe("/tmp/app/.superblocks/logs");
213
+ // Argv carries the baseline npm flags only — no --userconfig (pnpm
214
+ // would reject it; env is the mechanism instead).
215
+ const args = getResolveCommandArgs();
216
+ expect(args.some((a) => a.startsWith("--userconfig="))).toBe(false);
217
+ expect(args).toContain("--fund=false");
218
+ expect(args).toContain("--audit=false");
219
+ });
220
+ it("sets both NPM_CONFIG_USERCONFIG and PNPM_CONFIG_USERCONFIG under pnpm", async () => {
221
+ detectMock.mockResolvedValue({
222
+ name: "pnpm",
223
+ agent: "pnpm",
224
+ version: "11.0.0",
225
+ });
226
+ resolveCommandMock.mockImplementation((_agent, _action, args) => ({
227
+ command: "pnpm",
228
+ args: ["install", ...args],
229
+ }));
230
+ const { installPackages } = await import("./dev.mjs");
231
+ const client = fakeRegistryClient(notConfigured(undefined));
232
+ await installPackages("/tmp/app", mockLogger, client);
233
+ const opts = getExecOptions();
234
+ expect(opts.env?.NPM_CONFIG_USERCONFIG).toMatch(USERCONFIG_PATTERN);
235
+ expect(opts.env?.PNPM_CONFIG_USERCONFIG).toMatch(USERCONFIG_PATTERN);
236
+ const args = getResolveCommandArgs();
237
+ expect(args.some((a) => a.startsWith("--userconfig="))).toBe(false);
238
+ expect(args).not.toContain("--audit=false");
239
+ });
240
+ it("sets the userconfig env alongside --ignore-scripts when policy is restrictive", async () => {
241
+ // The install-scripts policy gate (argv) and the userconfig pin
242
+ // (env) are independent knobs that must co-exist.
243
+ const { installPackages } = await import("./dev.mjs");
244
+ const client = fakeRegistryClient(notConfigured(false));
245
+ await installPackages("/tmp/app", mockLogger, client);
246
+ const args = getResolveCommandArgs();
247
+ expect(args).toContain("--ignore-scripts");
248
+ const opts = getExecOptions();
249
+ expect(opts.env?.NPM_CONFIG_USERCONFIG).toMatch(USERCONFIG_PATTERN);
250
+ expect(opts.env?.PNPM_CONFIG_USERCONFIG).toMatch(USERCONFIG_PATTERN);
251
+ });
252
+ // PATH-preservation coverage lives in two places that don't trip the
253
+ // turbo `no-undeclared-env-vars` lint:
254
+ // - `buildInstallEnv`'s "accepts a custom base env" test verifies
255
+ // the merge semantics directly without referencing `process.env`.
256
+ // - The real-subprocess integration test
257
+ // (`userconfig-env.integration.test.mts`) would fail to resolve
258
+ // `npm`/`pnpm` on PATH if the overlay clobbered it.
259
+ });
260
+ //# sourceMappingURL=install-packages.npm-registry.test.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-packages.npm-registry.test.mjs","sourceRoot":"","sources":["../../src/cli-replacement/install-packages.npm-registry.test.mts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Post-CLI-upgrade lockfile normalization for the dev-server pod's globally
3
+ * installed Superblocks CLI.
4
+ *
5
+ * npm honors `resolved` URLs verbatim, so a tarball whose bundled lockfile
6
+ * entries point at `registry.npmjs.org` keeps fetching from public npm even
7
+ * after we've written a private `.npmrc`. This module strips those URLs
8
+ * post-upgrade so subsequent installs re-resolve through the active registry.
9
+ *
10
+ * The walk from the resolved `superblocks` binary up to the CLI package root
11
+ * is bounded so a misconfigured layout can never mutate arbitrary lockfiles
12
+ * on the filesystem.
13
+ *
14
+ * All failures are logged and swallowed — a failed post-strip must not crash
15
+ * the pod after a working upgrade. The next dev startup repeats the strip
16
+ * idempotently.
17
+ */
18
+ import { type Logger } from "../telemetry/logging.js";
19
+ /**
20
+ * Injectable subset of `child_process.exec` so tests can stub the
21
+ * `which`/`where` lookup without spawning a real subprocess.
22
+ */
23
+ export type WhichRunner = (binary: string) => Promise<string>;
24
+ /**
25
+ * Discovers the absolute path of the `@superblocksteam/cli` install root
26
+ * (the directory containing the CLI's `package.json`), or returns `undefined`
27
+ * if discovery fails. Discovery failures are non-fatal — the caller logs and
28
+ * skips the strip rather than aborting.
29
+ */
30
+ export declare function findGlobalCliInstallDir(logger: Logger, whichRunner?: WhichRunner): Promise<string | undefined>;
31
+ export interface StripUpgradedCliLockfilesOptions {
32
+ /**
33
+ * Pre-resolved install root. If omitted, `findGlobalCliInstallDir` is used.
34
+ * Tests pass this directly to avoid stubbing `which`.
35
+ */
36
+ installDir?: string;
37
+ whichRunner?: WhichRunner;
38
+ /**
39
+ * Override the strip timeout (ms). Tests use a tight value to exercise the
40
+ * timeout branch without sleeping for the real bound.
41
+ */
42
+ timeoutMs?: number;
43
+ }
44
+ /**
45
+ * Strips public-host `resolved` URLs from every lockfile under the global
46
+ * CLI install that the auto-upgrade could have refreshed. Returns the
47
+ * resolved install root on success, or `undefined` when discovery failed.
48
+ *
49
+ * Non-fatal: every individual strip already swallows lockfile-level errors
50
+ * (logged in `stripResolvedFromLockfilePath`); this wrapper additionally
51
+ * swallows discovery failures and any unexpected throw from the inner
52
+ * helpers so a successful upgrade is never demoted to a crash by a post-step
53
+ * problem.
54
+ */
55
+ export declare function stripUpgradedCliLockfiles(logger: Logger, options?: StripUpgradedCliLockfilesOptions): Promise<{
56
+ installDir?: string;
57
+ }>;
58
+ //# sourceMappingURL=post-upgrade-lockfile-strip.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post-upgrade-lockfile-strip.d.mts","sourceRoot":"","sources":["../../src/cli-replacement/post-upgrade-lockfile-strip.mts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAYH,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAoCpE;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAQ9D;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,WAAW,GAAE,WAAgC,GAC5C,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAqG7B;AAED,MAAM,WAAW,gCAAgC;IAC/C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,gCAAqC,GAC7C,OAAO,CAAC;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA+ElC"}