@objectstack/runtime 7.8.0 → 7.9.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.
package/dist/index.d.cts CHANGED
@@ -2027,6 +2027,15 @@ interface ObjectOSStackConfig {
2027
2027
  * (ADR §5.2 — "framework exposes seams; cloud supplies metadata + policy").
2028
2028
  */
2029
2029
  extraPlugins?: Plugin[];
2030
+ /**
2031
+ * Capability tokens force-mounted on EVERY per-environment kernel, in
2032
+ * addition to whatever the app artifact declares in `requires`. Merged and
2033
+ * de-duped with `bundle.requires` before the capability loader runs. This
2034
+ * is the host seam for a cloud operator to make a capability ubiquitous
2035
+ * across all tenants without editing each app — e.g. `['ai','aiStudio']`
2036
+ * so every cloud environment supports AI-driven online development.
2037
+ */
2038
+ defaultRequires?: string[];
2030
2039
  }
2031
2040
  interface ObjectOSStackResult {
2032
2041
  plugins: any[];
@@ -2248,6 +2257,14 @@ interface RuntimeConfigPluginConfig {
2248
2257
  controlPlaneUrl?: string;
2249
2258
  /** Override the `features.installLocal` flag. Default: false. */
2250
2259
  installLocal?: boolean;
2260
+ /**
2261
+ * Override the `features.aiStudio` flag — whether the SPA should surface
2262
+ * AI-driven metadata authoring ("online development") affordances. Default:
2263
+ * true (the actual authoring capability is still gated server-side by the
2264
+ * presence of the `metadata_assistant` agent / @objectstack/service-ai-studio
2265
+ * package; set false to force-hide the authoring UI for a tier/deployment).
2266
+ */
2267
+ aiStudio?: boolean;
2251
2268
  /**
2252
2269
  * Report this runtime as a single-environment deployment (CLI
2253
2270
  * `objectstack dev` / `os serve`). Defaults to `false` for
@@ -2269,6 +2286,7 @@ declare class RuntimeConfigPlugin implements Plugin {
2269
2286
  readonly version = "1.0.0";
2270
2287
  private readonly cloudUrl;
2271
2288
  private readonly installLocal;
2289
+ private readonly aiStudio;
2272
2290
  private readonly singleEnvironment;
2273
2291
  private readonly productName;
2274
2292
  private readonly productShortName;
@@ -2400,6 +2418,12 @@ interface ArtifactKernelFactoryConfig {
2400
2418
  * `process.env.OS_AUTH_SECRET` / `AUTH_SECRET` at construction time.
2401
2419
  */
2402
2420
  authBaseSecret?: string;
2421
+ /**
2422
+ * Capability tokens force-mounted on every per-environment kernel, merged
2423
+ * (and de-duped by the loader) with the artifact's own `requires`. Lets a
2424
+ * host make a capability ubiquitous across tenants — e.g. `['ai','aiStudio']`.
2425
+ */
2426
+ defaultRequires?: string[];
2403
2427
  }
2404
2428
  declare class ArtifactKernelFactory implements EnvironmentKernelFactory {
2405
2429
  private readonly client;
@@ -2407,6 +2431,7 @@ declare class ArtifactKernelFactory implements EnvironmentKernelFactory {
2407
2431
  private readonly logger;
2408
2432
  private readonly kernelConfig?;
2409
2433
  private readonly authBaseSecret;
2434
+ private readonly defaultRequires;
2410
2435
  constructor(config: ArtifactKernelFactoryConfig);
2411
2436
  create(environmentId: string): Promise<ObjectKernel>;
2412
2437
  }
package/dist/index.d.ts CHANGED
@@ -2027,6 +2027,15 @@ interface ObjectOSStackConfig {
2027
2027
  * (ADR §5.2 — "framework exposes seams; cloud supplies metadata + policy").
2028
2028
  */
2029
2029
  extraPlugins?: Plugin[];
2030
+ /**
2031
+ * Capability tokens force-mounted on EVERY per-environment kernel, in
2032
+ * addition to whatever the app artifact declares in `requires`. Merged and
2033
+ * de-duped with `bundle.requires` before the capability loader runs. This
2034
+ * is the host seam for a cloud operator to make a capability ubiquitous
2035
+ * across all tenants without editing each app — e.g. `['ai','aiStudio']`
2036
+ * so every cloud environment supports AI-driven online development.
2037
+ */
2038
+ defaultRequires?: string[];
2030
2039
  }
2031
2040
  interface ObjectOSStackResult {
2032
2041
  plugins: any[];
@@ -2248,6 +2257,14 @@ interface RuntimeConfigPluginConfig {
2248
2257
  controlPlaneUrl?: string;
2249
2258
  /** Override the `features.installLocal` flag. Default: false. */
2250
2259
  installLocal?: boolean;
2260
+ /**
2261
+ * Override the `features.aiStudio` flag — whether the SPA should surface
2262
+ * AI-driven metadata authoring ("online development") affordances. Default:
2263
+ * true (the actual authoring capability is still gated server-side by the
2264
+ * presence of the `metadata_assistant` agent / @objectstack/service-ai-studio
2265
+ * package; set false to force-hide the authoring UI for a tier/deployment).
2266
+ */
2267
+ aiStudio?: boolean;
2251
2268
  /**
2252
2269
  * Report this runtime as a single-environment deployment (CLI
2253
2270
  * `objectstack dev` / `os serve`). Defaults to `false` for
@@ -2269,6 +2286,7 @@ declare class RuntimeConfigPlugin implements Plugin {
2269
2286
  readonly version = "1.0.0";
2270
2287
  private readonly cloudUrl;
2271
2288
  private readonly installLocal;
2289
+ private readonly aiStudio;
2272
2290
  private readonly singleEnvironment;
2273
2291
  private readonly productName;
2274
2292
  private readonly productShortName;
@@ -2400,6 +2418,12 @@ interface ArtifactKernelFactoryConfig {
2400
2418
  * `process.env.OS_AUTH_SECRET` / `AUTH_SECRET` at construction time.
2401
2419
  */
2402
2420
  authBaseSecret?: string;
2421
+ /**
2422
+ * Capability tokens force-mounted on every per-environment kernel, merged
2423
+ * (and de-duped by the loader) with the artifact's own `requires`. Lets a
2424
+ * host make a capability ubiquitous across tenants — e.g. `['ai','aiStudio']`.
2425
+ */
2426
+ defaultRequires?: string[];
2403
2427
  }
2404
2428
  declare class ArtifactKernelFactory implements EnvironmentKernelFactory {
2405
2429
  private readonly client;
@@ -2407,6 +2431,7 @@ declare class ArtifactKernelFactory implements EnvironmentKernelFactory {
2407
2431
  private readonly logger;
2408
2432
  private readonly kernelConfig?;
2409
2433
  private readonly authBaseSecret;
2434
+ private readonly defaultRequires;
2410
2435
  constructor(config: ArtifactKernelFactoryConfig);
2411
2436
  create(environmentId: string): Promise<ObjectKernel>;
2412
2437
  }
package/dist/index.js CHANGED
@@ -3514,7 +3514,8 @@ var _HttpDispatcher = class _HttpDispatcher {
3514
3514
  if (protocol && typeof protocol.getMetaItem === "function") {
3515
3515
  try {
3516
3516
  const organizationId = await this.resolveActiveOrganizationId(_context);
3517
- const data = await protocol.getMetaItem({ type: singularType, name, packageId, organizationId });
3517
+ const previewDrafts = query?.preview === "draft";
3518
+ const data = await protocol.getMetaItem({ type: singularType, name, packageId, organizationId, previewDrafts });
3518
3519
  return { handled: true, response: this.success(data) };
3519
3520
  } catch (e) {
3520
3521
  }
@@ -3556,7 +3557,8 @@ var _HttpDispatcher = class _HttpDispatcher {
3556
3557
  if (protocol && typeof protocol.getMetaItems === "function") {
3557
3558
  try {
3558
3559
  const organizationId = await this.resolveActiveOrganizationId(_context);
3559
- const data = await protocol.getMetaItems({ type: typeOrName, packageId, organizationId });
3560
+ const previewDrafts = query?.preview === "draft";
3561
+ const data = await protocol.getMetaItems({ type: typeOrName, packageId, organizationId, previewDrafts });
3560
3562
  if (data && (data.items !== void 0 || Array.isArray(data))) {
3561
3563
  return { handled: true, response: this.success(data) };
3562
3564
  }
@@ -3910,6 +3912,24 @@ var _HttpDispatcher = class _HttpDispatcher {
3910
3912
  }
3911
3913
  return { handled: true, response: this.error("Draft publishing not supported", 501) };
3912
3914
  }
3915
+ if (parts.length === 2 && parts[1] === "discard-drafts" && m === "POST") {
3916
+ const id = decodeURIComponent(parts[0]);
3917
+ const protocol = await this.resolveService("protocol");
3918
+ if (protocol && typeof protocol.discardPackageDrafts === "function") {
3919
+ try {
3920
+ const organizationId = await this.resolveActiveOrganizationId(_context);
3921
+ const result = await protocol.discardPackageDrafts({
3922
+ packageId: id,
3923
+ ...organizationId ? { organizationId } : {},
3924
+ ...body?.actor ? { actor: body.actor } : {}
3925
+ });
3926
+ return { handled: true, response: this.success(result) };
3927
+ } catch (e) {
3928
+ return { handled: true, response: this.error(e.message, e.statusCode || 500) };
3929
+ }
3930
+ }
3931
+ return { handled: true, response: this.error("Draft discarding not supported", 501) };
3932
+ }
3913
3933
  if (parts.length === 2 && parts[1] === "revert" && m === "POST") {
3914
3934
  const id = decodeURIComponent(parts[0]);
3915
3935
  const metadataService = await this.getService(CoreServiceName.enum.metadata);
@@ -3935,9 +3955,27 @@ var _HttpDispatcher = class _HttpDispatcher {
3935
3955
  }
3936
3956
  if (parts.length === 1 && m === "DELETE") {
3937
3957
  const id = decodeURIComponent(parts[0]);
3938
- const success = registry.uninstallPackage(id);
3939
- if (!success) return { handled: true, response: this.error(`Package '${id}' not found`, 404) };
3940
- return { handled: true, response: this.success({ success: true }) };
3958
+ const registryRemoved = registry.uninstallPackage(id);
3959
+ let persisted = void 0;
3960
+ const protocol = await this.resolveService("protocol");
3961
+ if (protocol && typeof protocol.deletePackage === "function") {
3962
+ try {
3963
+ const organizationId = await this.resolveActiveOrganizationId(_context);
3964
+ const keepData = query?.keepData === "true" || query?.keepData === "1";
3965
+ persisted = await protocol.deletePackage({
3966
+ packageId: id,
3967
+ ...organizationId ? { organizationId } : {},
3968
+ ...keepData ? { keepData: true } : {}
3969
+ });
3970
+ } catch (e) {
3971
+ return { handled: true, response: this.error(e.message, e.statusCode || 500) };
3972
+ }
3973
+ }
3974
+ const deletedCount = persisted?.deletedCount ?? 0;
3975
+ if (!registryRemoved && deletedCount === 0) {
3976
+ return { handled: true, response: this.error(`Package '${id}' not found`, 404) };
3977
+ }
3978
+ return { handled: true, response: this.success({ success: true, registryRemoved, persisted }) };
3941
3979
  }
3942
3980
  } catch (e) {
3943
3981
  return { handled: true, response: this.error(e.message, e.statusCode || 500) };
@@ -6528,6 +6566,16 @@ var CAPABILITY_PROVIDERS = {
6528
6566
  pkg: "@objectstack/service-ai",
6529
6567
  export: "AIServicePlugin"
6530
6568
  },
6569
+ // AI Studio — AI-driven metadata authoring ("online development"). This is
6570
+ // a commercial capability that ships in the private @objectstack/service-ai-studio
6571
+ // package (not part of the open-source framework). The dynamic import below
6572
+ // silently skips when the package isn't installed, so the open-source build
6573
+ // is unaffected; cloud and enterprise installs that ship the package light it
6574
+ // up. Pair with `ai` in `requires` (it attaches via the `ai:ready` hook).
6575
+ aiStudio: {
6576
+ pkg: "@objectstack/service-ai-studio",
6577
+ export: "AIStudioPlugin"
6578
+ },
6531
6579
  analytics: {
6532
6580
  pkg: "@objectstack/service-analytics",
6533
6581
  export: "AnalyticsServicePlugin",
@@ -6854,6 +6902,7 @@ var ArtifactKernelFactory = class {
6854
6902
  this.envRegistry = config.envRegistry;
6855
6903
  this.logger = config.logger ?? console;
6856
6904
  this.kernelConfig = config.kernelConfig;
6905
+ this.defaultRequires = config.defaultRequires ?? [];
6857
6906
  this.authBaseSecret = (config.authBaseSecret ?? readEnvWithDeprecation3("OS_AUTH_SECRET", ["AUTH_SECRET", "BETTER_AUTH_SECRET"]) ?? "").trim();
6858
6907
  }
6859
6908
  async create(environmentId) {
@@ -7020,7 +7069,10 @@ var ArtifactKernelFactory = class {
7020
7069
  });
7021
7070
  }
7022
7071
  const requiresRaw = (Array.isArray(bundle?.requires) ? bundle.requires : null) ?? (Array.isArray(sys?.requires) ? sys.requires : null) ?? [];
7023
- const requires = requiresRaw.filter((x) => typeof x === "string" && x.length > 0);
7072
+ const requires = [
7073
+ ...requiresRaw,
7074
+ ...this.defaultRequires
7075
+ ].filter((x) => typeof x === "string" && x.length > 0);
7024
7076
  if (requires.length > 0) {
7025
7077
  const installed = await loadCapabilities({
7026
7078
  kernel,
@@ -7679,13 +7731,7 @@ var MarketplaceProxyPlugin = class _MarketplaceProxyPlugin {
7679
7731
  }
7680
7732
  const target = `${cloudUrl}${incomingUrl.pathname}${incomingUrl.search}`;
7681
7733
  if (method !== "GET" && method !== "HEAD") {
7682
- return c.json({
7683
- success: false,
7684
- error: {
7685
- code: "marketplace_method_not_allowed",
7686
- message: `Marketplace proxy only forwards GET/HEAD; install via cloud.`
7687
- }
7688
- }, 405);
7734
+ return next();
7689
7735
  }
7690
7736
  const accept = c.req.header("accept") ?? "application/json";
7691
7737
  const acceptLang = c.req.header("accept-language") ?? "";
@@ -7909,7 +7955,8 @@ var RuntimeConfigPlugin = class {
7909
7955
  const rawApp = httpServer.getRawApp();
7910
7956
  const features = {
7911
7957
  installLocal: this.installLocal,
7912
- marketplace: true
7958
+ marketplace: true,
7959
+ aiStudio: this.aiStudio
7913
7960
  };
7914
7961
  let envRegistry = null;
7915
7962
  try {
@@ -7960,6 +8007,7 @@ var RuntimeConfigPlugin = class {
7960
8007
  };
7961
8008
  this.cloudUrl = config.controlPlaneUrl === "" ? "" : resolveCloudUrl(config.controlPlaneUrl) ?? "";
7962
8009
  this.installLocal = !!config.installLocal;
8010
+ this.aiStudio = config.aiStudio !== false;
7963
8011
  this.singleEnvironment = !!config.singleEnvironment;
7964
8012
  const envName = (typeof process !== "undefined" ? process.env?.OS_PRODUCT_NAME : void 0)?.trim();
7965
8013
  const envShort = (typeof process !== "undefined" ? process.env?.OS_PRODUCT_SHORT_NAME : void 0)?.trim();
@@ -8151,7 +8199,8 @@ var ObjectOSEnvironmentPlugin = class {
8151
8199
  const factory = new ArtifactKernelFactory({
8152
8200
  client,
8153
8201
  envRegistry,
8154
- logger: ctx.logger
8202
+ logger: ctx.logger,
8203
+ defaultRequires: this.config.defaultRequires
8155
8204
  });
8156
8205
  const kernelManager = new KernelManager({
8157
8206
  factory,