@objectstack/runtime 8.0.1 → 9.0.1

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/dist/index.d.ts CHANGED
@@ -4,13 +4,12 @@ export { ObjectKernel } from '@objectstack/core';
4
4
  import { ClusterServicePluginOptions } from '@objectstack/service-cluster';
5
5
  import { ClusterCapabilityConfigInput, ExecutionContext } from '@objectstack/spec/kernel';
6
6
  import { z } from 'zod';
7
- import * as Contracts from '@objectstack/spec/contracts';
8
- import { ISeedLoaderService, IDataEngine, IMetadataService } from '@objectstack/spec/contracts';
9
- import { SeedLoaderRequest, SeedLoaderResult, ObjectDependencyGraph, Seed, SeedLoaderConfigInput, ExpressionBody, ScriptBody, HookBody, Hook } from '@objectstack/spec/data';
7
+ export { SeedLoaderService } from '@objectstack/objectql';
10
8
  import { SchemaDiffEntry } from '@objectstack/spec/shared';
11
9
  import { MetricsRegistry, ErrorReporter } from '@objectstack/observability';
12
10
  export { CapturedError, ErrorReporter, InMemoryErrorReporter, InMemoryMetricsRegistry, MetricSample, MetricsRegistry, NoopErrorReporter, NoopMetricsRegistry, OBSERVABILITY_ERRORS_SERVICE, OBSERVABILITY_METRICS_SERVICE, RUNTIME_METRICS } from '@objectstack/observability';
13
11
  import { MiddlewareConfig, MiddlewareType } from '@objectstack/spec/system';
12
+ import { ExpressionBody, ScriptBody, HookBody, Hook } from '@objectstack/spec/data';
14
13
  export { RestApiPluginConfig, RestServer, RouteEntry, RouteGroupBuilder, RouteManager, createRestApiPlugin } from '@objectstack/rest';
15
14
  export { _resetEnvDeprecationWarnings, readEnvWithDeprecation } from '@objectstack/types';
16
15
 
