@substrat-run/cli 0.49.7 → 0.51.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 (58) hide show
  1. package/README.md +31 -0
  2. package/dist/changeset.d.ts.map +1 -1
  3. package/dist/changeset.js +19 -6
  4. package/dist/changeset.js.map +1 -1
  5. package/dist/cli.js +96 -28
  6. package/dist/cli.js.map +1 -1
  7. package/dist/data-loss-check.d.ts.map +1 -1
  8. package/dist/data-loss-check.js +11 -1
  9. package/dist/data-loss-check.js.map +1 -1
  10. package/dist/dev-preload.d.ts +2 -0
  11. package/dist/dev-preload.d.ts.map +1 -0
  12. package/dist/dev-preload.js +32 -0
  13. package/dist/dev-preload.js.map +1 -0
  14. package/dist/dev-traces.d.ts +16 -0
  15. package/dist/dev-traces.d.ts.map +1 -0
  16. package/dist/dev-traces.js +191 -0
  17. package/dist/dev-traces.js.map +1 -0
  18. package/dist/dev.d.ts +6 -0
  19. package/dist/dev.d.ts.map +1 -0
  20. package/dist/dev.js +67 -0
  21. package/dist/dev.js.map +1 -0
  22. package/dist/doctor.d.ts +34 -0
  23. package/dist/doctor.d.ts.map +1 -0
  24. package/dist/doctor.js +89 -0
  25. package/dist/doctor.js.map +1 -0
  26. package/dist/login.d.ts +12 -0
  27. package/dist/login.d.ts.map +1 -1
  28. package/dist/login.js +22 -3
  29. package/dist/login.js.map +1 -1
  30. package/dist/outbound-scan.d.ts +1 -1
  31. package/dist/outbound-scan.d.ts.map +1 -1
  32. package/dist/outbound-scan.js +6 -4
  33. package/dist/outbound-scan.js.map +1 -1
  34. package/dist/preview.d.ts +2 -2
  35. package/dist/preview.js +1 -1
  36. package/dist/promote.d.ts +2 -1
  37. package/dist/promote.d.ts.map +1 -1
  38. package/dist/promote.js +4 -3
  39. package/dist/promote.js.map +1 -1
  40. package/dist/prompt.d.ts +21 -0
  41. package/dist/prompt.d.ts.map +1 -0
  42. package/dist/prompt.js +39 -0
  43. package/dist/prompt.js.map +1 -0
  44. package/dist/published-concept.d.ts +3 -0
  45. package/dist/published-concept.d.ts.map +1 -0
  46. package/dist/published-concept.js +28 -0
  47. package/dist/published-concept.js.map +1 -0
  48. package/dist/push.d.ts +38 -1
  49. package/dist/push.d.ts.map +1 -1
  50. package/dist/push.js +270 -111
  51. package/dist/push.js.map +1 -1
  52. package/dist/store-driver.d.ts.map +1 -1
  53. package/dist/store-driver.js +5 -3
  54. package/dist/store-driver.js.map +1 -1
  55. package/dist/worker-node-imports.d.ts.map +1 -1
  56. package/dist/worker-node-imports.js +2 -1
  57. package/dist/worker-node-imports.js.map +1 -1
  58. package/package.json +6 -6
@@ -0,0 +1,28 @@
1
+ import { existsSync, readFileSync, realpathSync, statSync } from 'node:fs';
2
+ import { isAbsolute, relative, resolve, sep } from 'node:path';
3
+ import { CONCEPT_BYTES_MAX, publishedConcept } from '@substrat-run/contracts';
4
+ /** Publish only an explicitly named file. A design document's mere existence grants no access. */
5
+ export function readPublishedConcept(dir) {
6
+ const packageFile = resolve(dir, 'package.json');
7
+ if (!existsSync(packageFile))
8
+ return undefined;
9
+ const pkg = JSON.parse(readFileSync(packageFile, 'utf8'));
10
+ const path = pkg.substrat?.concept;
11
+ if (path === undefined)
12
+ return undefined;
13
+ if (typeof path !== 'string' || !path.trim() || isAbsolute(path)) {
14
+ throw new Error('substrat.concept must name a file relative to the application directory');
15
+ }
16
+ const root = realpathSync(dir);
17
+ const file = realpathSync(resolve(root, path));
18
+ const rel = relative(root, file);
19
+ if (rel === '..' || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {
20
+ throw new Error('substrat.concept must stay inside the application directory, including symlinks');
21
+ }
22
+ const stat = statSync(file);
23
+ if (!stat.isFile() || stat.size > CONCEPT_BYTES_MAX) {
24
+ throw new Error(`substrat.concept must be a file of at most ${CONCEPT_BYTES_MAX} UTF-8 bytes`);
25
+ }
26
+ return publishedConcept.parse(readFileSync(file, 'utf8'));
27
+ }
28
+ //# sourceMappingURL=published-concept.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"published-concept.js","sourceRoot":"","sources":["../src/published-concept.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE9E,kGAAkG;AAClG,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IACjD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAyC,CAAC;IAClG,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC;IACnC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC7F,CAAC;IACD,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACrG,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,8CAA8C,iBAAiB,cAAc,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,gBAAgB,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;AAC5D,CAAC"}
package/dist/push.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type DeclaredMigration, type AssetEntry, type AssetsNeed, type DeclaredBinding, type DeclaredOperationOutput, type IngressModel, type EnvVarSpec, type PermissionRegistry, type PermissionsInput, type RuntimeNeeds, type VersionOrigin, type DeployManifest } from '@substrat-run/contracts';
1
+ import { type DeclaredMigration, type AssetEntry, type AssetsNeed, type DeclaredBinding, type DeclaredOperationOutput, type IngressModel, type EnvVarSpec, type PermissionRegistry, type PermissionsInput, type RuntimeNeeds, type VersionOrigin, type DeployManifest, type VerticalConnectorDeclaration } from '@substrat-run/contracts';
2
2
  import { type DataLossCheck, type ReplayInputs } from './data-loss-check.js';
