@somewhere-tech/cli 0.31.0 → 0.31.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@somewhere-tech/cli",
3
- "version": "0.31.0",
3
+ "version": "0.31.2",
4
4
  "description": "CLI for somewhere.tech — auth, projects, deploy, pull, promote, db, logs, env, MCP bridge.",
5
5
  "keywords": [
6
6
  "somewhere",
@@ -1,8 +1,8 @@
1
1
  {
2
- "commit": "d8fc42de",
2
+ "commit": "3237dc1e",
3
3
  "files": {
4
- "sw-init.mjs": "7e7e43ecc22cd7098360f5122b7030dd129a834c63c0bd7ffa2ded6fb5264269",
5
- "platform-context.mjs": "6aa7d869dbbf221d4040c0ddecb2e37ff0f5bd5d8849c7727b868979398240c6",
6
- "browser-probes.mjs": "2a8d601045ef2c182c3d482ffaa86db5e8b92e2f51b2a0ca6743afb12cb3f880"
4
+ "sw-init.mjs": "ad6b9169aa1529a87a320a812d2a575288c095d3403296042770f6ee7ca2de9a",
5
+ "platform-context.mjs": "c98b6dc87001e47fa0ed96af462b6739d25e37d8f132f15420fe44e109a87e31",
6
+ "browser-probes.mjs": "171eef34120b730ece88995654fd341b6ef5f83da6ec0fc7ce63835bd457e4c2"
7
7
  }
8
8
  }
@@ -1,4 +1,4 @@
1
- // VENDORED from worker/src/utils/browser-test.ts (DOM_OUTLINE_SCRIPT) @ d8fc42de
1
+ // VENDORED from worker/src/utils/browser-test.ts (DOM_OUTLINE_SCRIPT) @ 3237dc1e
2
2
  // — the exact runtime deployed functions run against. Do not edit by hand;
3
3
  // re-sync with: node scripts/extract-runtime.mjs <monorepo>
4
4
  export const MAX_OUTLINE_NODES = 200;
@@ -1,5 +1,5 @@
1
1
  {
2
- "commit": "d8fc42de",
2
+ "commit": "3237dc1e",
3
3
  "esbuild": "0.24.0",
4
4
  "toolchain": {
5
5
  "base": {
@@ -57,7 +57,7 @@
57
57
  }
58
58
  },
59
59
  "files": {
60
- "compile-core.cjs": "4117fcbf26ac4e06b1ab3492802a4097dd250f3ea1ec9ef5214327defd3663fc",
60
+ "compile-core.cjs": "944c430803c04bb976f1cc4e1576015e518e114e53994d5bf2cbdadc6ed8fb2e",
61
61
  "graph-contract.cjs": "aaeebc34f486ee5f639444de5757accfc283de641e631908ccd8d8c688bfb5c0",
62
62
  "typed-functions.cjs": "5c0b499015dcdf755ca72dab04a80afce0891e782f835547592faec802c63be6"
63
63
  }
@@ -859,6 +859,65 @@ function functionLocalImportPlugin(root) {
859
859
  * Build a compiler instance bound to one host environment.
860
860
  * @param {object} host — see the file header for the complete contract.
861
861
  */
862
+ /**
863
+ * Build-CONFIG files, which are never in the browser graph.
864
+ *
865
+ * The platform IS the bundler, so a project's vite/rollup/webpack/postcss/
866
+ * tailwind config is never executed by anything the compiler emits. Scanning
867
+ * them for phantom imports produced a warning whose own premise was false —
868
+ * "if that code path runs, your app will fail to load it", for a code path
869
+ * that cannot run — on our OWN init scaffold, whose vite.config.ts imports
870
+ * vite and @vitejs/plugin-react (tsk_424174be).
871
+ */
872
+ function isBuildConfigFile(filePath) {
873
+ const base = filePath.split('/').pop() || '';
874
+ return /^(?:vite|vitest|rollup|webpack|next|nuxt|svelte|astro|remix|tailwind|postcss|babel|jest|playwright|cypress|eslint|prettier|stylelint)\.config\.[cm]?[jt]sx?$/i.test(base);
875
+ }
876
+
877
+ /* ─── devDependencies the app's own source actually imports (tsk_2a7c6b33) ────
878
+ * The install is `dependencies`-only BY DESIGN — the platform is the build
879
+ * toolchain, so vite/typescript/@vitejs/* have no business in a per-build
880
+ * install. That was always the stated rule, and `missing` always honoured it,
881
+ * but `npm install <specs>` runs in a build root holding the customer's whole
882
+ * package.json and npm reifies the FULL declared tree from it, devDependencies
883
+ * included. Measured on our own `somewhere init` scaffold: 74 packages / 72 MB
884
+ * with the dev closure (vite, rollup, @babel/*, esbuild + its platform binary,
885
+ * typescript, @types/*), 8 packages / 13 MB without it. Every scaffold deploy
886
+ * has been paying for a toolchain the bundle never imports, and on a slow or
887
+ * churning instance that is what puts an install over the 300 s build budget.
888
+ * `--omit=dev` on the npm side closes it (server.js).
889
+ *
890
+ * RULE 9 — THE CARVE-OUT THAT KEEPS WORKING CODE WORKING: because the dev
891
+ * closure landed incidentally, a project that IMPORTS a dev-declared package
892
+ * from its own source has always had that import resolve. Dropping the dev
893
+ * tree wholesale would turn those builds into "Could not resolve" failures —
894
+ * the exact class rule 9 forbids. So a devDependency the source imports is
895
+ * installed EXPLICITLY, by name, and nothing that builds today stops building.
896
+ * Only the unimported remainder — the toolchain — goes away.
897
+ *
898
+ * BUILD-CONFIG FILES ARE EXCLUDED, and that exclusion is the whole point: the
899
+ * scaffold's own vite.config.ts imports `vite` and `@vitejs/plugin-react`, and
900
+ * the platform never executes it (isBuildConfigFile, tsk_424174be). Counting it
901
+ * as an import would reinstall the toolchain and buy nothing.
902
+ */
903
+ function importedDevDeps(pkg, files) {
904
+ const declared = (pkg && pkg.devDependencies) || {};
905
+ const names = Object.keys(declared);
906
+ if (!names.length || !files || typeof files !== 'object') return [];
907
+ const declaredSet = new Set(names);
908
+ const hit = new Set();
909
+ for (const [filePath, content] of Object.entries(files)) {
910
+ if (typeof content !== 'string') continue;
911
+ if (!/\.(tsx?|jsx?|mjs|cjs)$/i.test(filePath)) continue;
912
+ if (isBuildConfigFile(filePath)) continue;
913
+ for (const spec of extractBareSpecifiers(content)) {
914
+ const root = specRootPkg(spec);
915
+ if (declaredSet.has(root)) hit.add(root);
916
+ }
917
+ }
918
+ return [...hit];
919
+ }
920
+
862
921
  function createCompileCore(host) {
863
922
  if (!host || typeof host !== 'object') throw new Error('createCompileCore(host) requires a host');
864
923
  for (const required of ['imageNodeModules', 'requireImage', 'installPackages']) {
@@ -977,12 +1036,22 @@ function createCompileCore(host) {
977
1036
  * per-build install lands in the build root, which esbuild resolves before
978
1037
  * the baked nodePaths, so the project's pin wins.
979
1038
  * devDependencies (tailwind, vite, etc.) are NOT installed — the build toolchain
980
- * is the container's job, not the app's.
1039
+ * is the container's job, not the app's. The ONE exception is a devDependency
1040
+ * the project's own source imports: see importedDevDeps (tsk_2a7c6b33) for why
1041
+ * that carve-out exists and why it is not optional.
981
1042
  */
982
1043
 
983
1044
 
984
- async function ensureDeps(root, pkg, warnings, ctx, scopedProxyReady = true) {
985
- const deps = (pkg && pkg.dependencies) || {};
1045
+ async function ensureDeps(root, pkg, warnings, ctx, scopedProxyReady = true, sourceFiles = null) {
1046
+ // `dependencies`, plus any devDependency the source actually imports. npm
1047
+ // is told `--omit=dev` (server.js), so anything the app really needs must
1048
+ // be named here explicitly — which is what keeps a build that resolves a
1049
+ // dev-declared import today resolving it tomorrow (rule 9).
1050
+ const declaredDev = (pkg && pkg.devDependencies) || {};
1051
+ const deps = { ...((pkg && pkg.dependencies) || {}) };
1052
+ for (const name of importedDevDeps(pkg, sourceFiles)) {
1053
+ if (!(name in deps)) deps[name] = declaredDev[name];
1054
+ }
986
1055
  const buildRoot = path.join(root, 'node_modules');
987
1056
  // The project's own lockfile, materialized alongside package.json. It IS
988
1057
  // uploaded on every deploy and was, until now, ignored — which is what made
@@ -1078,21 +1147,6 @@ function createCompileCore(host) {
1078
1147
  }
1079
1148
  }
1080
1149
 
1081
- /**
1082
- * Build-CONFIG files, which are never in the browser graph.
1083
- *
1084
- * The platform IS the bundler, so a project's vite/rollup/webpack/postcss/
1085
- * tailwind config is never executed by anything the compiler emits. Scanning
1086
- * them for phantom imports produced a warning whose own premise was false —
1087
- * "if that code path runs, your app will fail to load it", for a code path
1088
- * that cannot run — on our OWN init scaffold, whose vite.config.ts imports
1089
- * vite and @vitejs/plugin-react (tsk_424174be).
1090
- */
1091
- function isBuildConfigFile(filePath) {
1092
- const base = filePath.split('/').pop() || '';
1093
- return /^(?:vite|vitest|rollup|webpack|next|nuxt|svelte|astro|remix|tailwind|postcss|babel|jest|playwright|cypress|eslint|prettier|stylelint)\.config\.[cm]?[jt]sx?$/i.test(base);
1094
- }
1095
-
1096
1150
  /** Make the implicit project root explicit for path aliases. */
1097
1151
  function normalizeTsconfigText(tsconfigText) {
1098
1152
  if (typeof tsconfigText !== 'string') return tsconfigText;
@@ -1143,11 +1197,12 @@ function isBuildConfigFile(filePath) {
1143
1197
  // packages, so "add it to your package.json" is wrong advice on code our
1144
1198
  // own docs hand the developer (tsk_53badecfb7).
1145
1199
  if (PLATFORM_MODULE_ROOTS.has(rootPkg)) continue;
1146
- // DECLARED in devDependencies. ensureDeps deliberately installs only
1147
- // `dependencies` (the build toolchain is the platform's job, not the
1148
- // app's), so a devDependency is never resolvable here but it IS
1149
- // declared, and "add it to your package.json" is already done. Warning
1150
- // about it is a false positive with wrong remediation (tsk_424174be).
1200
+ // DECLARED in devDependencies. It IS declared, so "add it to your
1201
+ // package.json" is already done and warning about it is a false
1202
+ // positive with wrong remediation (tsk_424174be) whether or not it
1203
+ // resolved. (Since tsk_2a7c6b33 a dev-declared package the source
1204
+ // imports IS installed by name, so this branch is now mostly reached
1205
+ // by build-config imports, which are skipped above anyway.)
1151
1206
  if (devDeclared.has(rootPkg)) continue;
1152
1207
  // Resolvable through NODE_POLYFILLS alias (e.g. 'buffer', 'process')
1153
1208
  if (polyfillKeys.has(rootPkg)) continue;
@@ -1612,7 +1667,10 @@ function isBuildConfigFile(filePath) {
1612
1667
  // container is egress-locked and must fail closed, the CLI reaches npm
1613
1668
  // directly through the developer's own config. Default is the container's
1614
1669
  // refusal, so opening it is always deliberate.
1615
- await ensureDeps(root, pkg, warnings, ctx, hasScopedProxy || host.requiresPackageProxy === false);
1670
+ // `files` (frontend AND function sources) is what decides the one
1671
+ // devDependency carve-out — a dev-declared package the app imports is
1672
+ // installed by name so the install can otherwise skip the dev closure.
1673
+ await ensureDeps(root, pkg, warnings, ctx, hasScopedProxy || host.requiresPackageProxy === false, files);
1616
1674
  timing.install = _ms(_tInstall);
1617
1675
 
1618
1676
  // Dependency review (PR1) — WARN-FIRST, non-blocking. A scanner bug must
@@ -1926,6 +1984,10 @@ module.exports = {
1926
1984
  lockfileVersions,
1927
1985
  resolveInstallSpec,
1928
1986
  cleanRange,
1987
+ // The devDependency carve-out (tsk_2a7c6b33) — pure, exported so the fixture
1988
+ // can pin BOTH directions: the toolchain is dropped, an imported dev-declared
1989
+ // package is not.
1990
+ importedDevDeps,
1929
1991
  NODE_POLYFILLS,
1930
1992
  ASSET_LOADERS,
1931
1993
  KNOWN_BAD_VERSIONS,
@@ -1,4 +1,4 @@
1
- // VENDORED from worker/src/runtime/context.ts (PLATFORM_CONTEXT_JS) @ d8fc42de
1
+ // VENDORED from worker/src/runtime/context.ts (PLATFORM_CONTEXT_JS) @ 3237dc1e
2
2
  // — the exact runtime deployed functions run against. Do not edit by hand;
3
3
  // re-sync with: node scripts/extract-runtime.mjs <monorepo>
4
4
  // ── Primordial freeze (tsk_327fe8a4, opinionated-not-greenfield) ───────────
@@ -1,4 +1,4 @@
1
- // VENDORED from worker/src/utils/function-bundle.ts (SW_INIT_JS) @ d8fc42de
1
+ // VENDORED from worker/src/utils/function-bundle.ts (SW_INIT_JS) @ 3237dc1e
2
2
  // — the exact runtime deployed functions run against. Do not edit by hand;
3
3
  // re-sync with: node scripts/extract-runtime.mjs <monorepo>
4
4
  // Generated by somewhere.tech deploy pipeline. Sets up the global