@@ -301,58 +300,6 @@ declare function collectBundleActions(bundle: any): Array<{
301
300
  */
302
301
  declare function collectBundleFunctions(bundle: any): Record<string, (ctx: any) => any>;
303
302
 
304
- interface Logger {
305
- info(message: string, meta?: Record<string, any>): void;
306
- warn(message: string, meta?: Record<string, any>): void;
307
- error(message: string, error?: Error, meta?: Record<string, any>): void;
308
- debug(message: string, meta?: Record<string, any>): void;
309
- }
310
- /**
311
- * SeedLoaderService — Runtime implementation of ISeedLoaderService
312
- *
313
- * Provides metadata-driven seed data loading with:
314
- * - Automatic lookup/master_detail reference resolution via externalId
315
- * - Topological dependency ordering (parents before children)
316
- * - Multi-pass loading for circular references
317
- * - Dry-run validation mode
318
- * - Upsert support honoring SeedSchema mode
319
- * - Actionable error reporting
320
- */
321
- declare class SeedLoaderService implements ISeedLoaderService {
322
- private engine;
323
- private metadata;
324
- private logger;
325
- constructor(engine: IDataEngine, metadata: IMetadataService, logger: Logger);
326
- load(request: SeedLoaderRequest): Promise<SeedLoaderResult>;
327
- buildDependencyGraph(objectNames: string[]): Promise<ObjectDependencyGraph>;
328
- validate(datasets: Seed[], config?: SeedLoaderConfigInput): Promise<SeedLoaderResult>;
329
- private loadDataset;
330
- private resolveFromDatabase;
331
- private resolveDeferredUpdates;
332
- /**
333
- * Seed writes always run as a privileged system context. This bypasses
334
- * RBAC checks (so seeds can target system tables like `sys_*`) and
335
- * disables the SecurityPlugin's auto-injection of `organization_id` /
336
- * `owner_id` — seeds either declare those fields explicitly per
337
- * record, or are intentionally cross-tenant / global.
338
- */
339
- private static readonly SEED_OPTIONS;
340
- private writeRecord;
341
- /**
342
- * Kahn's algorithm for topological sort with cycle detection.
343
- */
344
- private topologicalSort;
345
- private findCycles;
346
- private filterByEnv;
347
- private orderDatasets;
348
- private buildReferenceMap;
349
- private loadExistingRecords;
350
- private looksLikeInternalId;
351
- private extractId;
352
- private buildEmptyResult;
353
- private buildResult;
354
- }
355
-
356
303
  /**
357
304
  * Payload of the `external.schema.drift` event emitted on the kernel bus by the
358
305
  * background drift checker (ADR-0015 §5.2). Consumed by `audit` / `notification`
@@ -891,57 +838,6 @@ declare class HttpServer implements IHttpServer {
891
838
  getMiddlewares(): Middleware[];
892
839
  }
893
840
 
894
- /**
895
- * Per-project driver registry contract.
896
- *
897
- * Resolves a project (by hostname or ID) and produces an instantiated
898
- * `IDataDriver` bound to that project's physical database. Concrete
899
- * implementations sit on top of either:
900
- * - the ObjectStack Cloud HTTP API (see {@link ArtifactEnvironmentRegistry})
901
- * - a local file artifact (see {@link FileArtifactApiClient} +
902
- * {@link ArtifactEnvironmentRegistry})
903
- *
904
- * The contract lives in `@objectstack/runtime` so the runtime can
905
- * express "fetch artifact + boot per-project kernel" without taking a
906
- * dependency on the cloud control plane.
907
- */
908
-
909
- type IDataDriver = Contracts.IDataDriver;
910
- /**
911
- * Multi-tenant kernel router contract.
912
- *
913
- * The HTTP dispatcher uses this optional seam to resolve a per-environment
914
- * kernel when serving a multi-tenant runtime. The framework only depends on
915
- * the *interface* — the concrete LRU/TTL implementation (and everything else
916
- * multi-tenant: hostname resolution, artifact fetching, per-env kernel
917
- * construction) lives in the cloud distribution
918
- * (`@objectstack/objectos-runtime`), not here.
919
- */
920
- interface KernelManager {
921
- /** Resolve (building + caching on first use) the kernel for an environment. */
922
- getOrCreate(environmentId: string): Promise<ObjectKernel>;
923
- }
924
- interface EnvironmentDriverRegistry {
925
- /** Resolve a project by hostname. Returns `null` when unknown. */
926
- resolveByHostname(host: string): Promise<{
927
- environmentId: string;
928
- driver: IDataDriver;
929
- } | null>;
930
- /** Resolve a project's driver by ID. Returns `null` when unknown. */
931
- resolveById(environmentId: string): Promise<IDataDriver | null>;
932
- /**
933
- * Look up the cached project row + driver by ID without triggering a
934
- * remote/file fetch. Returns the full cached entry when fresh.
935
- */
936
- peekById(environmentId: string): {
937
- environmentId: string;
938
- driver: IDataDriver;
939
- project: any;
940
- } | null;
941
- /** Drop cached entries for the given project. */
942
- invalidate(environmentId: string): void;
943
- }
944
-
945
841
  /** Minimal local interface — full EnvironmentScopeManager was removed in Phase R. */
946
842
  interface EnvironmentScopeManager {
947
843
  touch(environmentId: string): void;
@@ -951,6 +847,21 @@ interface HttpProtocolContext {
951
847
  response?: any;
952
848
  environmentId?: string;
953
849
  dataDriver?: any;
850
+ /**
851
+ * Dispatcher-provided hint for the host's {@link KernelResolver}: the
852
+ * cleaned route path (API prefix stripped). Lets the resolver apply its
853
+ * own path policy (e.g. skip env resolution for control-plane routes)
854
+ * without re-deriving the dispatcher's URL handling.
855
+ */
856
+ routePath?: string;
857
+ /**
858
+ * Dispatcher-provided hint for the host's {@link KernelResolver}: the
859
+ * UNVALIDATED environment-id candidate parsed from the scoped URL form
860
+ * (`/environments/:id/...`) or the router's `params.environmentId`.
861
+ * URL parsing is the dispatcher's routing convention, so it stays here;
862
+ * validation (registry lookup) is the resolver's job.
863
+ */
864
+ urlEnvironmentId?: string;
954
865
  /**
955
866
  * Identity envelope resolved by `resolveExecutionContext` and threaded
956
867
  * into every ObjectQL call so the SecurityPlugin middleware can apply
@@ -967,6 +878,31 @@ interface HttpDispatcherResult {
967
878
  };
968
879
  result?: any;
969
880
  }
881
+ /**
882
+ * ADR-0006 generic kernel-resolution seam.
883
+ *
884
+ * A host (e.g. ObjectStack Cloud) injects a resolver to own per-request
885
+ * kernel selection. The framework ships NO multi-tenant implementation — all
886
+ * hostname→env strategy, the per-env kernel cache, and the control plane live
887
+ * in the host distribution (`@objectstack/objectos-runtime`). When no resolver
888
+ * is injected the dispatcher serves every request from its single
889
+ * `defaultKernel` (single-environment mode).
890
+ *
891
+ * Returning `undefined` routes the request to `defaultKernel` — resolvers use
892
+ * this for control-plane / unscoped / single-environment requests.
893
+ *
894
+ * As of ADR-0006 Phase 5 the resolver owns the ENTIRE per-request environment
895
+ * resolution, not just kernel selection: the dispatcher no longer performs any
896
+ * hostname / header / session → environment lookup of its own. The dispatcher
897
+ * provides parsing hints on the context (`routePath`, `urlEnvironmentId`) and
898
+ * expects the resolver to SET `context.environmentId` (and optionally
899
+ * `context.dataDriver`) for scoped requests — downstream dispatcher stages
900
+ * (project-membership enforcement, scope TTL touch, scoped service resolution)
901
+ * key off `context.environmentId`.
902
+ */
903
+ interface KernelResolver {
904
+ resolveKernel(context: HttpProtocolContext, defaultKernel: ObjectKernel): Promise<ObjectKernel | undefined> | ObjectKernel | undefined;
905
+ }
970
906
  /**
971
907
  * Optional configuration passed to the dispatcher constructor. Supports the
972
908
  * legacy `enforceProjectMembership` toggle plus the new multi-kernel
@@ -975,13 +911,16 @@ interface HttpDispatcherResult {
975
911
  interface HttpDispatcherOptions {
976
912
  enforceProjectMembership?: boolean;
977
913
  /**
978
- * Optional {@link KernelManager}. When present, the dispatcher resolves
979
- * `context.environmentId` first and then routes the request against the
980
- * project's dedicated kernel via `kernelManager.getOrCreate(environmentId)`.
981
- * Requests that fail to resolve a environmentId fall through to the
982
- * constructor-supplied kernel (self-hosted / legacy behavior).
914
+ * Optional generic kernel-resolution seam (ADR-0006). The SOLE
915
+ * multi-tenant hook: the host's resolver owns env resolution + kernel
916
+ * selection per request (see {@link KernelResolver}). Falls back to
917
+ * `resolveService('kernel-resolver')`. Hosts that register none run
918
+ * single-environment on `defaultKernel`. (The legacy `kernelManager`
919
+ * option and the dispatcher's built-in hostname/header/session
920
+ * resolution were removed in ADR-0006 Phase 5 — that strategy lives in
921
+ * the cloud distribution's resolver now.)
983
922
  */
984
- kernelManager?: KernelManager;
923
+ kernelResolver?: KernelResolver;
985
924
  /**
986
925
  * Optional {@link EnvironmentScopeManager}. When present, `touch(environmentId)` is
987
926
  * called on every scoped request so idle projects are evicted after TTL.
@@ -999,9 +938,8 @@ interface HttpDispatcherOptions {
999
938
  declare class HttpDispatcher {
1000
939
  private kernel;
1001
940
  private defaultKernel;
1002
- private envRegistry?;
1003
941
  private defaultProject?;
1004
- private kernelManager?;
942
+ private kernelResolver?;
1005
943
  private scopeManager?;
1006
944
  /**
1007
945
  * When `true`, scoped data-plane routes enforce a
@@ -1023,7 +961,13 @@ declare class HttpDispatcher {
1023
961
  private static readonly SYSTEM_ENVIRONMENT_ID;
1024
962
  /** Well-known platform org id — members bypass project membership. */
1025
963
  private static readonly PLATFORM_ORG_ID;
1026
- constructor(kernel: ObjectKernel, envRegistry?: any, options?: HttpDispatcherOptions);
964
+ /**
965
+ * @param _envRegistryIgnored — RETIRED (ADR-0006 Phase 5). Environment
966
+ * resolution moved behind the host's {@link KernelResolver}; the
967
+ * positional parameter is kept so existing 3-arg callers keep compiling,
968
+ * but its value is ignored.
969
+ */
970
+ constructor(kernel: ObjectKernel, _envRegistryIgnored?: unknown, options?: HttpDispatcherOptions);
1027
971
  private resolveDefaultProject;
1028
972
  private success;
1029
973
  private error;
@@ -1107,24 +1051,17 @@ declare class HttpDispatcher {
1107
1051
  */
1108
1052
  private extractEnvironmentIdFromPath;
1109
1053
  /**
1110
- * Resolve environment context for incoming request.
1111
- *
1112
- * Precedence:
1113
- * 0. URL path matches `/environments/:environmentId/...` OR request.params.environmentId set by router
1114
- * → envRegistry.resolveById(id)
1115
- * 1. request.headers.host → envRegistry.resolveByHostname(host)
1116
- * 2. request.headers['x-environment-id'] → envRegistry.resolveById(id)
1117
- * 3. session.activeEnvironmentId → envRegistry.resolveById(id)
1118
- * 4. session.activeOrganizationId → find default project → envRegistry.resolveById(id)
1119
- * 5. single-environment default (registered by `createSingleEnvironmentPlugin`)
1120
- * → envRegistry.resolveById(defaultProject.environmentId). Lets bare
1121
- * `/api/v1/data/...` URLs resolve to the lone project in
1122
- * `cloudUrl: 'local'` deployments.
1054
+ * Attach the dispatcher's parsing hints for the host's
1055
+ * {@link KernelResolver} (ADR-0006 Phase 5).
1123
1056
  *
1124
- * Skip for paths: /auth, /cloud, /health, /discovery (NOT /meta when scoped,
1125
- * so project-scoped meta routes can resolve their project).
1057
+ * Environment RESOLUTION (hostname / x-environment-id / session /
1058
+ * org-default / single-env-default environment + driver) is owned by
1059
+ * the host's resolver — the dispatcher no longer touches an environment
1060
+ * registry. What stays here is pure URL parsing (the dispatcher's own
1061
+ * routing convention): the scoped-path environment-id candidate and the
1062
+ * cleaned route path, both UNVALIDATED.
1126
1063
  */
1127
- private resolveEnvironmentContext;
1064
+ private prepareResolverHints;
1128
1065
  /**
1129
1066
  * Check whether the authenticated user is a member of
1130
1067
  * `context.environmentId`. Runs after {@link resolveEnvironmentContext}
@@ -1763,274 +1700,6 @@ declare function readArtifactSource(pathOrUrl: string, opts?: {
1763
1700
  declare function loadArtifactBundle(absArtifactPath: string, opts?: LoadArtifactBundleOptions): Promise<any | null>;
1764
1701
  declare function mergeRuntimeModule(bundle: any, artifactAbsPath: string, tag?: string): Promise<void>;
1765
1702
 
1766
- /**
1767
- * MarketplaceProxyPlugin
1768
- *
1769
- * Forwards `GET /api/v1/marketplace/*` from a tenant ObjectOS runtime to
1770
- * the configured ObjectStack Cloud control-plane URL. The cloud endpoint
1771
- * is unauthenticated and only exposes packages whose owner has opted in
1772
- * to the public catalog (`sys_package.marketplace_listed = true`) — so the
1773
- * proxy passes through without any credentials.
1774
- *
1775
- * Why proxy instead of direct browser → cloud:
1776
- * - The Console SPA stays on the tenant origin, so no CORS configuration
1777
- * is required on the cloud side.
1778
- * - Local-dev `os serve` works regardless of whether the developer's
1779
- * browser has cookies for cloud.objectos.ai.
1780
- * - Adds a single, easily auditable network seam between tenant and
1781
- * control plane.
1782
- *
1783
- * Install is NOT proxied here. Installing a package mutates control-plane
1784
- * state and requires a cloud session + active organization context — the
1785
- * Console SPA performs install by opening the cloud's install dialog in a
1786
- * new tab so the user authenticates against cloud directly. A future
1787
- * iteration may introduce a delegated install token; until then, browse
1788
- * here and install on cloud.
1789
- */
1790
-
1791
- interface MarketplaceProxyPluginConfig {
1792
- /**
1793
- * Control-plane base URL (e.g. https://cloud.objectos.ai). When the
1794
- * caller passes nothing AND the runtime has no OS_CLOUD_URL set, the
1795
- * plugin falls back to the public ObjectStack-operated cloud so that
1796
- * `objectstack dev` can browse the marketplace out of the box. Set
1797
- * OS_CLOUD_URL=off (or `local`) to opt out — the plugin then mounts
1798
- * a stub that responds 503 and the SPA renders an empty-state
1799
- * explaining marketplace is unavailable in this runtime.
1800
- */
1801
- controlPlaneUrl?: string;
1802
- /**
1803
- * Disable the in-memory response cache (testing / debugging).
1804
- * Defaults to the value of `OS_MARKETPLACE_CACHE` (anything in
1805
- * {"off","false","0","no"} disables).
1806
- */
1807
- cacheDisabled?: boolean;
1808
- /**
1809
- * Override the LRU upper bound. Defaults to 200 entries.
1810
- */
1811
- cacheMaxEntries?: number;
1812
- /**
1813
- * Public R2 base URL for marketplace snapshots. When set, GETs for
1814
- * snapshot-backed paths (`/packages`, `/packages/:id`,
1815
- * `/packages/:id/versions/:vid/manifest`) are fetched directly from
1816
- * R2 (CF edge) — bypassing the cloud control plane entirely.
1817
- * Defaults to the value of OS_MARKETPLACE_PUBLIC_BASE_URL. Empty
1818
- * string disables the public fast-path (legacy cloud-proxy only).
1819
- */
1820
- publicMarketplaceBaseUrl?: string;
1821
- }
1822
- declare class MarketplaceProxyPlugin implements Plugin {
1823
- readonly name = "com.objectstack.runtime.marketplace-proxy";
1824
- readonly version = "1.1.0";
1825
- private readonly cloudUrl;
1826
- private readonly publicBaseUrl;
1827
- private readonly cache;
1828
- constructor(config?: MarketplaceProxyPluginConfig);
1829
- init: (_ctx: PluginContext) => Promise<void>;
1830
- start: (ctx: PluginContext) => Promise<void>;
1831
- }
1832
-
1833
- interface MarketplaceInstallLocalPluginConfig {
1834
- /** Cloud control-plane base URL. When unset, falls back to OS_CLOUD_URL
1835
- * and then to the public ObjectStack cloud so a fresh `objectstack dev`
1836
- * can install from the marketplace without configuration. Set
1837
- * OS_CLOUD_URL=off to disable (the install endpoint then returns 503). */
1838
- controlPlaneUrl?: string;
1839
- /** Override the on-disk cache directory. Defaults to
1840
- * `<cwd>/.objectstack/installed-packages`. */
1841
- storageDir?: string;
1842
- }
1843
- declare class MarketplaceInstallLocalPlugin implements Plugin {
1844
- readonly name = "com.objectstack.runtime.marketplace-install-local";
1845
- readonly version = "1.0.0";
1846
- private readonly cloudUrl;
1847
- private readonly storageDir;
1848
- constructor(config?: MarketplaceInstallLocalPluginConfig);
1849
- init: (_ctx: PluginContext) => Promise<void>;
1850
- start: (ctx: PluginContext) => Promise<void>;
1851
- /**
1852
- * Re-register every cached manifest with the kernel's manifest service.
1853
- * Safe to call on a kernel that already has the same manifest_id (the
1854
- * underlying ObjectQL registry overwrites by id, but we still warn so
1855
- * a developer can spot the dev-time clash between their config.ts and
1856
- * a marketplace package).
1857
- */
1858
- private rehydrate;
1859
- private handleInstall;
1860
- private handleList;
1861
- private handleUninstall;
1862
- /**
1863
- * Detect whether `manifestId` is already known to the kernel and classify
1864
- * the source so we can refuse vs upgrade gracefully.
1865
- *
1866
- * 'none' — fresh install
1867
- * 'marketplace' — previously installed by this plugin (allow upgrade)
1868
- * 'user-code' — defined by AppPlugin from objectstack.config.ts
1869
- * (refuse to avoid silently overwriting authored code)
1870
- */
1871
- private findConflict;
1872
- /**
1873
- * Pull a userId out of the request's better-auth session, if any.
1874
- * Returns null when there is no signed-in user. v1 does not check
1875
- * admin role — UI gating + the auth requirement is sufficient for
1876
- * dev / single-tenant runtimes. Stricter checks can be layered on
1877
- * via a middleware in cloud-hosted multi-tenant deployments.
1878
- */
1879
- /**
1880
- * POST /api/v1/marketplace/install-local/:manifestId/reseed-sample-data
1881
- *
1882
- * Re-runs SeedLoaderService against the cached manifest's `data` arrays.
1883
- * Idempotent (upsert by id). Useful when:
1884
- * • The user installed an app and skipped sample data
1885
- * • A purge was undone
1886
- * • The user wants a clean baseline back after editing demo rows
1887
- *
1888
- * Multi-tenant: requires an active organization on the session (same
1889
- * rule as install seed path).
1890
- */
1891
- private handleReseed;
1892
- /**
1893
- * POST /api/v1/marketplace/install-local/:manifestId/purge-sample-data
1894
- *
1895
- * Deletes every record whose id is declared in the cached manifest's
1896
- * seed datasets. Uses the `driver` service directly to bypass ACL /
1897
- * lifecycle hooks (same pattern as cloud purge). User-created records
1898
- * are never touched — only ids declared in the package's bundled
1899
- * datasets are removed. Already-deleted rows count as `skipped`.
1900
- */
1901
- private handlePurge;
1902
- /**
1903
- * Replicate the start-time side-effects that AppPlugin runs for
1904
- * statically-declared apps but the `manifest` service does NOT:
1905
- *
1906
- * 1. Load `manifest.translations` (array of `Record<locale, data>`)
1907
- * into the i18n service — auto-creating an in-memory fallback if
1908
- * none is registered, matching AppPlugin's behaviour.
1909
- *
1910
- * 2. Merge `manifest.data` (an array of seed datasets) into the
1911
- * kernel's `seed-datasets` service so SecurityPlugin's per-org
1912
- * replay middleware picks them up on every future
1913
- * sys_organization insert.
1914
- *
1915
- * 3. When `seedNow=true`, also run the seed immediately so the user
1916
- * sees demo data without having to create a new org:
1917
- * • single-tenant: run SeedLoaderService inline (mirrors
1918
- * AppPlugin single-tenant branch)
1919
- * • multi-tenant: invoke `seed-replayer` for the caller's
1920
- * active org (resolved from the request session)
1921
- *
1922
- * Errors are logged but never thrown — install succeeds even if
1923
- * post-register side-effects partially fail (the manifest itself is
1924
- * already registered + cached). Returns a small summary for the
1925
- * response envelope.
1926
- */
1927
- private applySideEffects;
1928
- /**
1929
- * Best-effort active-org resolution. Reads the better-auth session
1930
- * (same path as requireAuthenticatedUser) and returns
1931
- * `session.activeOrganizationId`, falling back to the user's first
1932
- * org membership.
1933
- */
1934
- private resolveActiveOrgId;
1935
- private requireAuthenticatedUser;
1936
- private readAll;
1937
- }
1938
-
1939
- /**
1940
- * RuntimeConfigPlugin
1941
- *
1942
- * Serves `GET /api/v1/runtime/config` (and the legacy alias
1943
- * `GET /api/v1/studio/runtime-config`) from a tenant ObjectOS runtime so
1944
- * the Console / Studio SPA can learn the upstream cloud URL and capability
1945
- * flags **at boot time**, instead of sniffing `window.location.hostname`
1946
- * or reading Vite-time env vars.
1947
- *
1948
- * Response shape (mirrors cloud's `createStudioRuntimeConfigPlugin`):
1949
- *
1950
- * {
1951
- * cloudUrl: string, // base URL of the upstream cloud
1952
- * singleEnvironment: false, // multi-tenant runtime
1953
- * features: {
1954
- * installLocal: boolean, // false here — install-local is owned
1955
- * // by CLI `serve` (single-tenant), not
1956
- * // by createObjectOSStack
1957
- * marketplace: boolean, // true — MarketplaceProxyPlugin mounts
1958
- * // /api/v1/marketplace/*
1959
- * }
1960
- * }
1961
- *
1962
- * Registers its routes on the Hono raw app, parallel to MarketplaceProxy /
1963
- * AuthProxy / MarketplaceInstallLocal plugins.
1964
- */
1965
-
1966
- interface RuntimeConfigPluginConfig {
1967
- /**
1968
- * Upstream cloud base URL. Falls back to `resolveCloudUrl()` (reads
1969
- * `OS_CLOUD_URL` / built-in default) when omitted. Pass an explicit
1970
- * empty string to declare "this runtime IS the cloud" (same-origin
1971
- * for marketplace + install).
1972
- */
1973
- controlPlaneUrl?: string;
1974
- /** Override the `features.installLocal` flag. Default: false. */
1975
- installLocal?: boolean;
1976
- /**
1977
- * Override the `features.aiStudio` flag — whether the SPA should surface
1978
- * AI-driven metadata authoring ("online development") affordances. Default:
1979
- * true (the actual authoring capability is still gated server-side by the
1980
- * presence of the `metadata_assistant` agent / @objectstack/service-ai-studio
1981
- * package; set false to force-hide the authoring UI for a tier/deployment).
1982
- */
1983
- aiStudio?: boolean;
1984
- /**
1985
- * Report this runtime as a single-environment deployment (CLI
1986
- * `objectstack dev` / `os serve`). Defaults to `false` for
1987
- * multi-tenant ObjectOS.
1988
- */
1989
- singleEnvironment?: boolean;
1990
- /**
1991
- * Product name shown in browser title, splash screen, and other
1992
- * client chrome. Operators can override per-deployment (white-label,
1993
- * regional rebrands). Falls back to `OS_PRODUCT_NAME` env var, then
1994
- * to the default `'ObjectOS'`.
1995
- */
1996
- productName?: string;
1997
- /** Short product name (PWA shortName, compact spots). Defaults to productName. */
1998
- productShortName?: string;
1999
- }
2000
- declare class RuntimeConfigPlugin implements Plugin {
2001
- readonly name = "com.objectstack.runtime.runtime-config";
2002
- readonly version = "1.0.0";
2003
- private readonly cloudUrl;
2004
- private readonly installLocal;
2005
- private readonly aiStudio;
2006
- private readonly singleEnvironment;
2007
- private readonly productName;
2008
- private readonly productShortName;
2009
- constructor(config?: RuntimeConfigPluginConfig);
2010
- init: (_ctx: PluginContext) => Promise<void>;
2011
- start: (ctx: PluginContext) => Promise<void>;
2012
- destroy: () => Promise<void>;
2013
- }
2014
-
2015
- /**
2016
- * Shared marketplace / cloud control-plane defaults.
2017
- *
2018
- * Centralised so every plugin + the CLI auto-inject path agree on
2019
- * "what cloud URL do we mean when the user didn't set OS_CLOUD_URL?".
2020
- * Until we have a competing public hosted cloud, this points at the
2021
- * ObjectStack-operated control plane so a vanilla `objectstack dev` can
2022
- * browse the marketplace out of the box.
2023
- */
2024
- declare const DEFAULT_CLOUD_URL = "https://cloud.objectos.ai";
2025
- /**
2026
- * Resolve the effective control-plane URL from an explicit constructor
2027
- * value, the OS_CLOUD_URL env var, or the default. Returns an empty
2028
- * string when the caller explicitly disabled cloud with
2029
- * `OS_CLOUD_URL=off` / `local` — callers should treat that as
2030
- * "marketplace unavailable on this runtime".
2031
- */
2032
- declare function resolveCloudUrl(explicit?: string | null): string;
2033
-
2034
1703
  /**
2035
1704
  * # Hook & Action Body Sandbox
2036
1705
  *
@@ -2261,4 +1930,4 @@ declare function actionBodyRunnerFactory(runner: ScriptRunner, opts: FactoryOpti
2261
1930
  timeoutMs?: number;
2262
1931
  }) => ((actionCtx: any) => Promise<unknown>) | undefined;
2263
1932
 
2264
- export { AppPlugin, DEFAULT_CLOUD_URL, DEFAULT_RATE_LIMITS, type DefaultHostConfigOptions, type DefaultHostConfigResult, type DispatcherPluginConfig, DriverPlugin, type EnvironmentDriverRegistry, type ExternalSchemaDriftEvent, ExternalValidationPlugin, HttpDispatcher, type HttpDispatcherResult, type HttpProtocolContext, HttpServer, type KernelManager, type LoadArtifactBundleOptions, MarketplaceInstallLocalPlugin, type MarketplaceInstallLocalPluginConfig, MarketplaceProxyPlugin, type MarketplaceProxyPluginConfig, MiddlewareManager, ObservabilityServicePlugin, type ObservabilityServicePluginOptions, QuickJSScriptRunner, type QuickJSScriptRunnerOptions, type RateLimitBucketConfig, type RateLimitDecision, type RateLimitDefaults, type RateLimitStore, RateLimiter, Runtime, type RuntimeConfig, RuntimeConfigPlugin, type RuntimeConfigPluginConfig, SYSTEM_ENVIRONMENT_ID, SandboxError, type ScriptContext, type ScriptOrigin, type ScriptResult, type ScriptRunOptions, type ScriptRunner, type SecurityHeadersOptions, SeedLoaderService, type StandaloneStackConfig, type StandaloneStackResult, type SystemEnvironmentPluginConfig, type TraceContext, UnimplementedScriptRunner, actionBodyRunnerFactory, buildSecurityHeaders, collectBundleActions, collectBundleFunctions, collectBundleHooks, createDefaultHostConfig, createDispatcherPlugin, createExternalValidationPlugin, createStandaloneStack, createSystemEnvironmentPlugin, extractRequestId, formatTraceparent, generateRequestId, hookBodyRunnerFactory, isHttpUrl, loadArtifactBundle, mergeRuntimeModule, parseTraceparent, readArtifactSource, resolveCloudUrl, resolveDefaultArtifactPath, resolveErrorReporter, resolveMetrics, resolveObjectStackHome, resolveRequestId };
1933
+ export { AppPlugin, DEFAULT_RATE_LIMITS, type DefaultHostConfigOptions, type DefaultHostConfigResult, type DispatcherPluginConfig, DriverPlugin, type ExternalSchemaDriftEvent, ExternalValidationPlugin, HttpDispatcher, type HttpDispatcherResult, type HttpProtocolContext, HttpServer, type KernelResolver, type LoadArtifactBundleOptions, MiddlewareManager, ObservabilityServicePlugin, type ObservabilityServicePluginOptions, QuickJSScriptRunner, type QuickJSScriptRunnerOptions, type RateLimitBucketConfig, type RateLimitDecision, type RateLimitDefaults, type RateLimitStore, RateLimiter, Runtime, type RuntimeConfig, SYSTEM_ENVIRONMENT_ID, SandboxError, type ScriptContext, type ScriptOrigin, type ScriptResult, type ScriptRunOptions, type ScriptRunner, type SecurityHeadersOptions, type StandaloneStackConfig, type StandaloneStackResult, type SystemEnvironmentPluginConfig, type TraceContext, UnimplementedScriptRunner, actionBodyRunnerFactory, buildSecurityHeaders, collectBundleActions, collectBundleFunctions, collectBundleHooks, createDefaultHostConfig, createDispatcherPlugin, createExternalValidationPlugin, createStandaloneStack, createSystemEnvironmentPlugin, extractRequestId, formatTraceparent, generateRequestId, hookBodyRunnerFactory, isHttpUrl, loadArtifactBundle, mergeRuntimeModule, parseTraceparent, readArtifactSource, resolveDefaultArtifactPath, resolveErrorReporter, resolveMetrics, resolveObjectStackHome, resolveRequestId };