3
3
  import { type ScheduleRef } from './schedule-sweeper.js';
4
4
  /**
@@ -130,6 +130,9 @@ export interface DeclaredSurface {
130
130
  readonly declaresAttachments: boolean;
131
131
  /** What the data-loss check replays (#2321) — see `checkMigrationDataLoss`. */
132
132
  readonly replay: ReplayInputs;
133
+ /** The `substrat.connectors` entry's declarations (vertical-connectors.md §5.1), validated —
134
+ * undefined when the vertical declares none, so the manifest field stays absent. */
135
+ readonly connectors: VerticalConnectorDeclaration[] | undefined;
133
136
  }
134
137
  export declare function deriveDeclaredSurface(dir: string): Promise<DeclaredSurface>;
135
138
  /** The declared permission surface alone — `deriveDeclaredSurface` for the callers that
@@ -553,6 +556,40 @@ export declare function assertAttachmentBindingFree(bindings: readonly {
553
556
  * inside one, where `dir` is '.' and joining twice is a no-op.
554
557
  */
555
558
  export declare function generatedConfigPath(dir: string): string;
559
+ /**
560
+ * The vertical's own wrangler: the script its `bin` names, and the version that script is.
561
+ *
562
+ * Resolved the way Node resolves an import from the vertical (its `node_modules`, then each
563
+ * parent's, so a workspace that hoists wrangler to its root still finds it), and run as
564
+ * `node <bin>`. Not through `npx`, for two reasons:
565
+ *
566
+ * - On Windows `npx` is `npx.cmd`. Node will not spawn a batch file without a shell
567
+ * (CVE-2024-27980), and through a shell every argument is parsed twice — by cmd.exe and
568
+ * again by the batch file's `%*` — so a build path holding a space, `&`, `%` or `^` cannot
569
+ * be passed safely. `push` failed there with `spawnSync npx ENOENT` before it built anything.
570
+ * - `npx` downloads the newest wrangler when the project has none, without asking when stdin
571
+ * is not a TTY. The bundle a deploy ships then depends on the day it was built. The
572
+ * project's pinned wrangler is the only one this runs; a project without one is told so.
573
+ *
574
+ * Every node_modules directory is checked for `wrangler/package.json` on disk rather than
575
+ * through `require.resolve('wrangler/package.json')`, so the lookup never depends on which
576
+ * subpaths a given wrangler release lists in its `exports`.
577
+ */
578
+ export declare function resolveWrangler(dir: string): {
579
+ bin: string;
580
+ version: string;
581
+ };
582
+ /**
583
+ * The environment wrangler builds in: this process's, with the project's `node_modules/.bin`
584
+ * directories (its own, then each parent's, nearest first) and Node's own directory put in
585
+ * front of PATH.
586
+ *
587
+ * That is what `npx` used to give it, and the project's build command depends on it. Wrangler
588
+ * runs `build.command` (`runtimeNeeds.build`) through a shell on the PATH it was handed, so a
589
+ * build of `vite build` or `tsc` finds the project's own `vite` or `tsc` only when its `.bin`
590
+ * is there. A CLI installed globally, or started from a repository root, has no such entry.
591
+ */
592
+ export declare function wranglerEnv(dir: string, env?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
556
593
  export interface PreparedWorkerBundle {
557
594
  root: string;
558
595
  cfg: Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../src/push.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../src/push.ts"],"names":[],"mappings":"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"}
package/dist/push.js CHANGED
@@ -1,15 +1,17 @@
1
1
  import { execFileSync } from 'node:child_process';
2
2
  import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs';
3
3
  import { tmpdir } from 'node:os';
4
- import { join, basename, extname, relative, resolve } from 'node:path';
4
+ import { createRequire } from 'node:module';
5
+ import { join, basename, delimiter, dirname, extname, relative, resolve } from 'node:path';
5
6
  import { pathToFileURL } from 'node:url';
6
7
  import { webcrypto } from 'node:crypto';
7
8
  import { build } from 'esbuild';
8
- import { migrationDigestOf, DECLARED_OUTPUT_FIELDS_MAX, ASSET_PART_PREFIX, assetHash, assetsNeed, ATTACHMENT_BLOB_BINDING, buildPermissionRegistry, declaredOwnerGrants, ownerGrantSets, reservedKeyMessage, reservedKeyOffences, reservedKeysOf, declaresAttachmentTargets, DECLARED_MIGRATIONS_MAX, DECLARED_MIGRATIONS_SQL_BYTES_MAX, DEPLOY_MANIFEST_BYTES_SAFE, deployManifest, emittedModel, declaredMigrationDeclarations, sqlBytes, utf8Length, envVarSpec, runtimeNeeds, RUNTIME_BASELINE, PLATFORM_FEATURES_HEADER, PLATFORM_FEATURE_SCOPE_SWEEPER, assertDeclaredScopeStores, storeNamesOfBindings, manifestStoresOf, } from '@substrat-run/contracts';
9
+ import { migrationDigestOf, DECLARED_OUTPUT_FIELDS_MAX, ASSET_PART_PREFIX, assetHash, assetsNeed, ATTACHMENT_BLOB_BINDING, buildPermissionRegistry, declaredOwnerGrants, ownerGrantSets, reservedKeyMessage, reservedKeyOffences, reservedKeysOf, declaresAttachmentTargets, DECLARED_MIGRATIONS_MAX, DECLARED_MIGRATIONS_SQL_BYTES_MAX, DEPLOY_MANIFEST_BYTES_SAFE, deployManifest, emittedModel, declaredMigrationDeclarations, sqlBytes, utf8Length, envVarSpec, runtimeNeeds, RUNTIME_BASELINE, PLATFORM_FEATURES_HEADER, PLATFORM_FEATURE_SCOPE_SWEEPER, assertDeclaredScopeStores, storeNamesOfBindings, manifestStoresOf, pushedConnectorProblems, verticalConnectorDeclarations, } from '@substrat-run/contracts';
9
10
  import { lint, loadConfig as loadBoundaryLintConfig, resolvePackages, declaredEngines, formatViolations, maskSource, } from '@substrat-run/boundary-lint';
10
11
  import { walkPages } from '@substrat-run/control-plane-client';
11
12
  import { checkMigrationDataLoss } from './data-loss-check.js';
12
13
  import { parseJsonBody } from './http.js';
14
+ import { readPublishedConcept } from './published-concept.js';
13
15
  import { planeFor } from './plane.js';
14
16
  import { failureMessage } from './problem.js';
15
17
  import { assertWorkerNodeImports } from './worker-node-imports.js';
@@ -251,6 +253,32 @@ export function boundManifest(manifest, warn = console.warn) {
251
253
  const { migrations: _omitted, ...rest } = manifest;
252
254
  return rest;
253
255
  }
256
+ /**
257
+ * Bundle `contents` — an ES module whose imports resolve from `dir` — with every package left
258
+ * external, write it INTO `dir` so Node resolves those imports (@substrat-run/*, and any node
259
+ * addon a node-ful entry pulls) from the vertical's own node_modules, import it, and remove it.
260
+ * The unique name avoids the ESM import cache across pushes.
261
+ */
262
+ async function importBundledAsData(dir, stem, contents) {
263
+ const out = join(dir, `.substrat.${stem}.${Date.now()}.mjs`);
264
+ try {
265
+ await build({
266
+ stdin: { contents, resolveDir: resolve(dir), sourcefile: `substrat-${stem}.mjs`, loader: 'js' },
267
+ bundle: true,
268
+ platform: 'node',
269
+ format: 'esm',
270
+ packages: 'external',
271
+ outfile: out,
272
+ logLevel: 'silent',
273
+ });
274
+ // @vite-ignore: this is a real filesystem path imported at runtime, never a bundler input —
275
+ // the comment keeps vitest/vite from trying to resolve it through their transform pipeline.
276
+ return (await import(/* @vite-ignore */ pathToFileURL(out).href));
277
+ }
278
+ finally {
279
+ rmSync(out, { force: true });
280
+ }
281
+ }
254
282
  export async function deriveDeclaredSurface(dir) {
255
283
  const pkgPath = join(dir, 'package.json');
256
284
  // Named rather than left as an ENOENT trace: `substrat push --check` (#1205) is run from
@@ -274,121 +302,173 @@ export async function deriveDeclaredSurface(dir) {
274
302
  if (!existsSync(entryPath)) {
275
303
  throw new Error(`substrat.permissions points at "${entry}", which does not exist under ${dir}.`);
276
304
  }
277
- // Written INTO the vertical dir so Node resolves the externalised imports (@substrat-run/*,
278
- // and any node addon a node-ful entry pulls) from the vertical's own node_modules. Removed
279
- // immediately after import. The unique name avoids the ESM import cache across pushes.
280
- const out = join(dir, `.substrat.permissions.${Date.now()}.mjs`);
305
+ let mod;
281
306
  try {
282
- let mod;
307
+ // The entry, plus the vertical's OWN kernel (#1677), imported where the vertical
308
+ // resolves it: `packages: 'external'` keeps the specifier, so it loads from the
309
+ // vertical's node_modules. Optional — a vertical with none still reads as data.
310
+ // Both absolute: a CI job names the dir relatively (`substrat push demos/ticket0`), and
311
+ // a relative path written as an import specifier is a BARE one — `packages: 'external'`
312
+ // then keeps `demos/…` as a package named `demos`, which Node cannot find. `join` also
313
+ // strips a leading `./`, so spelling the dir `./demos/…` would not have saved it.
314
+ // The specifiers are the VERTICAL's packages, resolved from its node_modules, never the CLI's
315
+ // own dependencies; spelled through `q` so `lint:deps`, which reads text, does not count them.
316
+ const q = JSON.stringify;
317
+ mod = await importBundledAsData(dir, 'permissions', `export * from ${q(resolve(entryPath))};\n` +
318
+ `export const __substratKernel = await import(${q('@substrat-run/kernel')}).catch(() => null);\n` +
319
+ // The spine the data-loss replay builds first (#2321), from the vertical's own
320
+ // adapter-sqlite — imported only when a replay runs, since it loads a native driver.
321
+ `export const __substratSpine = () => import(${q('@substrat-run/adapter-sqlite')}).then((m) => m.SCOPE_SPINE_DDL, () => undefined);\n` +
322
+ // Where that kernel resolves, for the replay's own process to import (#2321).
323
+ `export const __substratKernelUrl = (() => { try { return import.meta.resolve(${q('@substrat-run/kernel')}); } catch { return null; } })();\n`);
324
+ }
325
+ catch (e) {
326
+ // The third silent-until-deploy failure (#1205): the entry exists and exports the right
327
+ // name, but cannot be read OUTSIDE the vertical's runtime — a worker-only import, a
328
+ // `node:*` on a path the bundler follows, an import-time side effect wanting a live host.
329
+ // Named as that, rather than as a bare esbuild/ESM stack, because the remedy is specific:
330
+ // `definePermissions(...)` returns a plain object, so the module holding it must stay
331
+ // importable as data.
332
+ throw new Error(`substrat.permissions points at "${entry}", which could not be bundled and imported as data — ` +
333
+ `the declared surface must be readable without a live host (no worker-only imports on the ` +
334
+ `path it pulls in, no import-time side effects).\n${e instanceof Error ? e.message : String(e)}`);
335
+ }
336
+ if (!mod.permissions) {
337
+ throw new Error(`${entry} exports no \`permissions\`. Export ` +
338
+ `\`const permissions = definePermissions({ modules, roles, entityGrants })\`.`);
339
+ }
340
+ let spec;
341
+ if (mod.envSpec !== undefined) {
342
+ if (!Array.isArray(mod.envSpec)) {
343
+ throw new Error(`${entry} exports \`envSpec\`, but it is not an array of env-var specs.`);
344
+ }
283
345
  try {
284
- await build({
285
- // The entry, plus the vertical's OWN kernel (#1677), imported where the vertical
286
- // resolves it: `packages: 'external'` keeps the specifier, so it loads from the
287
- // vertical's node_modules. Optional — a vertical with none still reads as data.
288
- // Both absolute: a CI job names the dir relatively (`substrat push demos/ticket0`), and
289
- // a relative path written as an import specifier is a BARE one — `packages: 'external'`
290
- // then keeps `demos/…` as a package named `demos`, which Node cannot find. `join` also
291
- // strips a leading `./`, so spelling the dir `./demos/…` would not have saved it.
292
- stdin: {
293
- contents: `export * from ${JSON.stringify(resolve(entryPath))};\n` +
294
- `export const __substratKernel = await import('@substrat-run/kernel').catch(() => null);\n` +
295
- // The spine the data-loss replay builds first (#2321), from the vertical's own
296
- // adapter-sqlite — imported only when a replay runs, since it loads a native driver.
297
- `export const __substratSpine = () => import('@substrat-run/adapter-sqlite').then((m) => m.SCOPE_SPINE_DDL, () => undefined);\n` +
298
- // Where that kernel resolves, for the replay's own process to import (#2321).
299
- `export const __substratKernelUrl = (() => { try { return import.meta.resolve('@substrat-run/kernel'); } catch { return null; } })();\n`,
300
- resolveDir: resolve(dir),
301
- sourcefile: 'substrat-surface.mjs',
302
- loader: 'js',
303
- },
304
- bundle: true,
305
- platform: 'node',
306
- format: 'esm',
307
- packages: 'external',
308
- outfile: out,
309
- logLevel: 'silent',
310
- });
311
- // @vite-ignore: this is a real filesystem path imported at runtime, never a bundler input —
312
- // the comment keeps vitest/vite from trying to resolve it through their transform pipeline.
313
- mod = (await import(/* @vite-ignore */ pathToFileURL(out).href));
346
+ spec = mod.envSpec.map((e) => envVarSpec.parse(e));
314
347
  }
315
348
  catch (e) {
316
- // The third silent-until-deploy failure (#1205): the entry exists and exports the right
317
- // name, but cannot be read OUTSIDE the vertical's runtime — a worker-only import, a
318
- // `node:*` on a path the bundler follows, an import-time side effect wanting a live host.
319
- // Named as that, rather than as a bare esbuild/ESM stack, because the remedy is specific:
320
- // `definePermissions(...)` returns a plain object, so the module holding it must stay
321
- // importable as data.
322
- throw new Error(`substrat.permissions points at "${entry}", which could not be bundled and imported as data — ` +
323
- `the declared surface must be readable without a live host (no worker-only imports on the ` +
324
- `path it pulls in, no import-time side effects).\n${e instanceof Error ? e.message : String(e)}`);
325
- }
326
- if (!mod.permissions) {
327
- throw new Error(`${entry} exports no \`permissions\`. Export ` +
328
- `\`const permissions = definePermissions({ modules, roles, entityGrants })\`.`);
349
+ throw new Error(`${entry} exports an \`envSpec\` that is not a valid env-var spec list.\n` +
350
+ `${e instanceof Error ? e.message : String(e)}`);
329
351
  }
330
- let spec;
331
- if (mod.envSpec !== undefined) {
332
- if (!Array.isArray(mod.envSpec)) {
333
- throw new Error(`${entry} exports \`envSpec\`, but it is not an array of env-var specs.`);
334
- }
335
- try {
336
- spec = mod.envSpec.map((e) => envVarSpec.parse(e));
337
- }
338
- catch (e) {
339
- throw new Error(`${entry} exports an \`envSpec\` that is not a valid env-var spec list.\n` +
340
- `${e instanceof Error ? e.message : String(e)}`);
341
- }
342
- }
343
- // #2430: a key a module declares `holder: 'system'` in a role a person can hold, an entity grant
344
- // shape or an owner grant (a module's, or this package's `substrat.ownerGrants`, which an install
345
- // grants its owner), refused before anything uploads, in `lint:permissions`' own words. The
346
- // registry build below refuses most of it too; this is the message that names the remedy.
347
- const reserved = reservedKeysOf(mod.permissions.modules);
348
- const offences = reservedKeyOffences({
349
- roles: mod.permissions.roles,
350
- grants: mod.permissions.entityGrants ?? [],
351
- personGrants: ownerGrantSets(mod.permissions.modules, ownerGrants.grants),
352
- }, reserved);
353
- if (offences.length > 0)
354
- throw new Error(reservedKeyMessage(basename(resolve(dir)), entry, offences, reserved));
355
- // #1234: the declared half of a declared-vs-observed finding — what the modules say
356
- // they emit and consume, which exists nowhere off their manifests.
357
- const declaredEvents = flattenDeclaredEvents(mod.permissions);
358
- return {
359
- registry: buildPermissionRegistry(mod.permissions),
360
- modules: mod.permissions.modules.map(({ manifest }) => ({
361
- id: manifest.id,
362
- permissions: manifest.permissions.map(({ key, description, holder }) => ({
363
- key, description, ...(holder ? { holder } : {}),
364
- })),
365
- ...(manifest.ownerGrants ? { ownerGrants: manifest.ownerGrants } : {}),
352
+ }
353
+ // #2430: a key a module declares `holder: 'system'` in a role a person can hold, an entity grant
354
+ // shape or an owner grant (a module's, or this package's `substrat.ownerGrants`, which an install
355
+ // grants its owner), refused before anything uploads, in `lint:permissions`' own words. The
356
+ // registry build below refuses most of it too; this is the message that names the remedy.
357
+ const reserved = reservedKeysOf(mod.permissions.modules);
358
+ const offences = reservedKeyOffences({
359
+ roles: mod.permissions.roles,
360
+ grants: mod.permissions.entityGrants ?? [],
361
+ personGrants: ownerGrantSets(mod.permissions.modules, ownerGrants.grants),
362
+ }, reserved);
363
+ if (offences.length > 0)
364
+ throw new Error(reservedKeyMessage(basename(resolve(dir)), entry, offences, reserved));
365
+ // #1234: the declared half of a declared-vs-observed finding — what the modules say
366
+ // they emit and consume, which exists nowhere off their manifests.
367
+ const declaredEvents = flattenDeclaredEvents(mod.permissions);
368
+ const connectors = await readDeclaredConnectors(dir, pkg.substrat?.connectors);
369
+ const registry = buildPermissionRegistry(mod.permissions);
370
+ if (connectors) {
371
+ // The standing grants join the registry, so widening them moves the permission digest the
372
+ // promote checkpoint acknowledges. Sorted like the rest of the registry, so the digest is a
373
+ // function of content. Absent when there are none: a digest must not move for a vertical
374
+ // without connectors.
375
+ registry.connectors = connectors
376
+ .map((c) => ({ provider: c.provider, grants: [...c.grants].sort() }))
377
+ .sort((a, b) => a.provider.localeCompare(b.provider));
378
+ assertConnectorsAdmissible(basename(resolve(dir)), pkg.substrat?.connectors, connectors, registry, mod.permissions);
379
+ }
380
+ return {
381
+ registry,
382
+ modules: mod.permissions.modules.map(({ manifest }) => ({
383
+ id: manifest.id,
384
+ permissions: manifest.permissions.map(({ key, description, holder }) => ({
385
+ key, description, ...(holder ? { holder } : {}),
366
386
  })),
367
- envSpec: spec,
368
- // #1232: the same import that yields the permission surface already holds every
369
- // module manifest — the schedules ride out of it with zero extra reads.
370
- schedules: flattenDeclaredSchedules(mod.permissions),
371
- freshness: flattenDeclaredFreshness(mod.permissions),
372
- declaredEvents: declaredEvents.events,
373
- declaredEventsTruncated: declaredEvents.truncated,
374
- declaresAttachments: declaresAttachmentTargets(mod.permissions.modules.map((m) => m.manifest)),
375
- migrations: flattenDeclaredMigrations(mod.permissions, typeof mod.__substratKernel?.moduleMigrations === 'function'
376
- ? mod.__substratKernel.moduleMigrations
377
- : undefined),
378
- replay: {
379
- kernel: mod.__substratKernel ?? null,
380
- kernelUrl: typeof mod.__substratKernelUrl === 'string' ? mod.__substratKernelUrl : null,
381
- modules: mod.permissions.modules,
382
- spineDdl: async () => {
383
- const ddl = await mod.__substratSpine?.();
384
- return typeof ddl === 'string' ? ddl : undefined;
385
- },
387
+ ...(manifest.ownerGrants ? { ownerGrants: manifest.ownerGrants } : {}),
388
+ })),
389
+ envSpec: spec,
390
+ // #1232: the same import that yields the permission surface already holds every
391
+ // module manifest — the schedules ride out of it with zero extra reads.
392
+ schedules: flattenDeclaredSchedules(mod.permissions),
393
+ freshness: flattenDeclaredFreshness(mod.permissions),
394
+ declaredEvents: declaredEvents.events,
395
+ declaredEventsTruncated: declaredEvents.truncated,
396
+ declaresAttachments: declaresAttachmentTargets(mod.permissions.modules.map((m) => m.manifest)),
397
+ migrations: flattenDeclaredMigrations(mod.permissions, typeof mod.__substratKernel?.moduleMigrations === 'function'
398
+ ? mod.__substratKernel.moduleMigrations
399
+ : undefined),
400
+ replay: {
401
+ kernel: mod.__substratKernel ?? null,
402
+ kernelUrl: typeof mod.__substratKernelUrl === 'string' ? mod.__substratKernelUrl : null,
403
+ modules: mod.permissions.modules,
404
+ spineDdl: async () => {
405
+ const ddl = await mod.__substratSpine?.();
406
+ return typeof ddl === 'string' ? ddl : undefined;
386
407
  },
387
- };
408
+ },
409
+ connectors,
410
+ };
411
+ }
412
+ /**
413
+ * The vertical's connectors (vertical-connectors.md §5.1): `substrat.connectors` names a module
414
+ * exporting `connectors`, a `defineConnectors(...)` value whose `declarations()` is the static half
415
+ * a push carries. Imported as data the way the permission entry is. Undefined when the package
416
+ * names no such module or its declarations are empty.
417
+ */
418
+ async function readDeclaredConnectors(dir, entry) {
419
+ if (entry === undefined)
420
+ return undefined;
421
+ if (typeof entry !== 'string' || entry.length === 0) {
422
+ throw new Error(`${basename(resolve(dir))}/package.json declares \`substrat.connectors\` as ${JSON.stringify(entry)}, ` +
423
+ `not a path. Point it at the module that exports \`connectors = defineConnectors(...)\`.`);
388
424
  }
389
- finally {
390
- rmSync(out, { force: true });
425
+ const entryPath = join(dir, entry);
426
+ if (!existsSync(entryPath))
427
+ throw new Error(`substrat.connectors points at "${entry}", which does not exist under ${dir}.`);
428
+ let mod;
429
+ try {
430
+ mod = await importBundledAsData(dir, 'connectors', `export * from ${JSON.stringify(resolve(entryPath))};\n`);
431
+ }
432
+ catch (e) {
433
+ throw new Error(`substrat.connectors points at "${entry}", which could not be bundled and imported as data — ` +
434
+ `the connectors module must be importable without a live host (no worker-only imports on the ` +
435
+ `path it pulls in, no import-time side effects).\n${e instanceof Error ? e.message : String(e)}`);
436
+ }
437
+ const declarations = mod.connectors?.declarations;
438
+ if (typeof declarations !== 'function') {
439
+ throw new Error(`${entry} exports no \`connectors\` with a \`declarations()\`. Export ` +
440
+ `\`const connectors = defineConnectors({ … })\` from @substrat-run/vertical-host/connectors.`);
441
+ }
442
+ let raw;
443
+ try {
444
+ raw = declarations.call(mod.connectors);
391
445
  }
446
+ catch (e) {
447
+ throw new Error(`${entry}: \`connectors.declarations()\` threw.\n${e instanceof Error ? e.message : String(e)}`);
448
+ }
449
+ const parsed = verticalConnectorDeclarations.safeParse(raw);
450
+ if (!parsed.success) {
451
+ const issues = parsed.error.issues.map((i) => ` - ${i.path.length ? `${i.path.join('.')}: ` : ''}${i.message}`);
452
+ throw new Error(`${entry} declares connectors a push cannot carry:\n${issues.join('\n')}`);
453
+ }
454
+ return parsed.data.length > 0 ? parsed.data : undefined;
455
+ }
456
+ /**
457
+ * vertical-connectors.md §7.1, the refusals the static half allows: a standing grant the registry
458
+ * does not declare or reserves to a system principal (`pushedConnectorProblems`, the check the
459
+ * control plane repeats), and a routed event type no module of the vertical declares it emits.
460
+ */
461
+ function assertConnectorsAdmissible(vertical, entry, connectors, registry, permissions) {
462
+ const emitted = new Set(permissions.modules.flatMap((m) => (m.manifest.events?.emits ?? []).map((e) => e.type)));
463
+ const problems = [
464
+ ...pushedConnectorProblems({ connectors, registry }),
465
+ ...connectors.flatMap((c) => c.events.filter((t) => !emitted.has(t)).map((t) => `connector ${c.provider} routes ${t}, which no module of ${vertical} declares it emits`)),
466
+ ];
467
+ if (problems.length === 0)
468
+ return;
469
+ throw new Error(`${vertical}: ${entry} declares connectors a push cannot carry:\n${problems.map((p) => ` - ${p}`).join('\n')}\n` +
470
+ `Remedy: a standing grant must be a key a module declares and does not reserve (\`holder: 'system'\`); ` +
471
+ `a routed event must be one a module's manifest lists under \`events.emits\`.`);
392
472
  }
393
473
  /** The declared permission surface alone — `deriveDeclaredSurface` for the callers that
394
474
  * want only the registry (D-41). */
@@ -527,6 +607,13 @@ export function formatPermissionSurface(surface, label) {
527
607
  lines.push(` ${l.provider}: ${l.operation} holding ${l.permission}`);
528
608
  }
529
609
  }
610
+ // A vertical-defined connector's standing grants, which the digest also covers.
611
+ if (registry.connectors?.length) {
612
+ lines.push('', 'connector standing grants:');
613
+ for (const c of registry.connectors) {
614
+ lines.push(` ${c.provider}: ${c.grants.length ? c.grants.join(', ') : '(none)'}`);
615
+ }
616
+ }
530
617
  if (surface.envSpec) {
531
618
  lines.push('', `env keys (code-declared, #1206): ${surface.envSpec.length}`);
532
619
  for (const e of surface.envSpec) {
@@ -1206,18 +1293,84 @@ export function assertAttachmentBindingFree(bindings, blobStores) {
1206
1293
  export function generatedConfigPath(dir) {
1207
1294
  return resolve(dir, '.wrangler.substrat.json');
1208
1295
  }
1296
+ /**
1297
+ * The vertical's own wrangler: the script its `bin` names, and the version that script is.
1298
+ *
1299
+ * Resolved the way Node resolves an import from the vertical (its `node_modules`, then each
1300
+ * parent's, so a workspace that hoists wrangler to its root still finds it), and run as
1301
+ * `node <bin>`. Not through `npx`, for two reasons:
1302
+ *
1303
+ * - On Windows `npx` is `npx.cmd`. Node will not spawn a batch file without a shell
1304
+ * (CVE-2024-27980), and through a shell every argument is parsed twice — by cmd.exe and
1305
+ * again by the batch file's `%*` — so a build path holding a space, `&`, `%` or `^` cannot
1306
+ * be passed safely. `push` failed there with `spawnSync npx ENOENT` before it built anything.
1307
+ * - `npx` downloads the newest wrangler when the project has none, without asking when stdin
1308
+ * is not a TTY. The bundle a deploy ships then depends on the day it was built. The
1309
+ * project's pinned wrangler is the only one this runs; a project without one is told so.
1310
+ *
1311
+ * Every node_modules directory is checked for `wrangler/package.json` on disk rather than
1312
+ * through `require.resolve('wrangler/package.json')`, so the lookup never depends on which
1313
+ * subpaths a given wrangler release lists in its `exports`.
1314
+ */
1315
+ export function resolveWrangler(dir) {
1316
+ const root = resolve(dir);
1317
+ const candidates = createRequire(join(root, 'package.json')).resolve.paths('wrangler') ?? [];
1318
+ const pkgFile = candidates.map((nm) => join(nm, 'wrangler', 'package.json')).find((f) => existsSync(f));
1319
+ if (!pkgFile) {
1320
+ throw new Error([
1321
+ `wrangler is not installed in this project (${root}).`,
1322
+ ' substrat push builds the Worker with the wrangler your project pins, and never downloads one.',
1323
+ ' Add it as a devDependency, then push again:',
1324
+ ' npm install --save-dev wrangler (or: pnpm add -D wrangler, yarn add -D wrangler)',
1325
+ ' Yarn Plug\'n\'Play installs no node_modules, which the push reads: set `nodeLinker: node-modules`',
1326
+ ' in .yarnrc.yml and run `yarn install`.',
1327
+ ].join('\n'));
1328
+ }
1329
+ const pkg = JSON.parse(readFileSync(pkgFile, 'utf8'));
1330
+ const rel = typeof pkg.bin === 'string' ? pkg.bin : pkg.bin?.wrangler;
1331
+ if (!rel)
1332
+ throw new Error(`${pkgFile} names no \`wrangler\` bin — reinstall wrangler in this project`);
1333
+ return { bin: resolve(dirname(pkgFile), rel), version: pkg.version ?? 'unknown' };
1334
+ }
1335
+ /**
1336
+ * The environment wrangler builds in: this process's, with the project's `node_modules/.bin`
1337
+ * directories (its own, then each parent's, nearest first) and Node's own directory put in
1338
+ * front of PATH.
1339
+ *
1340
+ * That is what `npx` used to give it, and the project's build command depends on it. Wrangler
1341
+ * runs `build.command` (`runtimeNeeds.build`) through a shell on the PATH it was handed, so a
1342
+ * build of `vite build` or `tsc` finds the project's own `vite` or `tsc` only when its `.bin`
1343
+ * is there. A CLI installed globally, or started from a repository root, has no such entry.
1344
+ */
1345
+ export function wranglerEnv(dir, env = process.env) {
1346
+ const bins = [];
1347
+ for (let at = resolve(dir);; at = dirname(at)) {
1348
+ bins.push(join(at, 'node_modules', '.bin'));
1349
+ if (dirname(at) === at)
1350
+ break;
1351
+ }
1352
+ // Windows names it `Path`, and environment keys are case-insensitive there. A copy is a
1353
+ // plain object, so set the key that is already present instead of adding a second one.
1354
+ const key = Object.keys(env).find((k) => k.toUpperCase() === 'PATH') ?? 'PATH';
1355
+ const path = [...bins, dirname(process.execPath), env[key]].filter(Boolean).join(delimiter);
1356
+ return { ...env, [key]: path };
1357
+ }
1209
1358
  const checkedWorkerBundles = new WeakSet();
1210
1359
  /** Run Wrangler's configured build once, then check the source graph it produced. */
1211
1360
  export async function prepareWorkerBundle(dir, resolved = resolveWranglerConfig(dir), label = 'Worker', output = 'stdout') {
1212
1361
  const { cfg, needs } = resolved;
1362
+ // Before anything is written: a project without wrangler leaves no temp dir or config behind.
1363
+ const wrangler = resolveWrangler(dir);
1213
1364
  const out = mkdtempSync(join(tmpdir(), 'substrat-build-'));
1214
1365
  const generated = needs ? generatedConfigPath(dir) : undefined;
1215
- (output === 'stderr' ? console.error : console.log)(`building ${label} …`);
1366
+ (output === 'stderr' ? console.error : console.log)(`building ${label} with wrangler ${wrangler.version} …`);
1216
1367
  try {
1217
1368
  if (generated)
1218
1369
  writeFileSync(generated, JSON.stringify(cfg, null, 2) + '\n');
1219
1370
  try {
1220
- execFileSync('npx', ['wrangler', 'deploy', '--dry-run', '--outdir', out, ...(generated ? ['--config', generated] : [])], { cwd: dir, stdio: output === 'stderr' ? ['inherit', 2, 2] : 'inherit' });
1371
+ // `node <wrangler bin>`, no shell: each argument reaches wrangler as one argv entry on
1372
+ // every OS, so `out` and `generated` may hold spaces or non-ASCII (see resolveWrangler).
1373
+ execFileSync(process.execPath, [wrangler.bin, 'deploy', '--dry-run', '--outdir', out, ...(generated ? ['--config', generated] : [])], { cwd: dir, env: wranglerEnv(dir), stdio: output === 'stderr' ? ['inherit', 2, 2] : 'inherit' });
1221
1374
  }
1222
1375
  finally {
1223
1376
  if (generated)
@@ -1234,6 +1387,7 @@ export async function prepareWorkerBundle(dir, resolved = resolveWranglerConfig(
1234
1387
  }
1235
1388
  }
1236
1389
  export async function push(opts) {
1390
+ const concept = readPublishedConcept(opts.dir);
1237
1391
  // The layer rules, before anything is built or uploaded (#955). First, because it reads
1238
1392
  // the source tree and needs nothing else — a violation is refused in a second rather than
1239
1393
  // after a wrangler build whose output was never going to be admissible. Skipped only for
@@ -1286,7 +1440,7 @@ export async function push(opts) {
1286
1440
  // below. Throws if the vertical declares no surface: absence is never a silent empty registry.
1287
1441
  // The same import reads the entry's `envSpec` export (#1206); when it exists it is the copy
1288
1442
  // that ships, and a drifted package.json duplicate refuses the push.
1289
- const { registry, modules: declaredModules, envSpec: derivedEnvSpec, schedules, freshness, declaredEvents, declaredEventsTruncated, migrations, declaresAttachments, replay, } = await deriveDeclaredSurface(opts.dir);
1443
+ const { registry, modules: declaredModules, envSpec: derivedEnvSpec, schedules, freshness, declaredEvents, declaredEventsTruncated, migrations, declaresAttachments, replay, connectors, } = await deriveDeclaredSurface(opts.dir);
1290
1444
  // #2321: the vertical's migrations, replayed against a populated in-memory scope through its own
1291
1445
  // kernel's data-loss fence — before anything is uploaded, so a migration that would close every
1292
1446
  // populated scope at promote is refused here instead. Throws on a refusal.
@@ -1401,6 +1555,7 @@ export async function push(opts) {
1401
1555
  // The emitted entity model (#1214) — metadata like envSpec/surfaces, not in any digest:
1402
1556
  // it describes what the migrations built, it does not build anything.
1403
1557
  ...(model ? { model } : {}),
1558
+ ...(concept !== undefined ? { concept } : {}),
1404
1559
  // #1321: the declared output surface travels with the version — `openapi.json`
1405
1560
  // is built inside the vertical and never sent, so the platform has no other way
1406
1561
  // to know which declared fields anything is even capable of returning.
@@ -1431,6 +1586,10 @@ export async function push(opts) {
1431
1586
  // `[]` when undeclared, because absence means "pre-#1706 push" (unenforced) and a
1432
1587
  // new-CLI push must not read as that. Enforcement input, versioned with the code.
1433
1588
  calls: opts.calls ?? [],
1589
+ // The vertical's connector declarations (vertical-connectors.md §5.1), absent when none, so a
1590
+ // vertical without connectors pushes the manifest it did before. Their standing grants are
1591
+ // also in `registry.connectors`, which the permission digest covers.
1592
+ ...(connectors ? { connectors } : {}),
1434
1593
  // The declared permission surface travels with the bundle (D-39/D-41): keys+descriptions,
1435
1594
  // role templates, entity-grant shapes. Required — its content hash is digests.permission.
1436
1595
  registry,