@objectstack/runtime 7.7.0 → 7.8.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.cjs +136 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +136 -2
- package/dist/index.js.map +1 -1
- package/package.json +18 -18
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/load-artifact-bundle.ts","../src/driver-plugin.ts","../src/seed-loader.ts","../src/package-state-store.ts","../src/sandbox/quickjs-runner.ts","../src/sandbox/body-runner.ts","../src/app-plugin.ts","../src/standalone-stack.ts","../src/cloud/environment-org-seed.ts","../src/cloud/environment-owner-seed.ts","../src/index.ts","../src/runtime.ts","../src/default-host.ts","../src/external-validation-plugin.ts","../src/http-dispatcher.ts","../src/security/resolve-execution-context.ts","../src/security/security-headers.ts","../src/security/rate-limit.ts","../src/observability/request-context.ts","../src/observability/metrics.ts","../src/observability/error-reporter.ts","../src/observability/instrument.ts","../src/observability/observability-service-plugin.ts","../src/dispatcher-plugin.ts","../src/system-environment-plugin.ts","../src/http-server.ts","../src/middleware.ts","../src/cloud/kernel-manager.ts","../src/cloud/artifact-api-client.ts","../src/cloud/artifact-environment-registry.ts","../src/cloud/artifact-kernel-factory.ts","../src/cloud/capability-loader.ts","../src/cloud/platform-sso.ts","../src/cloud/auth-proxy-plugin.ts","../src/cloud/cloud-url.ts","../src/cloud/marketplace-public-url.ts","../src/cloud/marketplace-proxy-plugin.ts","../src/cloud/runtime-config-plugin.ts","../src/cloud/file-artifact-api-client.ts","../src/cloud/objectos-stack.ts","../src/cloud/marketplace-install-local-plugin.ts","../src/sandbox/script-runner.ts","../src/sandbox/index.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Shared artifact loader used by every code path that boots a kernel\n * from an `objectstack build` artifact:\n *\n * - `FsAppBundleResolver` — cloud / multi-environment file binding\n * - `runtime-stack.ts:basePlugins` — single-environment local boot\n * - `StandaloneStack` — `objectstack serve --standalone`\n * - `http-dispatcher.ts` — in-flight artifact rebind\n *\n * Reads the JSON artifact (from a local path *or* an `http(s)://` URL) and,\n * for **local** artifacts only, if the bundle declares a sibling\n * `runtimeModule` (the ESM produced by `packages/cli/src/utils/build-runtime.ts`),\n * dynamic-imports it and merges its `functions` map onto the bundle so\n * declarative Hooks resolve their handlers at boot.\n *\n * For **remote** (`http(s)://`) artifacts the `runtimeModule` reference is\n * intentionally ignored — Node cannot dynamic-import arbitrary URLs and we\n * refuse to execute remote code by default. Remote artifacts are therefore\n * expected to be fully declarative (Hooks/Flows carry their bodies inline).\n *\n * Mutates the returned bundle in place. Returns `null` on read/parse\n * failure (callers may treat as \"no bundle for this project yet\").\n * Runtime-module load failures are logged but non-fatal — the bundle\n * is still returned, just without runtime functions.\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { resolve as resolvePath, isAbsolute, dirname } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nexport interface LoadArtifactBundleOptions {\n /** Optional log tag for warnings (defaults to `[loadArtifactBundle]`). */\n tag?: string;\n /** When true, an unwrapped `{ schemaVersion, metadata }` envelope is unwrapped. */\n unwrapEnvelope?: boolean;\n /** Optional fetch timeout in ms for `http(s)://` sources (default 15000). */\n fetchTimeoutMs?: number;\n}\n\n/** Returns true when `pathOrUrl` looks like an `http://` or `https://` URL. */\nexport function isHttpUrl(pathOrUrl: string): boolean {\n return /^https?:\\/\\//i.test(pathOrUrl);\n}\n\n/**\n * Read a JSON artifact from either a local file path or an `http(s)://` URL.\n * Returns the raw text body. Throws on network or filesystem failure.\n */\nexport async function readArtifactSource(\n pathOrUrl: string,\n opts: { fetchTimeoutMs?: number } = {},\n): Promise<string> {\n if (isHttpUrl(pathOrUrl)) {\n const timeoutMs = opts.fetchTimeoutMs ?? 15_000;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(pathOrUrl, {\n redirect: 'follow',\n signal: controller.signal,\n headers: { Accept: 'application/json, text/plain;q=0.9, */*;q=0.5' },\n });\n if (!res.ok) {\n throw new Error(`HTTP ${res.status} ${res.statusText} for ${pathOrUrl}`);\n }\n return await res.text();\n } finally {\n clearTimeout(timer);\n }\n }\n return readFile(pathOrUrl, 'utf-8');\n}\n\nexport async function loadArtifactBundle(\n absArtifactPath: string,\n opts: LoadArtifactBundleOptions = {},\n): Promise<any | null> {\n const tag = opts.tag ?? '[loadArtifactBundle]';\n const isUrl = isHttpUrl(absArtifactPath);\n let bundle: any;\n try {\n const raw = await readArtifactSource(absArtifactPath, { fetchTimeoutMs: opts.fetchTimeoutMs });\n const parsed = JSON.parse(raw);\n bundle = opts.unwrapEnvelope && parsed?.schemaVersion != null && parsed?.metadata !== undefined\n ? parsed.metadata\n : parsed;\n } catch (err: any) {\n // eslint-disable-next-line no-console\n console.warn(`${tag} artifact read FAILED: path='${absArtifactPath}' error=${err?.message ?? err}`);\n return null;\n }\n\n if (isUrl) {\n // Remote artifacts cannot dynamic-import a sibling ESM runtime module\n // safely (Node does not allow importing arbitrary URLs and we never\n // want to execute remote code by default). Hooks/flow handlers must\n // be carried in the JSON itself (declarative bodies, sandbox-eval).\n if (typeof bundle?.runtimeModule === 'string' && bundle.runtimeModule.length > 0) {\n // eslint-disable-next-line no-console\n console.warn(\n `${tag} ignoring runtimeModule='${bundle.runtimeModule}' for remote artifact ${absArtifactPath} ` +\n `(remote ESM imports are not supported; embed handlers in the JSON instead)`,\n );\n // Strip the reference so downstream code doesn't try to resolve it\n // as a local path against process.cwd().\n delete bundle.runtimeModule;\n }\n return bundle;\n }\n\n await mergeRuntimeModule(bundle, absArtifactPath, tag);\n return bundle;\n}\n\nexport async function mergeRuntimeModule(bundle: any, artifactAbsPath: string, tag = '[loadArtifactBundle]'): Promise<void> {\n const ref = bundle?.runtimeModule;\n if (typeof ref !== 'string' || ref.length === 0) return;\n const moduleAbsPath = isAbsolute(ref) ? ref : resolvePath(dirname(artifactAbsPath), ref);\n try {\n const mod: any = await import(pathToFileURL(moduleAbsPath).href);\n const fns = (mod && (mod.functions ?? mod.default?.functions)) ?? null;\n if (!fns || typeof fns !== 'object') {\n // eslint-disable-next-line no-console\n console.warn(`${tag} runtime module '${moduleAbsPath}' exported no \\`functions\\` map`);\n return;\n }\n const existing = (bundle.functions && typeof bundle.functions === 'object' && !Array.isArray(bundle.functions))\n ? bundle.functions as Record<string, unknown>\n : {};\n bundle.functions = { ...existing, ...fns };\n } catch (err: any) {\n // eslint-disable-next-line no-console\n console.warn(`${tag} runtime module load FAILED: path='${moduleAbsPath}' error=${err?.message ?? err}`);\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { Plugin, PluginContext } from '@objectstack/core';\n\n/**\n * Driver Plugin\n * \n * Generic plugin wrapper for ObjectQL drivers.\n * Registers a driver with the ObjectQL engine.\n * \n * Dependencies: None (Registers service for ObjectQL to discover)\n * Services: driver.{name}\n * \n * @example\n * const memoryDriver = new InMemoryDriver();\n * const driverPlugin = new DriverPlugin(memoryDriver, 'memory');\n * kernel.use(driverPlugin);\n */\nexport interface DriverPluginOptions {\n /**\n * If set, registers a named datasource so packages declaring\n * `defaultDatasource: '<name>'` resolve to this driver.\n */\n datasourceName?: string;\n /**\n * If `true` (default), registers this driver as the `default` datasource\n * when none exists. Set to `false` for proxy drivers (e.g. cloud proxy)\n * that should never become the default.\n */\n registerAsDefault?: boolean;\n}\n\nexport class DriverPlugin implements Plugin {\n name: string;\n type = 'driver';\n version = '1.0.0';\n\n private driver: any;\n private options: DriverPluginOptions;\n\n constructor(driver: any, driverNameOrOptions?: string | DriverPluginOptions, options?: DriverPluginOptions) {\n this.driver = driver;\n const driverName = typeof driverNameOrOptions === 'string' ? driverNameOrOptions : undefined;\n this.options = (typeof driverNameOrOptions === 'object' ? driverNameOrOptions : options) ?? {};\n this.name = `com.objectstack.driver.${driverName || driver.name || 'unknown'}`;\n }\n\n init = async (ctx: PluginContext) => {\n const serviceName = `driver.${this.driver.name || 'unknown'}`;\n ctx.registerService(serviceName, this.driver);\n ctx.logger.info('Driver service registered', { \n serviceName, \n driverName: this.driver.name,\n driverVersion: this.driver.version \n });\n }\n\n start = async (ctx: PluginContext) => {\n try {\n const metadata = ctx.getService<any>('metadata');\n if (!metadata?.addDatasource) return;\n\n // Register a named datasource for this driver (e.g. 'cloud').\n if (this.options.datasourceName) {\n await metadata.addDatasource({\n name: this.options.datasourceName,\n driver: this.driver.name,\n });\n ctx.logger.info(`[DriverPlugin] Registered named datasource '${this.options.datasourceName}'`, { driver: this.driver.name });\n }\n\n // Auto-register as 'default' datasource unless explicitly disabled.\n if (this.options.registerAsDefault !== false) {\n const datasources = metadata.getDatasources ? metadata.getDatasources() : [];\n const hasDefault = datasources.some((ds: any) => ds.name === 'default');\n if (!hasDefault) {\n ctx.logger.info(`[DriverPlugin] No 'default' datasource found — registering '${this.driver.name}' as default.`);\n await metadata.addDatasource({ name: 'default', driver: this.driver.name });\n }\n }\n } catch (e) {\n ctx.logger.debug('[DriverPlugin] Failed to configure datasource (metadata service missing?)', { error: e });\n }\n\n ctx.logger.debug('Driver plugin started', { driverName: this.driver.name || 'unknown' });\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { IDataEngine, IMetadataService, ISeedLoaderService } from '@objectstack/spec/contracts';\nimport type {\n SeedLoaderRequest,\n SeedLoaderResult,\n SeedLoaderConfig,\n SeedLoaderConfigInput,\n ObjectDependencyGraph,\n ObjectDependencyNode,\n ReferenceResolution,\n ReferenceResolutionError,\n DatasetLoadResult,\n Dataset,\n} from '@objectstack/spec/data';\nimport { SeedLoaderConfigSchema } from '@objectstack/spec/data';\nimport { resolveSeedRecord } from '@objectstack/formula';\n\ninterface Logger {\n info(message: string, meta?: Record<string, any>): void;\n warn(message: string, meta?: Record<string, any>): void;\n error(message: string, error?: Error, meta?: Record<string, any>): void;\n debug(message: string, meta?: Record<string, any>): void;\n}\n\n/** Default field used for externalId matching on target objects */\nconst DEFAULT_EXTERNAL_ID_FIELD = 'name';\n\n/**\n * SeedLoaderService — Runtime implementation of ISeedLoaderService\n *\n * Provides metadata-driven seed data loading with:\n * - Automatic lookup/master_detail reference resolution via externalId\n * - Topological dependency ordering (parents before children)\n * - Multi-pass loading for circular references\n * - Dry-run validation mode\n * - Upsert support honoring DatasetSchema mode\n * - Actionable error reporting\n */\nexport class SeedLoaderService implements ISeedLoaderService {\n private engine: IDataEngine;\n private metadata: IMetadataService;\n private logger: Logger;\n\n constructor(engine: IDataEngine, metadata: IMetadataService, logger: Logger) {\n this.engine = engine;\n this.metadata = metadata;\n this.logger = logger;\n }\n\n // ==========================================================================\n // Public API\n // ==========================================================================\n\n async load(request: SeedLoaderRequest): Promise<SeedLoaderResult> {\n const startTime = Date.now();\n const config = request.config;\n const allErrors: ReferenceResolutionError[] = [];\n const allResults: DatasetLoadResult[] = [];\n\n // 1. Filter datasets by environment\n const datasets = this.filterByEnv(request.datasets, config.env);\n\n if (datasets.length === 0) {\n return this.buildEmptyResult(config, Date.now() - startTime);\n }\n\n // 2. Build dependency graph\n const objectNames = datasets.map(d => d.object);\n const graph = await this.buildDependencyGraph(objectNames);\n\n this.logger.info('[SeedLoader] Dependency graph built', {\n objects: objectNames.length,\n insertOrder: graph.insertOrder,\n circularDeps: graph.circularDependencies.length,\n });\n\n // 3. Order datasets by topological insert order\n const orderedDatasets = this.orderDatasets(datasets, graph.insertOrder);\n\n // 4. Build reference lookup map from metadata (field → target object)\n const refMap = this.buildReferenceMap(graph);\n\n // 5. Pass 1: Insert/upsert records, resolving references\n const insertedRecords = new Map<string, Map<string, string>>(); // object → externalIdValue → internalId\n const deferredUpdates: DeferredUpdate[] = [];\n\n for (const dataset of orderedDatasets) {\n const result = await this.loadDataset(\n dataset, config, refMap, insertedRecords, deferredUpdates, allErrors\n );\n allResults.push(result);\n\n if (config.haltOnError && result.errored > 0) {\n this.logger.warn('[SeedLoader] Halting on first error', { object: dataset.object });\n break;\n }\n }\n\n // 6. Pass 2: Resolve deferred references (circular dependencies)\n if (config.multiPass && deferredUpdates.length > 0 && !config.dryRun) {\n this.logger.info('[SeedLoader] Pass 2: resolving deferred references', {\n count: deferredUpdates.length,\n });\n await this.resolveDeferredUpdates(deferredUpdates, insertedRecords, allResults, allErrors, config.organizationId);\n }\n\n // 7. Build final result\n const durationMs = Date.now() - startTime;\n return this.buildResult(config, graph, allResults, allErrors, durationMs);\n }\n\n async buildDependencyGraph(objectNames: string[]): Promise<ObjectDependencyGraph> {\n const nodes: ObjectDependencyNode[] = [];\n const objectSet = new Set(objectNames);\n\n for (const objectName of objectNames) {\n const objDef = await this.metadata.getObject(objectName) as any;\n const dependsOn: string[] = [];\n const references: ReferenceResolution[] = [];\n\n if (objDef && objDef.fields) {\n const fields = objDef.fields as Record<string, any>;\n for (const [fieldName, fieldDef] of Object.entries(fields)) {\n if (\n (fieldDef.type === 'lookup' || fieldDef.type === 'master_detail') &&\n fieldDef.reference\n ) {\n const targetObject = fieldDef.reference as string;\n\n // Track dependency ordering only for objects within the graph\n if (objectSet.has(targetObject) && !dependsOn.includes(targetObject)) {\n dependsOn.push(targetObject);\n }\n\n // Track ALL references for resolution (target may exist in database)\n references.push({\n field: fieldName,\n targetObject,\n targetField: DEFAULT_EXTERNAL_ID_FIELD,\n fieldType: fieldDef.type as 'lookup' | 'master_detail',\n });\n }\n }\n }\n\n nodes.push({ object: objectName, dependsOn, references });\n }\n\n // Topological sort\n const { insertOrder, circularDependencies } = this.topologicalSort(nodes);\n\n return { nodes, insertOrder, circularDependencies };\n }\n\n async validate(datasets: Dataset[], config?: SeedLoaderConfigInput): Promise<SeedLoaderResult> {\n const parsedConfig = SeedLoaderConfigSchema.parse({ ...config, dryRun: true });\n return this.load({ datasets, config: parsedConfig });\n }\n\n // ==========================================================================\n // Internal: Dataset Loading\n // ==========================================================================\n\n private async loadDataset(\n dataset: Dataset,\n config: SeedLoaderConfig,\n refMap: Map<string, ReferenceResolution[]>,\n insertedRecords: Map<string, Map<string, string>>,\n deferredUpdates: DeferredUpdate[],\n allErrors: ReferenceResolutionError[],\n ): Promise<DatasetLoadResult> {\n const objectName = dataset.object;\n const mode = dataset.mode || config.defaultMode;\n const externalId = dataset.externalId || 'name';\n\n let inserted = 0;\n let updated = 0;\n let skipped = 0;\n let errored = 0;\n let referencesResolved = 0;\n let referencesDeferred = 0;\n const errors: ReferenceResolutionError[] = [];\n\n // Ensure the object's record map exists\n if (!insertedRecords.has(objectName)) {\n insertedRecords.set(objectName, new Map());\n }\n\n // Pre-load existing records for upsert matching. When a target\n // organization is set, scope the lookup so each tenant gets its\n // own copy (otherwise upsert would clobber other tenants' rows\n // that share the same natural key — e.g. `name: 'Acme Corp'`).\n let existingRecords: Map<string, any> | undefined;\n if ((mode === 'upsert' || mode === 'update' || mode === 'ignore') && !config.dryRun) {\n existingRecords = await this.loadExistingRecords(\n objectName,\n externalId,\n config.organizationId,\n );\n }\n\n // Get reference resolutions for this object\n const objectRefs = refMap.get(objectName) || [];\n\n // Pin a single `now()` snapshot for the entire dataset so multi-pass\n // loads see one logical clock — the M9 determinism guarantee for seeds.\n const seedNow = new Date();\n\n // Identity/context bound to seed CEL expressions. `os.user` / `os.org`\n // resolve from here, so `owner_id: cel\\`os.user.id\\`` works. When no\n // identity is supplied, `os.user` / `os.org` are simply unbound and any\n // record that references them fails loudly below (rather than silently\n // writing a raw Expression envelope into the column).\n const seedIdentity = config.identity;\n const baseEvalCtx = {\n now: seedNow,\n user: seedIdentity?.user,\n // Fall back to the per-tenant organizationId so `os.org.id` resolves\n // during per-org replay even without an explicit identity.org.\n org: seedIdentity?.org ?? (config.organizationId ? { id: config.organizationId } : undefined),\n env: config.env,\n };\n\n for (let i = 0; i < dataset.records.length; i++) {\n // Resolve any embedded Expression envelopes (e.g. `cel\\`daysFromNow(30)\\``,\n // `cel\\`os.user.id\\``) BEFORE reference resolution so downstream lookups\n // see resolved values.\n const seedResult = resolveSeedRecord(\n dataset.records[i] as Record<string, never>,\n baseEvalCtx,\n );\n if (!seedResult.ok) {\n // LOUD FAILURE: a record whose dynamic values cannot be resolved is\n // dropped — but never silently. Record an actionable error (so it\n // surfaces in result.errors and flips success=false) instead of\n // writing the unresolved Expression envelope into the database.\n errored++;\n const error: ReferenceResolutionError = {\n sourceObject: objectName,\n field: '(expression)',\n targetObject: objectName,\n targetField: '(expression)',\n attemptedValue: dataset.records[i],\n recordIndex: i,\n message:\n `Cannot resolve dynamic seed values for ${objectName} record #${i}: ${seedResult.error.message}. ` +\n 'Records using cel`os.user.id` / cel`os.org.id` require a seed identity — ' +\n 'ensure a system/admin user exists before seeding (see SeedLoaderConfig.identity).',\n };\n errors.push(error);\n allErrors.push(error);\n this.logger.warn(`[SeedLoader] ${error.message}`);\n continue;\n }\n const record = { ...(seedResult.value as Record<string, unknown>) };\n\n // Per-tenant tagging: when a target org is set, stamp every\n // seeded row with it (unless the record itself already supplies\n // an explicit organization_id — respect dataset author overrides).\n // Skipped objects that don't declare `organization_id` will have\n // the extra key silently ignored by the engine.\n if (config.organizationId && record['organization_id'] == null) {\n record['organization_id'] = config.organizationId;\n }\n\n // Resolve references\n for (const ref of objectRefs) {\n const fieldValue = record[ref.field];\n if (fieldValue === undefined || fieldValue === null) continue;\n\n // Skip if value looks like an internal ID (not a natural key)\n if (typeof fieldValue !== 'string' || this.looksLikeInternalId(fieldValue)) continue;\n\n // Try to resolve via already-inserted records\n const targetMap = insertedRecords.get(ref.targetObject);\n const resolvedId = targetMap?.get(String(fieldValue));\n\n if (resolvedId) {\n record[ref.field] = resolvedId;\n referencesResolved++;\n } else if (!config.dryRun) {\n // Try to resolve from existing data in the database\n const dbId = await this.resolveFromDatabase(ref.targetObject, ref.targetField, fieldValue, config.organizationId);\n if (dbId) {\n record[ref.field] = dbId;\n referencesResolved++;\n } else if (config.multiPass) {\n // Defer to pass 2\n record[ref.field] = null;\n deferredUpdates.push({\n objectName,\n recordExternalId: String(record[externalId] ?? ''),\n field: ref.field,\n targetObject: ref.targetObject,\n targetField: ref.targetField,\n attemptedValue: fieldValue,\n recordIndex: i,\n });\n referencesDeferred++;\n } else {\n // Cannot resolve - record error\n const error: ReferenceResolutionError = {\n sourceObject: objectName,\n field: ref.field,\n targetObject: ref.targetObject,\n targetField: ref.targetField,\n attemptedValue: fieldValue,\n recordIndex: i,\n message: `Cannot resolve reference: ${objectName}.${ref.field} = '${fieldValue}' → ${ref.targetObject}.${ref.targetField} not found`,\n };\n errors.push(error);\n allErrors.push(error);\n }\n } else {\n // Dry-run: attempt resolution, report error if not found\n const targetMap2 = insertedRecords.get(ref.targetObject);\n if (!targetMap2?.has(String(fieldValue))) {\n const error: ReferenceResolutionError = {\n sourceObject: objectName,\n field: ref.field,\n targetObject: ref.targetObject,\n targetField: ref.targetField,\n attemptedValue: fieldValue,\n recordIndex: i,\n message: `[dry-run] Reference may not resolve: ${objectName}.${ref.field} = '${fieldValue}' → ${ref.targetObject}.${ref.targetField}`,\n };\n errors.push(error);\n allErrors.push(error);\n }\n }\n }\n\n // Insert/upsert the record\n if (!config.dryRun) {\n try {\n const result = await this.writeRecord(\n objectName, record, mode, externalId, existingRecords\n );\n\n if (result.action === 'inserted') inserted++;\n else if (result.action === 'updated') updated++;\n else if (result.action === 'skipped') skipped++;\n\n // Track the inserted/updated record's ID for reference resolution\n const externalIdValue = String(record[externalId] ?? '');\n const internalId = result.id;\n if (externalIdValue && internalId) {\n insertedRecords.get(objectName)!.set(externalIdValue, String(internalId));\n }\n } catch (err: any) {\n // LOUD FAILURE: write errors were previously only counted +\n // warn-logged, so dropped rows were invisible in result.errors and\n // the boot summary. Surface them as actionable errors too, so the\n // overall load is marked unsuccessful and the reason is reported.\n errored++;\n const error: ReferenceResolutionError = {\n sourceObject: objectName,\n field: '(write)',\n targetObject: objectName,\n targetField: externalId,\n attemptedValue: record[externalId] ?? null,\n recordIndex: i,\n message: `Failed to write ${objectName} record #${i} (${externalId}=${String(record[externalId] ?? '')}): ${err.message}`,\n };\n errors.push(error);\n allErrors.push(error);\n this.logger.warn(`[SeedLoader] ${error.message}`, { recordIndex: i });\n }\n } else {\n // Dry-run: simulate insert tracking\n const externalIdValue = String(record[externalId] ?? '');\n if (externalIdValue) {\n insertedRecords.get(objectName)!.set(externalIdValue, `dry-run-id-${i}`);\n }\n inserted++; // Count as \"would be inserted\"\n }\n }\n\n return {\n object: objectName,\n mode,\n inserted,\n updated,\n skipped,\n errored,\n total: dataset.records.length,\n referencesResolved,\n referencesDeferred,\n errors,\n };\n }\n\n // ==========================================================================\n // Internal: Reference Resolution\n // ==========================================================================\n\n private async resolveFromDatabase(\n targetObject: string,\n targetField: string,\n value: unknown,\n organizationId?: string,\n ): Promise<string | null> {\n try {\n const where: Record<string, unknown> = { [targetField]: value };\n // Per-tenant replay: when scoping is requested, only consider\n // rows that belong to the target tenant so cross-tenant rows\n // never get borrowed as a \"resolved\" reference (would silently\n // create a cross-org FK).\n if (organizationId) where.organization_id = organizationId;\n const records = await this.engine.find(targetObject, {\n where,\n fields: ['id'],\n limit: 1,\n context: { isSystem: true },\n } as any);\n if (records && records.length > 0) {\n return String(records[0].id || records[0]._id);\n }\n } catch {\n // Target object may not exist yet\n }\n return null;\n }\n\n private async resolveDeferredUpdates(\n deferredUpdates: DeferredUpdate[],\n insertedRecords: Map<string, Map<string, string>>,\n allResults: DatasetLoadResult[],\n allErrors: ReferenceResolutionError[],\n organizationId?: string,\n ): Promise<void> {\n for (const deferred of deferredUpdates) {\n // Try to resolve from inserted records\n const targetMap = insertedRecords.get(deferred.targetObject);\n let resolvedId = targetMap?.get(String(deferred.attemptedValue));\n\n // Try database fallback\n if (!resolvedId) {\n resolvedId = (await this.resolveFromDatabase(\n deferred.targetObject, deferred.targetField, deferred.attemptedValue, organizationId\n )) ?? undefined;\n }\n\n if (resolvedId) {\n // Find the record and update the reference\n const objectRecordMap = insertedRecords.get(deferred.objectName);\n const recordId = objectRecordMap?.get(deferred.recordExternalId);\n\n if (recordId) {\n try {\n await this.engine.update(deferred.objectName, {\n id: recordId,\n [deferred.field]: resolvedId,\n }, { context: { isSystem: true } } as any);\n\n // Update result stats\n const resultEntry = allResults.find(r => r.object === deferred.objectName);\n if (resultEntry) {\n resultEntry.referencesResolved++;\n resultEntry.referencesDeferred--;\n }\n } catch (err: any) {\n this.logger.warn('[SeedLoader] Failed to resolve deferred reference', {\n object: deferred.objectName,\n field: deferred.field,\n error: err.message,\n });\n }\n }\n } else {\n // Still unresolved after pass 2\n const error: ReferenceResolutionError = {\n sourceObject: deferred.objectName,\n field: deferred.field,\n targetObject: deferred.targetObject,\n targetField: deferred.targetField,\n attemptedValue: deferred.attemptedValue,\n recordIndex: deferred.recordIndex,\n message: `Deferred reference unresolved after pass 2: ${deferred.objectName}.${deferred.field} = '${deferred.attemptedValue}' → ${deferred.targetObject}.${deferred.targetField} not found`,\n };\n\n const resultEntry = allResults.find(r => r.object === deferred.objectName);\n if (resultEntry) {\n resultEntry.errors.push(error);\n }\n allErrors.push(error);\n }\n }\n }\n\n // ==========================================================================\n // Internal: Write Operations\n // ==========================================================================\n\n /**\n * Seed writes always run as a privileged system context. This bypasses\n * RBAC checks (so seeds can target system tables like `sys_*`) and\n * disables the SecurityPlugin's auto-injection of `organization_id` /\n * `owner_id` — seeds either declare those fields explicitly per\n * record, or are intentionally cross-tenant / global.\n */\n private static readonly SEED_OPTIONS = { context: { isSystem: true } } as const;\n\n private async writeRecord(\n objectName: string,\n record: Record<string, unknown>,\n mode: string,\n externalId: string,\n existingRecords?: Map<string, any>,\n ): Promise<{ action: 'inserted' | 'updated' | 'skipped'; id?: string }> {\n const externalIdValue = record[externalId];\n const existing = existingRecords?.get(String(externalIdValue ?? ''));\n const opts = SeedLoaderService.SEED_OPTIONS as any;\n\n switch (mode) {\n case 'insert': {\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n\n case 'update': {\n if (!existing) {\n return { action: 'skipped' };\n }\n const id = this.extractId(existing);\n await this.engine.update(objectName, { ...record, id }, opts);\n return { action: 'updated', id };\n }\n\n case 'upsert': {\n if (existing) {\n const id = this.extractId(existing);\n await this.engine.update(objectName, { ...record, id }, opts);\n return { action: 'updated', id };\n } else {\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n }\n\n case 'ignore': {\n if (existing) {\n return { action: 'skipped', id: this.extractId(existing) };\n }\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n\n case 'replace': {\n // Replace mode: just insert (caller should have cleared the table)\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n\n default: {\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n }\n }\n\n // ==========================================================================\n // Internal: Dependency Graph\n // ==========================================================================\n\n /**\n * Kahn's algorithm for topological sort with cycle detection.\n */\n private topologicalSort(\n nodes: ObjectDependencyNode[],\n ): { insertOrder: string[]; circularDependencies: string[][] } {\n const inDegree = new Map<string, number>();\n const adjacency = new Map<string, string[]>();\n const objectSet = new Set(nodes.map(n => n.object));\n\n // Initialize\n for (const node of nodes) {\n inDegree.set(node.object, 0);\n adjacency.set(node.object, []);\n }\n\n // Build adjacency list and in-degree counts\n for (const node of nodes) {\n for (const dep of node.dependsOn) {\n // Exclude self-references from ordering (e.g., employee.manager_id → employee).\n // Self-referencing fields are still tracked in node.references for resolution.\n if (objectSet.has(dep) && dep !== node.object) {\n adjacency.get(dep)!.push(node.object);\n inDegree.set(node.object, (inDegree.get(node.object) || 0) + 1);\n }\n }\n }\n\n // Kahn's algorithm\n const queue: string[] = [];\n for (const [obj, degree] of inDegree) {\n if (degree === 0) queue.push(obj);\n }\n\n const insertOrder: string[] = [];\n while (queue.length > 0) {\n const current = queue.shift()!;\n insertOrder.push(current);\n\n for (const neighbor of (adjacency.get(current) || [])) {\n const newDegree = (inDegree.get(neighbor) || 0) - 1;\n inDegree.set(neighbor, newDegree);\n if (newDegree === 0) {\n queue.push(neighbor);\n }\n }\n }\n\n // Detect circular dependencies\n const circularDependencies: string[][] = [];\n const remaining = nodes.filter(n => !insertOrder.includes(n.object));\n\n if (remaining.length > 0) {\n // Find cycles using DFS\n const cycles = this.findCycles(remaining);\n circularDependencies.push(...cycles);\n\n // Add remaining objects to insertOrder (they'll need multi-pass)\n for (const node of remaining) {\n if (!insertOrder.includes(node.object)) {\n insertOrder.push(node.object);\n }\n }\n }\n\n return { insertOrder, circularDependencies };\n }\n\n private findCycles(nodes: ObjectDependencyNode[]): string[][] {\n const cycles: string[][] = [];\n const nodeMap = new Map(nodes.map(n => [n.object, n]));\n const visited = new Set<string>();\n const inStack = new Set<string>();\n\n const dfs = (current: string, path: string[]) => {\n if (inStack.has(current)) {\n // Found a cycle\n const cycleStart = path.indexOf(current);\n if (cycleStart !== -1) {\n cycles.push([...path.slice(cycleStart), current]);\n }\n return;\n }\n if (visited.has(current)) return;\n\n visited.add(current);\n inStack.add(current);\n path.push(current);\n\n const node = nodeMap.get(current);\n if (node) {\n for (const dep of node.dependsOn) {\n if (nodeMap.has(dep)) {\n dfs(dep, [...path]);\n }\n }\n }\n\n inStack.delete(current);\n };\n\n for (const node of nodes) {\n if (!visited.has(node.object)) {\n dfs(node.object, []);\n }\n }\n\n return cycles;\n }\n\n // ==========================================================================\n // Internal: Helpers\n // ==========================================================================\n\n private filterByEnv(datasets: Dataset[], env?: string): Dataset[] {\n if (!env) return datasets;\n return datasets.filter(d => (d.env as string[]).includes(env));\n }\n\n private orderDatasets(datasets: Dataset[], insertOrder: string[]): Dataset[] {\n const orderMap = new Map(insertOrder.map((name, i) => [name, i]));\n return [...datasets].sort((a, b) => {\n const orderA = orderMap.get(a.object) ?? Number.MAX_SAFE_INTEGER;\n const orderB = orderMap.get(b.object) ?? Number.MAX_SAFE_INTEGER;\n return orderA - orderB;\n });\n }\n\n private buildReferenceMap(graph: ObjectDependencyGraph): Map<string, ReferenceResolution[]> {\n const map = new Map<string, ReferenceResolution[]>();\n for (const node of graph.nodes) {\n if (node.references.length > 0) {\n map.set(node.object, node.references);\n }\n }\n return map;\n }\n\n private async loadExistingRecords(\n objectName: string,\n externalId: string,\n organizationId?: string,\n ): Promise<Map<string, any>> {\n const map = new Map<string, any>();\n try {\n const findArgs: Record<string, unknown> = {\n fields: ['id', externalId],\n context: { isSystem: true },\n };\n // Per-tenant replay: restrict to the target tenant's own rows\n // so upsert key matching never returns another tenant's record\n // (would silently steal/overwrite rows across orgs).\n if (organizationId) findArgs.where = { organization_id: organizationId };\n const records = await this.engine.find(objectName, findArgs as any);\n for (const record of records || []) {\n const key = String(record[externalId] ?? '');\n if (key) {\n map.set(key, record);\n }\n }\n } catch {\n // Object may not have records yet\n }\n return map;\n }\n\n private looksLikeInternalId(value: string): boolean {\n // UUID v4 pattern\n if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)) {\n return true;\n }\n // MongoDB ObjectId pattern (24 hex chars)\n if (/^[0-9a-f]{24}$/i.test(value)) {\n return true;\n }\n return false;\n }\n\n private extractId(record: any): string | undefined {\n if (!record) return undefined;\n return String(record.id || record._id || '');\n }\n\n private buildEmptyResult(config: SeedLoaderConfig, durationMs: number): SeedLoaderResult {\n return {\n success: true,\n dryRun: config.dryRun,\n dependencyGraph: { nodes: [], insertOrder: [], circularDependencies: [] },\n results: [],\n errors: [],\n summary: {\n objectsProcessed: 0,\n totalRecords: 0,\n totalInserted: 0,\n totalUpdated: 0,\n totalSkipped: 0,\n totalErrored: 0,\n totalReferencesResolved: 0,\n totalReferencesDeferred: 0,\n circularDependencyCount: 0,\n durationMs,\n },\n };\n }\n\n private buildResult(\n config: SeedLoaderConfig,\n graph: ObjectDependencyGraph,\n results: DatasetLoadResult[],\n errors: ReferenceResolutionError[],\n durationMs: number,\n ): SeedLoaderResult {\n const summary = {\n objectsProcessed: results.length,\n totalRecords: results.reduce((sum, r) => sum + r.total, 0),\n totalInserted: results.reduce((sum, r) => sum + r.inserted, 0),\n totalUpdated: results.reduce((sum, r) => sum + r.updated, 0),\n totalSkipped: results.reduce((sum, r) => sum + r.skipped, 0),\n totalErrored: results.reduce((sum, r) => sum + r.errored, 0),\n totalReferencesResolved: results.reduce((sum, r) => sum + r.referencesResolved, 0),\n totalReferencesDeferred: results.reduce((sum, r) => sum + r.referencesDeferred, 0),\n circularDependencyCount: graph.circularDependencies.length,\n durationMs,\n };\n\n const hasErrors = errors.length > 0 || summary.totalErrored > 0;\n\n return {\n success: !hasErrors,\n dryRun: config.dryRun,\n dependencyGraph: graph,\n results,\n errors,\n summary,\n };\n }\n}\n\n// ==========================================================================\n// Internal Types\n// ==========================================================================\n\ninterface DeferredUpdate {\n objectName: string;\n recordExternalId: string;\n field: string;\n targetObject: string;\n targetField: string;\n attemptedValue: unknown;\n recordIndex: number;\n}\n","/**\n * Package lifecycle-state persistence (local-first).\n *\n * The in-memory {@link SchemaRegistry} loses package enable/disable state on\n * every restart because packages are re-registered from the compiled artifact\n * (always enabled). This store persists the *runtime lifecycle state* (which\n * packages an operator has disabled) outside the artifact so the choice\n * survives restarts.\n *\n * Storage is a small JSON file under the ObjectStack home directory, keyed by\n * environment id so disables never leak between environments (e.g. `env_local`\n * vs staging):\n *\n * <OS_HOME>/package-state/<environmentId>.json → { \"disabled\": [\"id\", …] }\n *\n * This is intentionally a flat file rather than a `sys_*` object: package\n * lifecycle state is runtime/operational state, not project metadata, and the\n * local-first install path already keeps per-environment data under OS_HOME.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport { resolveObjectStackHome } from './standalone-stack.js';\n\nconst DEFAULT_ENVIRONMENT_ID = 'default';\n\ninterface PackageStateFile {\n disabled?: string[];\n}\n\nfunction sanitizeEnvironmentId(environmentId?: string): string {\n const raw = (environmentId ?? process.env.OS_ENVIRONMENT_ID ?? DEFAULT_ENVIRONMENT_ID).trim();\n const safe = raw.replace(/[^a-zA-Z0-9._-]/g, '_');\n return safe.length > 0 ? safe : DEFAULT_ENVIRONMENT_ID;\n}\n\nfunction stateFilePath(environmentId?: string): string {\n return join(resolveObjectStackHome(), 'package-state', `${sanitizeEnvironmentId(environmentId)}.json`);\n}\n\nfunction readState(environmentId?: string): PackageStateFile {\n const file = stateFilePath(environmentId);\n if (!existsSync(file)) return {};\n try {\n const parsed = JSON.parse(readFileSync(file, 'utf8')) as PackageStateFile;\n return parsed && typeof parsed === 'object' ? parsed : {};\n } catch {\n // Corrupt/partial file — treat as empty rather than crashing boot.\n return {};\n }\n}\n\nfunction writeState(environmentId: string | undefined, state: PackageStateFile): void {\n const file = stateFilePath(environmentId);\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, `${JSON.stringify(state, null, 2)}\\n`, 'utf8');\n}\n\n/** Set of package ids currently persisted as disabled for the environment. */\nexport function loadDisabledPackageIds(environmentId?: string): Set<string> {\n const disabled = readState(environmentId).disabled;\n return new Set(Array.isArray(disabled) ? disabled.filter((id) => typeof id === 'string') : []);\n}\n\n/**\n * Persist the disabled/enabled state of a single package. Best-effort: failures\n * are surfaced to the caller so the HTTP layer can log, but disabling already\n * took effect in-memory regardless.\n */\nexport function setPackageDisabled(environmentId: string | undefined, packageId: string, disabled: boolean): void {\n const ids = loadDisabledPackageIds(environmentId);\n if (disabled) ids.add(packageId);\n else ids.delete(packageId);\n writeState(environmentId, { disabled: Array.from(ids).sort() });\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * # QuickJS-backed ScriptRunner\n *\n * Implements `ScriptRunner` using `quickjs-emscripten` (pure-WASM, edge-safe).\n *\n * Responsibilities:\n * - L1 ExpressionBody — evaluated as a `return (<source>)` snippet.\n * - L2 ScriptBody — wrapped in `(async (ctx) => { <source> })(ctx)` (hooks)\n * or `(async (input, ctx) => { <source> })(input, ctx)` (actions).\n * - Hard timeout via QuickJS interrupt handler.\n * - Capability gating — host-side `ctx.api`, `ctx.crypto`, `ctx.log` are only\n * wired into the VM if the body declares the matching capability.\n * - Structured marshalling — JSON-serialisable values cross the VM boundary.\n * Functions are exposed as host-resident proxies (the script calls\n * `ctx.api.object('foo').count(...)` and the host method runs in node).\n *\n * Trade-offs:\n * - Per-invocation overhead is dominated by VM creation. We pool runtimes per\n * `(origin.kind, capabilities-set)` to amortise startup. Pool size is bounded\n * by `maxPooled` (default 8); evicted runtimes are disposed.\n * - Memory caps are advisory under quickjs (engine has no hard MB cap); the\n * runner uses `setMemoryLimit(memoryMb * 1MB)` which is best-effort.\n */\n\nimport {\n newAsyncContext,\n type QuickJSAsyncContext,\n type QuickJSHandle,\n} from 'quickjs-emscripten';\nimport type { HookBody, ScriptBody, ExpressionBody, HookBodyCapability } from '@objectstack/spec/data';\nimport type {\n ScriptContext,\n ScriptOrigin,\n ScriptResult,\n ScriptRunOptions,\n ScriptRunner,\n} from './script-runner.js';\n\nconst DEFAULT_HOOK_TIMEOUT_MS = 250;\nconst DEFAULT_ACTION_TIMEOUT_MS = 5000;\nconst DEFAULT_MEMORY_MB = 32;\n\nexport interface QuickJSScriptRunnerOptions {\n /** Default per-invocation timeout for hooks (ms). */\n hookTimeoutMs?: number;\n /** Default per-invocation timeout for actions (ms). */\n actionTimeoutMs?: number;\n /** Default memory cap in MB. */\n memoryMb?: number;\n}\n\nexport class QuickJSScriptRunner implements ScriptRunner {\n private opts: Required<QuickJSScriptRunnerOptions>;\n\n constructor(opts: QuickJSScriptRunnerOptions = {}) {\n this.opts = {\n hookTimeoutMs: opts.hookTimeoutMs ?? DEFAULT_HOOK_TIMEOUT_MS,\n actionTimeoutMs: opts.actionTimeoutMs ?? DEFAULT_ACTION_TIMEOUT_MS,\n memoryMb: opts.memoryMb ?? DEFAULT_MEMORY_MB,\n };\n }\n\n async evalExpression(\n body: ExpressionBody,\n ctx: ScriptContext,\n opts: ScriptRunOptions,\n ): Promise<ScriptResult> {\n return this.execute({\n isExpression: true,\n source: body.source,\n capabilities: [],\n timeoutMs: this.resolveTimeout(opts, undefined),\n memoryMb: this.opts.memoryMb,\n ctx,\n origin: opts.origin,\n });\n }\n\n async runScript(\n body: ScriptBody,\n ctx: ScriptContext,\n opts: ScriptRunOptions,\n ): Promise<ScriptResult> {\n return this.execute({\n isExpression: false,\n source: body.source,\n capabilities: body.capabilities,\n timeoutMs: this.resolveTimeout(opts, body.timeoutMs),\n memoryMb: body.memoryMb ?? this.opts.memoryMb,\n ctx,\n origin: opts.origin,\n });\n }\n\n run(body: HookBody, ctx: ScriptContext, opts: ScriptRunOptions): Promise<ScriptResult> {\n return body.language === 'expression'\n ? this.evalExpression(body, ctx, opts)\n : this.runScript(body, ctx, opts);\n }\n\n async dispose(): Promise<void> {\n /* no-op — runtimes are per-invocation in v1 */\n }\n\n /** Pick the smallest of body / opts / engine-default. */\n private resolveTimeout(opts: ScriptRunOptions, bodyTimeoutMs: number | undefined): number {\n const def = opts.origin.kind === 'hook' ? this.opts.hookTimeoutMs : this.opts.actionTimeoutMs;\n return Math.min(...[def, opts.timeoutMs, bodyTimeoutMs].filter((n): n is number => typeof n === 'number'));\n }\n\n private async execute(args: {\n isExpression: boolean;\n source: string;\n capabilities: HookBodyCapability[];\n timeoutMs: number;\n memoryMb: number;\n ctx: ScriptContext;\n origin: ScriptOrigin;\n }): Promise<ScriptResult> {\n // Each invocation gets its own WebAssembly module via newAsyncContext().\n // This is the canonical \"per-invocation isolate\" model and avoids the\n // shared-runtime HostRef double-free issues we hit with a singleton\n // QuickJSAsyncWASMModule when contexts are disposed concurrently.\n const vm = await newAsyncContext();\n const runtime = vm.runtime;\n runtime.setMemoryLimit(args.memoryMb * 1024 * 1024);\n runtime.setMaxStackSize(512 * 1024);\n\n const start = Date.now();\n const deadline = start + args.timeoutMs;\n runtime.setInterruptHandler(() => Date.now() > deadline);\n\n try {\n this.installCtx(vm, args.ctx, new Set(args.capabilities), args.origin);\n\n // L1 expressions are pure-sync: evaluate and read __result.\n if (args.isExpression) {\n const wrapped = `globalThis.__result = JSON.stringify((function(){ return (${args.source}); })());`;\n const result = vm.evalCode(wrapped);\n if (result.error) {\n const err = vm.dump(result.error);\n result.error.dispose();\n throw new SandboxError(`${args.origin.kind} '${args.origin.name}' threw: ${formatErr(err)}`);\n }\n result.value.dispose();\n const resH = vm.getProp(vm.global, '__result');\n const resStr = vm.dump(resH);\n resH.dispose();\n const value = resStr === undefined || resStr === null || resStr === 'null'\n ? undefined\n : safeJsonParse(resStr);\n return { value, durationMs: Date.now() - start };\n }\n\n // L2 scripts: wrap as async IIFE and use side-channel + asyncified pump.\n // Each pump iteration:\n // 1. yield to the host event loop (lets asyncified host calls resolve)\n // 2. drain QuickJS pending jobs (advances the .then chain)\n // 3. read __result/__error from the VM\n const wrapped = args.origin.kind === 'hook'\n ? `globalThis.__result = undefined; globalThis.__error = undefined;\n (async (ctx) => { ${args.source} })(globalThis.__ctx).then(\n function(v){ globalThis.__result = JSON.stringify(v === undefined ? null : v); },\n function(e){ globalThis.__error = (e && e.message) ? (e.name + ': ' + e.message) : String(e); }\n );`\n : `globalThis.__result = undefined; globalThis.__error = undefined;\n (async (input, ctx) => { ${args.source} })(globalThis.__input, globalThis.__ctx).then(\n function(v){ globalThis.__result = JSON.stringify(v === undefined ? null : v); },\n function(e){ globalThis.__error = (e && e.message) ? (e.name + ': ' + e.message) : String(e); }\n );`;\n\n const evalRes = await vm.evalCodeAsync(wrapped);\n if (evalRes.error) {\n const err = vm.dump(evalRes.error);\n evalRes.error.dispose();\n throw new SandboxError(`${args.origin.kind} '${args.origin.name}' threw: ${formatErr(err)}`);\n }\n evalRes.value.dispose();\n\n let pumps = 0;\n while (pumps < 1000) {\n // Yield to host event loop so any in-flight asyncified host promises resolve.\n await new Promise<void>((resolve) => setImmediate(resolve));\n\n const pending = runtime.executePendingJobs();\n if (pending.error) {\n const err = vm.dump(pending.error);\n pending.error.dispose();\n throw new SandboxError(`${args.origin.kind} '${args.origin.name}' threw: ${formatErr(err)}`);\n }\n\n const errH = vm.getProp(vm.global, '__error');\n const errStr = vm.dump(errH);\n errH.dispose();\n if (errStr) {\n throw new SandboxError(`${args.origin.kind} '${args.origin.name}' threw: ${errStr}`);\n }\n\n const resH = vm.getProp(vm.global, '__result');\n const resStr = vm.dump(resH);\n resH.dispose();\n if (resStr !== undefined && resStr !== null) {\n const value = resStr === 'null' ? undefined : safeJsonParse(resStr);\n // Capture mutated ctx.input so the host can write through.\n const mutatedInput = readCtxInputJson(vm);\n return { value, mutatedInput, durationMs: Date.now() - start };\n }\n\n if (Date.now() > deadline) {\n throw new SandboxError(\n `${args.origin.kind} '${args.origin.name}' exceeded timeout of ${args.timeoutMs}ms`,\n );\n }\n pumps++;\n }\n throw new SandboxError(\n `${args.origin.kind} '${args.origin.name}' did not resolve after ${pumps} pump iterations`,\n );\n } finally {\n // newAsyncContext() owns its WASM module; disposing the context disposes\n // the runtime + module together.\n vm.dispose();\n }\n }\n\n /**\n * Install ctx onto the VM's globalThis. Each capability is wired in only if\n * the body declared it; missing methods throw at call-time inside the VM\n * with a clear diagnostic.\n *\n * Host API methods are installed via {@link QuickJSAsyncContext.newAsyncifiedFunction}\n * so they may return Promises (real ObjectQL `find/count/insert/...` are async).\n */\n private installCtx(\n vm: QuickJSAsyncContext,\n ctx: ScriptContext,\n caps: Set<HookBodyCapability>,\n origin: ScriptOrigin,\n ): void {\n setGlobalJson(vm, '__input', ctx.input);\n setGlobalJson(vm, '__previous', ctx.previous);\n\n const ctxObj = vm.newObject();\n setObjectJson(vm, ctxObj, 'input', ctx.input);\n setObjectJson(vm, ctxObj, 'previous', ctx.previous);\n setObjectJson(vm, ctxObj, 'user', ctx.user);\n setObjectJson(vm, ctxObj, 'session', ctx.session);\n if (typeof ctx.event === 'string') {\n const evH = vm.newString(ctx.event);\n vm.setProp(ctxObj, 'event', evH);\n evH.dispose();\n }\n if (typeof ctx.object === 'string') {\n const obH = vm.newString(ctx.object);\n vm.setProp(ctxObj, 'object', obH);\n obH.dispose();\n }\n if (typeof ctx.recordId === 'string') {\n const idH = vm.newString(ctx.recordId);\n vm.setProp(ctxObj, 'recordId', idH);\n idH.dispose();\n }\n if (ctx.record !== undefined) {\n setObjectJson(vm, ctxObj, 'record', ctx.record);\n }\n if (ctx.result !== undefined) {\n setObjectJson(vm, ctxObj, 'result', ctx.result);\n }\n\n const apiObj = vm.newObject();\n const objectFn = vm.newFunction('object', (nameH) => {\n const objectName = vm.getString(nameH);\n const wrap = vm.newObject();\n const READ = ['find', 'findOne', 'count', 'aggregate'] as const;\n const WRITE = ['insert', 'update', 'delete', 'updateMany', 'deleteMany', 'upsert'] as const;\n for (const m of READ) installApiMethod(vm, wrap, m, objectName, ctx, caps, 'api.read', origin);\n for (const m of WRITE) installApiMethod(vm, wrap, m, objectName, ctx, caps, 'api.write', origin);\n return wrap;\n });\n vm.setProp(apiObj, 'object', objectFn);\n objectFn.dispose();\n vm.setProp(ctxObj, 'api', apiObj);\n apiObj.dispose();\n\n const logObj = vm.newObject();\n for (const level of ['info', 'warn', 'error'] as const) {\n const fn = vm.newFunction(level, (msgH, dataH) => {\n if (!caps.has('log')) {\n throw new SandboxError(`capability 'log' not granted to ${origin.kind} '${origin.name}'`);\n }\n const msg = vm.getString(msgH);\n const data = dataH ? safeJsonParse(vm.getString(dataH)) : undefined;\n ctx.log?.[level]?.(msg, data);\n return vm.undefined;\n });\n vm.setProp(logObj, level, fn);\n fn.dispose();\n }\n vm.setProp(ctxObj, 'log', logObj);\n logObj.dispose();\n\n const cryptoObj = vm.newObject();\n const uuidFn = vm.newFunction('randomUUID', () => {\n if (!caps.has('crypto.uuid')) {\n throw new SandboxError(`capability 'crypto.uuid' not granted to ${origin.kind} '${origin.name}'`);\n }\n const v = ctx.crypto?.randomUUID?.() ?? cryptoRandomUUID();\n return vm.newString(v);\n });\n vm.setProp(cryptoObj, 'randomUUID', uuidFn);\n uuidFn.dispose();\n vm.setProp(ctxObj, 'crypto', cryptoObj);\n cryptoObj.dispose();\n\n vm.setProp(vm.global, '__ctx', ctxObj);\n ctxObj.dispose();\n }\n}\n\n/**\n * Asyncified host-bound API method.\n *\n * Awaits Promise return values from the host implementation and marshals the\n * resolved value back into the VM. Capability check happens at call time and\n * surfaces inside the VM as a thrown error with a clear diagnostic.\n */\nfunction installApiMethod(\n vm: QuickJSAsyncContext,\n parent: QuickJSHandle,\n method: string,\n objectName: string,\n ctx: ScriptContext,\n caps: Set<HookBodyCapability>,\n required: HookBodyCapability,\n origin: ScriptOrigin,\n): void {\n const fn = vm.newAsyncifiedFunction(method, async (...argHandles) => {\n if (!caps.has(required)) {\n throw new SandboxError(\n `capability '${required}' not granted to ${origin.kind} '${origin.name}' (called ctx.api.object('${objectName}').${method})`,\n );\n }\n const apiAny = ctx.api as Record<string, unknown> | undefined;\n if (!apiAny || typeof apiAny.object !== 'function') {\n throw new SandboxError(`ctx.api unavailable in ${origin.kind} '${origin.name}'`);\n }\n const args = argHandles.map((h) => vm.dump(h));\n const proxy = (apiAny.object as (n: string) => Record<string, unknown>)(objectName);\n const m = proxy[method] as ((...a: unknown[]) => unknown) | undefined;\n if (typeof m !== 'function') {\n throw new SandboxError(`ctx.api.object('${objectName}').${method} not implemented`);\n }\n const ret = await Promise.resolve(m.apply(proxy, args));\n return jsonToHandle(vm, ret);\n });\n vm.setProp(parent, method, fn);\n fn.dispose();\n}\n\n/** Marshal a host JSON-serializable value into a QuickJS handle. */\nfunction jsonToHandle(vm: QuickJSAsyncContext, v: unknown): QuickJSHandle {\n const json = JSON.stringify(v ?? null);\n const r = vm.evalCode(`(${json})`);\n if (r.error) {\n const msg = vm.dump(r.error);\n r.error.dispose();\n throw new SandboxError(`failed to marshal host value: ${formatErr(msg)}`);\n }\n return r.value;\n}\n\nfunction setGlobalJson(vm: QuickJSAsyncContext, name: string, v: unknown): void {\n const json = JSON.stringify(v ?? null);\n const result = vm.evalCode(`(${json})`);\n if (result.error) {\n result.error.dispose();\n return;\n }\n vm.setProp(vm.global, name, result.value);\n result.value.dispose();\n}\n\nfunction setObjectJson(vm: QuickJSAsyncContext, parent: QuickJSHandle, key: string, v: unknown): void {\n const json = JSON.stringify(v ?? null);\n const result = vm.evalCode(`(${json})`);\n if (result.error) {\n result.error.dispose();\n vm.setProp(parent, key, vm.null);\n return;\n }\n vm.setProp(parent, key, result.value);\n result.value.dispose();\n}\n\n/**\n * After the script has settled, dump `globalThis.__ctx.input` so the host can\n * write through any direct property mutations the script performed (e.g.\n * `ctx.input.account_number = 'ABC'`).\n *\n * Returns `undefined` if the read fails for any reason — callers fall back to\n * the script's return value in that case.\n */\nfunction readCtxInputJson(vm: QuickJSAsyncContext): Record<string, unknown> | undefined {\n try {\n const r = vm.evalCode(`JSON.stringify(globalThis.__ctx && globalThis.__ctx.input || null)`);\n if (r.error) {\n r.error.dispose();\n return undefined;\n }\n const s = vm.dump(r.value);\n r.value.dispose();\n if (typeof s !== 'string' || s === 'null') return undefined;\n const parsed = safeJsonParse(s);\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction safeJsonParse(s: string | undefined): unknown {\n if (s === undefined || s === '') return undefined;\n try {\n return JSON.parse(s);\n } catch {\n return s;\n }\n}\n\nfunction cryptoRandomUUID(): string {\n if (typeof globalThis.crypto?.randomUUID === 'function') return globalThis.crypto.randomUUID();\n // RFC 4122 v4 fallback\n const r = () => Math.floor(Math.random() * 0x100000000).toString(16).padStart(8, '0');\n return `${r()}-${r().slice(0, 4)}-4${r().slice(0, 3)}-${r().slice(0, 4)}-${r()}${r().slice(0, 4)}`;\n}\n\nfunction formatErr(err: unknown): string {\n if (err && typeof err === 'object') {\n const o = err as { message?: string; name?: string; stack?: string };\n if (o.message) return `${o.name ?? 'Error'}: ${o.message}`;\n return JSON.stringify(err);\n }\n return String(err);\n}\n\nexport class SandboxError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'SandboxError';\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Hook & Action Body Runner Factory\n *\n * Bridges the metadata-only `Hook.body` / `Action.body` discriminated union\n * (defined in `@objectstack/spec/data/hook-body.zod`) into an executable\n * handler registered on the ObjectQL engine.\n *\n * The runtime owns this bridge — `objectql` itself never imports the\n * sandbox engine, so it can stay light enough to embed in tooling and\n * tests. `AppPlugin` constructs one factory per bundle bind and passes it\n * through `bindHooksToEngine({ bodyRunner })` for hooks, and walks the\n * bundle actions to register them via `engine.registerAction`.\n *\n * Per-invocation flow when a triggered hook fires:\n * 1. ObjectQL calls the wrapped handler with its native `(ctx)` arg.\n * 2. We adapt that engine-context into the sandbox `ScriptContext`\n * shape and proxy `ctx.api.object(...)` to the running ObjectQL\n * proxy bound to the current organization/user.\n * 3. `ScriptRunner.runScript` evaluates the body inside QuickJS with\n * the declared capabilities + timeout.\n * 4. After settle, we write back two kinds of mutations to the host\n * `ctx.input`:\n * a. `result.mutatedInput` — a snapshot of `ctx.input` taken inside\n * the VM, used to propagate direct property writes such as\n * `ctx.input.account_number = 'ABC'`.\n * b. `result.value` — if the script returned an object, it is\n * shallow-merged on top of `mutatedInput` as an explicit patch.\n * Writes go through `Object.assign`, which means the host engine's\n * flat-record Proxy (installed by `wrapDeclarativeHook`) sees them\n * via its set trap.\n */\n\nimport type { Hook } from '@objectstack/spec/data';\nimport { HookBodySchema } from '@objectstack/spec/data';\nimport type { ScriptRunner, ScriptContext, ScriptResult } from './script-runner.js';\n\ninterface FactoryOptions {\n ql: any;\n appId: string;\n logger?: any;\n}\n\nexport function hookBodyRunnerFactory(\n runner: ScriptRunner,\n opts: FactoryOptions,\n): (hook: Hook) => ((engineCtx: any) => Promise<void>) | undefined {\n return (hook: Hook) => {\n const raw = (hook as any).body;\n if (!raw) return undefined;\n\n const parsed = HookBodySchema.safeParse(raw);\n if (!parsed.success) {\n opts.logger?.warn?.('[BodyRunner] invalid hook.body shape', {\n appId: opts.appId,\n hook: hook.name,\n issues: parsed.error.issues.slice(0, 3),\n });\n return undefined;\n }\n const body = parsed.data;\n\n return async function boundBodyHandler(engineCtx: any): Promise<void> {\n const sandboxCtx = buildSandboxContext(engineCtx, opts.ql);\n try {\n opts.logger?.debug?.('[BodyRunner] hook fired', { appId: opts.appId, hook: hook.name });\n const result = await runner.run(body, sandboxCtx, {\n origin: {\n kind: 'hook',\n name: hook.name,\n object: typeof (hook as any).object === 'string' ? (hook as any).object : undefined,\n },\n timeoutMs: (body as any).timeoutMs ?? 250,\n });\n applyMutationsToInput(engineCtx, result);\n } catch (err: any) {\n opts.logger?.error?.('[BodyRunner] sandboxed hook threw', err, {\n appId: opts.appId,\n hook: hook.name,\n });\n throw err;\n }\n };\n };\n}\n\n/**\n * Action body runner factory.\n *\n * Returns a handler with the shape ObjectQL's `executeAction` expects:\n * `(actionCtx) => Promise<unknown>`. The action's return value bubbles up\n * to the HTTP dispatcher which JSON-serialises it back to the caller.\n */\nexport function actionBodyRunnerFactory(\n runner: ScriptRunner,\n opts: FactoryOptions,\n): (action: { name: string; body?: unknown; object?: string; timeoutMs?: number }) =>\n | ((actionCtx: any) => Promise<unknown>)\n | undefined {\n return (action) => {\n const raw = action.body;\n if (!raw) return undefined;\n\n const parsed = HookBodySchema.safeParse(raw);\n if (!parsed.success) {\n opts.logger?.warn?.('[BodyRunner] invalid action.body shape', {\n appId: opts.appId,\n action: action.name,\n issues: parsed.error.issues.slice(0, 3),\n });\n return undefined;\n }\n const body = parsed.data;\n\n return async function boundActionHandler(actionCtx: any): Promise<unknown> {\n const sandboxCtx = buildActionSandboxContext(actionCtx, opts.ql);\n try {\n opts.logger?.debug?.('[BodyRunner] action fired', {\n appId: opts.appId,\n action: action.name,\n object: action.object,\n });\n const result = await runner.run(body, sandboxCtx, {\n origin: { kind: 'action', name: action.name, object: action.object },\n timeoutMs: (body as any).timeoutMs ?? action.timeoutMs ?? 5000,\n });\n return result.value;\n } catch (err: any) {\n opts.logger?.error?.('[BodyRunner] sandboxed action threw', err, {\n appId: opts.appId,\n action: action.name,\n });\n throw err;\n }\n };\n };\n}\n\nfunction applyMutationsToInput(engineCtx: any, result: ScriptResult): void {\n const target = engineCtx?.input;\n if (!target || typeof target !== 'object') return;\n if (result.mutatedInput && typeof result.mutatedInput === 'object') {\n Object.assign(target, result.mutatedInput);\n }\n if (\n result.value &&\n typeof result.value === 'object' &&\n !Array.isArray(result.value)\n ) {\n Object.assign(target, result.value);\n }\n}\n\nfunction buildEngineRepoFacade(ql: any, objectName: string) {\n // Minimal repository surface that proxies to the raw engine.\n // Actions execute as the system user (no user context at HTTP boundary\n // beyond `actionCtx.user`); ObjectQL's permission middleware will still\n // gate writes via the engine's standard insert/update path.\n return {\n async find(opts?: any) { return ql.find(objectName, opts); },\n async findOne(opts?: any) {\n const rows = await ql.find(objectName, opts);\n return Array.isArray(rows) ? rows[0] ?? null : null;\n },\n async count(opts?: any) {\n if (typeof ql.count === 'function') return ql.count(objectName, opts);\n const rows = await ql.find(objectName, opts);\n return Array.isArray(rows) ? rows.length : 0;\n },\n async insert(data: any) { return ql.insert(objectName, data); },\n async update(data: any, opts?: any) { return ql.update(objectName, data, opts); },\n async upsert(data: any, opts?: any) {\n if (typeof ql.upsert === 'function') return ql.upsert(objectName, data, opts);\n return ql.insert(objectName, data);\n },\n async delete(opts?: any) { return ql.delete(objectName, opts); },\n };\n}\n\nfunction buildSandboxApi(engineCtx: any, ql: any, errLabel: string) {\n const engineApi = engineCtx?.api;\n if (engineApi && typeof engineApi.object === 'function') return engineApi;\n return {\n object: (objectName: string) => {\n if (!ql) throw new Error(`ObjectQL engine unavailable to ${errLabel}`);\n // Prefer the engine's own ScopedContext-based `.object()` when\n // present; otherwise synthesize a minimal repo facade against the\n // engine's CRUD primitives (so the body can call .insert/.find/etc).\n if (typeof ql.object === 'function') {\n try { return ql.object(objectName); } catch { /* fall through */ }\n }\n return buildEngineRepoFacade(ql, objectName);\n },\n };\n}\n\nfunction buildSandboxContext(engineCtx: any, ql: any): ScriptContext {\n const inputSnapshot = unwrapProxyToPlain(engineCtx?.input ?? engineCtx?.doc);\n const previousRaw = engineCtx?.previous ?? engineCtx?.previousDoc;\n return {\n input: inputSnapshot ?? {},\n // Preserve `undefined` for `previous` on insert events so hooks can\n // reliably distinguish create (`!ctx.previous`) from update/delete.\n previous: unwrapProxyToPlain(previousRaw),\n user: engineCtx?.user ?? engineCtx?.session?.user,\n session: engineCtx?.session,\n event: typeof engineCtx?.event === 'string' ? engineCtx.event : undefined,\n object: typeof engineCtx?.object === 'string' ? engineCtx.object : undefined,\n result: engineCtx?.result,\n api: buildSandboxApi(engineCtx, ql, 'hook body'),\n log: engineCtx?.logger,\n crypto: globalThis.crypto,\n };\n}\n\nfunction buildActionSandboxContext(actionCtx: any, ql: any): ScriptContext {\n // Action ctx convention (mirrors http-dispatcher.ts):\n // { record, params, recordId, user, session, engine, services, ... }\n // The script signature is `(input, ctx)` — input gets `params`, ctx gets\n // the full action context.\n const recordId =\n typeof actionCtx?.recordId === 'string'\n ? actionCtx.recordId\n : typeof actionCtx?.record?.id === 'string'\n ? actionCtx.record.id\n : undefined;\n return {\n input: unwrapProxyToPlain(actionCtx?.params ?? {}),\n previous: undefined,\n user: actionCtx?.user ?? actionCtx?.session?.user,\n session: actionCtx?.session,\n object: typeof actionCtx?.object === 'string' ? actionCtx.object : undefined,\n recordId,\n record: unwrapProxyToPlain(actionCtx?.record),\n api: buildSandboxApi(actionCtx, ql, 'action body'),\n log: actionCtx?.logger,\n crypto: globalThis.crypto,\n };\n}\n\n/**\n * Convert a Proxy-wrapped record into a plain object so it round-trips through\n * JSON cleanly. `Object.fromEntries(Object.entries(p))` triggers the proxy's\n * ownKeys + get traps, materialising every visible field.\n */\nfunction unwrapProxyToPlain(v: unknown): Record<string, unknown> | undefined {\n if (v === undefined || v === null) return undefined;\n if (typeof v !== 'object') return undefined;\n if (Array.isArray(v)) return undefined;\n try {\n return Object.fromEntries(Object.entries(v as Record<string, unknown>));\n } catch {\n return undefined;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { Plugin, PluginContext } from '@objectstack/core';\nimport { readEnvWithDeprecation } from '@objectstack/types';\nimport { SeedLoaderService } from './seed-loader.js';\nimport { loadDisabledPackageIds } from './package-state-store.js';\nimport type { IMetadataService, II18nService } from '@objectstack/spec/contracts';\nimport { SystemUserId } from '@objectstack/spec/system';\nimport { QuickJSScriptRunner } from './sandbox/quickjs-runner.js';\nimport { hookBodyRunnerFactory, actionBodyRunnerFactory } from './sandbox/body-runner.js';\n\n/**\n * Optional per-project context attached when AppPlugin is instantiated by the\n * project kernel factory. Required for the `app:registered` / `app:unregistered`\n * hooks that drive the org-scoped `sys_app` catalog. Standalone (single-tenant)\n * usages may omit this — no catalog hooks are emitted in that case.\n */\nexport interface AppPluginProjectContext {\n environmentId: string;\n organizationId: string;\n projectName?: string;\n /** When the app comes from a package installation, the source package id. */\n packageId?: string;\n /** Defaults to 'package' when packageId is set, otherwise 'user'. */\n source?: 'package' | 'user';\n}\n\n/**\n * AppPlugin\n * \n * Adapts a generic App Bundle (Manifest + Runtime Code) into a Kernel Plugin.\n * \n * Responsibilities:\n * 1. Register App Manifest as a service (for ObjectQL discovery)\n * 2. Execute Runtime `onEnable` hook (for code logic)\n * 3. Auto-load i18n translation bundles into the kernel's i18n service\n */\nexport class AppPlugin implements Plugin {\n name: string;\n type = 'app';\n version?: string;\n \n private bundle: any;\n private projectContext?: AppPluginProjectContext;\n /** When true, init/start become no-ops — env has no app payload. */\n private readonly empty: boolean = false;\n\n constructor(bundle: any, projectContext?: AppPluginProjectContext) {\n this.bundle = bundle;\n this.projectContext = projectContext;\n // Support both direct manifest (legacy) and Stack Definition (nested manifest)\n const sys = bundle?.manifest || bundle;\n const appId = sys?.id || sys?.name;\n\n if (!appId) {\n // No app id at all. Two scenarios:\n // (a) Empty environment — the artifact only ships the bootstrap\n // envelope ({ manifest: { plugins, drivers, engines }, functions: [] })\n // with no app categories. We must NOT crash kernel boot\n // here, otherwise every brand-new env returns 500.\n // (b) Malformed envelope where an app payload exists but the\n // caller forgot to pass `manifest`. We throw loudly with\n // diagnostics so the bug surfaces immediately.\n // App-category keys that indicate \"this bundle was supposed to\n // register an app\". `manifest`/`functions` are envelope-level\n // wrappers and don't count.\n const APP_CATEGORY_KEYS = [\n 'objects', 'views', 'apps', 'pages', 'dashboards', 'reports',\n 'flows', 'workflows', 'triggers', 'agents', 'tools', 'skills',\n 'actions', 'permissions', 'roles', 'profiles', 'translations',\n 'sharingRules', 'ragPipelines', 'data', 'emailTemplates',\n ];\n const hasAppPayload = APP_CATEGORY_KEYS.some((k) => {\n const v = (bundle && bundle[k]) ?? (sys && sys[k]);\n return Array.isArray(v) && v.length > 0;\n });\n\n if (!hasAppPayload) {\n // Empty env — degrade to a no-op plugin so kernel boot\n // succeeds. Auth / data routes will still work; there's\n // simply nothing to register.\n this.empty = true;\n const envSlug = projectContext?.environmentId\n ? projectContext.environmentId.slice(0, 8)\n : 'empty';\n this.name = `plugin.app.empty-${envSlug}`;\n return;\n }\n\n // Has app payload but no id — genuine malformed envelope.\n const bundleKeys = bundle && typeof bundle === 'object'\n ? Object.keys(bundle).slice(0, 20).join(',')\n : typeof bundle;\n const sysKeys = sys && typeof sys === 'object'\n ? Object.keys(sys).slice(0, 20).join(',')\n : typeof sys;\n const ctxHint = projectContext\n ? ` projectContext=${JSON.stringify({\n environmentId: projectContext.environmentId,\n packageId: projectContext.packageId,\n source: projectContext.source,\n })}`\n : '';\n throw new Error(\n `[AppPlugin] bundle has app payload but no manifest.id / manifest.name — `\n + `cannot register as a plugin. bundleKeys=[${bundleKeys}] `\n + `sysKeys=[${sysKeys}]${ctxHint}`,\n );\n }\n\n this.name = `plugin.app.${appId}`;\n this.version = sys?.version;\n }\n\n init = async (ctx: PluginContext) => {\n if (this.empty) {\n ctx.logger.debug('[AppPlugin] empty env — no app payload, skipping init', {\n pluginName: this.name,\n });\n return;\n }\n const sys = this.bundle.manifest || this.bundle;\n const appId = sys.id || sys.name;\n\n ctx.logger.info('Registering App Service', { \n appId, \n pluginName: this.name,\n version: this.version \n });\n \n // Register the app manifest directly via the manifest service.\n // This immediately decomposes the manifest into SchemaRegistry entries.\n const servicePayload = this.bundle.manifest\n ? { ...this.bundle.manifest, ...this.bundle }\n : this.bundle;\n\n console.warn(\n `[AppPlugin:init] appId=${appId} keys=${Object.keys(servicePayload).join(',')} flows=${Array.isArray((servicePayload as any).flows) ? (servicePayload as any).flows.length : 'n/a'}`,\n );\n\n // Seed persisted package disable-state into the registry BEFORE the\n // manifest is decomposed, so disabled packages are installed disabled\n // and stay hidden after restart. Honors every later registration path\n // (boot artifact, marketplace rehydrate, import) via the registry's\n // initial-disabled set. Best-effort — never block boot on this.\n try {\n const ql = ctx.getService<{ registry?: { setInitialDisabledPackageIds?: (ids: Iterable<string>) => void } }>('objectql');\n const setter = ql?.registry?.setInitialDisabledPackageIds;\n if (typeof setter === 'function') {\n const disabled = loadDisabledPackageIds(this.projectContext?.environmentId);\n if (disabled.size > 0) {\n setter.call(ql!.registry, disabled);\n ctx.logger.info('[AppPlugin] seeded persisted disabled packages', {\n environmentId: this.projectContext?.environmentId,\n disabled: Array.from(disabled),\n });\n }\n }\n } catch (err) {\n ctx.logger.warn('[AppPlugin] failed to seed persisted package state', {\n error: (err as Error)?.message ?? String(err),\n });\n }\n\n ctx.getService<{ register(m: any): void }>('manifest').register(servicePayload);\n }\n\n start = async (ctx: PluginContext) => {\n if (this.empty) {\n ctx.logger.debug('[AppPlugin] empty env — no app payload, skipping start', {\n pluginName: this.name,\n });\n return;\n }\n const sys = this.bundle.manifest || this.bundle;\n const appId = sys.id || sys.name;\n \n // Execute Runtime Step\n // Retrieve ObjectQL engine from services\n // ctx.getService throws when a service is not registered, so we\n // must use try/catch instead of a null-check.\n let ql: any;\n try {\n ql = ctx.getService('objectql');\n } catch {\n // Service not registered — handled below\n }\n\n if (!ql) {\n ctx.logger.warn('ObjectQL engine service not found', { \n appName: this.name,\n appId \n });\n return;\n }\n\n ctx.logger.debug('Retrieved ObjectQL engine service', { appId });\n\n // Configure datasourceMapping if provided in the stack definition\n if (this.bundle.datasourceMapping && Array.isArray(this.bundle.datasourceMapping)) {\n ctx.logger.info('Configuring datasource mapping rules', {\n appId,\n ruleCount: this.bundle.datasourceMapping.length\n });\n ql.setDatasourceMapping(this.bundle.datasourceMapping);\n }\n\n // Surface code-defined datasources (ADR-0015 Addendum) in the metadata\n // registry so the datasource-admin list returns them alongside any\n // UI-created (`origin:'runtime'`) ones. These are GitOps-managed\n // (declared in `*.datasource.ts`), so they are registered IN MEMORY\n // ONLY — never persisted to the runtime DB store — and stamped\n // `origin:'code'` so the admin service enforces them as read-only.\n // The engine already indexed them for the write gate via registerApp().\n try {\n const dsDefs = this.bundle.datasources;\n const dsList = Array.isArray(dsDefs)\n ? dsDefs\n : dsDefs && typeof dsDefs === 'object'\n ? Object.entries(dsDefs).map(([name, def]) => ({ name, ...(def as any) }))\n : [];\n if (dsList.length > 0) {\n const metadata = ctx.getService('metadata') as\n | { registerInMemory?: (t: string, n: string, d: unknown) => void }\n | undefined;\n if (typeof metadata?.registerInMemory === 'function') {\n for (const ds of dsList) {\n if (!ds?.name) continue;\n metadata.registerInMemory('datasource', ds.name, { ...ds, origin: 'code' });\n }\n ctx.logger.info('Registered code-defined datasources in metadata registry', {\n appId,\n count: dsList.length,\n });\n }\n }\n } catch (err) {\n ctx.logger.warn('[AppPlugin] failed to register code-defined datasources', {\n error: (err as Error)?.message ?? String(err),\n });\n }\n\n // Resolve the runtime hook owner. Modules that declare both a\n // `default` (defineStack(...)) export and a named `onEnable` export\n // hide the named export from `bundle.default`, so we fall back to the\n // top-level bundle when the default doesn't carry the hook.\n const stackBundle = this.bundle.default || this.bundle;\n const runtime: any = (stackBundle && typeof stackBundle.onEnable === 'function')\n ? stackBundle\n : this.bundle;\n\n if (runtime && typeof runtime.onEnable === 'function') {\n ctx.logger.info('Executing runtime.onEnable', { \n appName: this.name,\n appId \n });\n \n // Construct the Host Context (mirroring old ObjectQL.use logic)\n const hostContext = {\n ...ctx,\n ql,\n logger: ctx.logger,\n drivers: {\n register: (driver: any) => {\n ctx.logger.debug('Registering driver via app runtime', { \n driverName: driver.name,\n appId \n });\n ql.registerDriver(driver);\n }\n },\n };\n \n await runtime.onEnable(hostContext);\n ctx.logger.debug('Runtime.onEnable completed', { appId });\n } else {\n ctx.logger.debug('No runtime.onEnable function found', { appId });\n }\n\n // ── Auto-bind declarative Hook metadata ─────────────────────────\n // Hooks declared via `defineStack({ hooks })` (or attached to the\n // bundle by other tooling) are wired into the ObjectQL execution\n // pipeline here, with no boilerplate from user code. Inline\n // function handlers are resolved directly; string-named handlers\n // are looked up in `bundle.functions` (also auto-registered) or in\n // any function previously registered on the engine.\n //\n // Runs AFTER `runtime.onEnable` so user code may still\n // imperatively register additional hooks/functions for advanced\n // cases — both will coexist on the engine.\n try {\n const hooks = collectBundleHooks(this.bundle);\n const functions = collectBundleFunctions(this.bundle);\n if (hooks.length > 0 || Object.keys(functions).length > 0) {\n if (typeof ql.bindHooks === 'function') {\n ql.bindHooks(hooks, {\n packageId: `app:${appId}`,\n functions,\n bodyRunner: hookBodyRunnerFactory(new QuickJSScriptRunner(), {\n ql,\n logger: ctx.logger,\n appId,\n }),\n });\n ctx.logger.info('[AppPlugin] Bound declarative hooks', {\n appId,\n hookCount: hooks.length,\n functionCount: Object.keys(functions).length,\n });\n } else {\n ctx.logger.warn('[AppPlugin] ql.bindHooks unavailable; declarative hooks ignored', {\n appId,\n hookCount: hooks.length,\n });\n }\n }\n } catch (err: any) {\n ctx.logger.error('[AppPlugin] Failed to bind declarative hooks', err as Error, {\n appId,\n });\n }\n\n // ── Auto-register declarative Action handlers ───────────────────\n // Actions with an inline `handler` (or extracted `body`) are wired\n // to the engine here so HTTP `POST /api/v1/actions/<obj>/<name>`\n // can invoke them. Actions without a body are left for legacy\n // imperative `engine.registerAction(...)` registration in user code.\n try {\n const actions = collectBundleActions(this.bundle);\n const actionBodyRunner = actionBodyRunnerFactory(new QuickJSScriptRunner(), {\n ql,\n logger: ctx.logger,\n appId,\n });\n let registered = 0;\n if (actions.length > 0 && typeof ql.registerAction === 'function') {\n for (const action of actions) {\n const handler = actionBodyRunner(action);\n if (!handler) continue;\n const objectKey =\n typeof action.object === 'string' && action.object.length > 0\n ? action.object\n : 'global';\n try {\n ql.registerAction(objectKey, action.name, handler, `app:${appId}`);\n registered++;\n } catch (err: any) {\n ctx.logger.warn('[AppPlugin] Failed to register action body', {\n appId,\n action: action.name,\n object: objectKey,\n error: err?.message ?? String(err),\n });\n }\n }\n }\n if (registered > 0) {\n ctx.logger.info('[AppPlugin] Bound declarative actions', {\n appId,\n actionCount: registered,\n });\n }\n } catch (err: any) {\n ctx.logger.error('[AppPlugin] Failed to bind declarative actions', err as Error, {\n appId,\n });\n }\n\n // ── Auto-register declarative Background Jobs ────────────────────\n // Jobs declared via `defineStack({ jobs })` are scheduled against the\n // running `IJobService` on `kernel:ready` (so the service plugin and\n // ObjectQL engine have had a chance to register). Handler strings are\n // resolved through `collectBundleFunctions(bundle)` — the same\n // registry used by hooks/actions, keeping the surface uniform.\n try {\n const jobs: any[] = Array.isArray(this.bundle.jobs)\n ? this.bundle.jobs\n : Array.isArray((this.bundle.manifest || {}).jobs)\n ? (this.bundle.manifest as any).jobs\n : [];\n if (jobs.length > 0) {\n ctx.hook('kernel:ready', async () => {\n let svc: any;\n try { svc = ctx.getService('job'); } catch { /* not installed */ }\n if (!svc || typeof svc.schedule !== 'function') {\n ctx.logger.warn('[AppPlugin] job service not registered — skipping declarative jobs', {\n appId, jobCount: jobs.length,\n });\n return;\n }\n const fnMap = collectBundleFunctions(this.bundle);\n let ok = 0;\n for (const job of jobs) {\n const jobName: string = job?.name;\n if (!jobName) {\n ctx.logger.warn('[AppPlugin] skipping job without name', { appId, job });\n continue;\n }\n if (job.enabled === false) {\n ctx.logger.debug('[AppPlugin] job disabled — skipping', { appId, job: jobName });\n continue;\n }\n const handler = fnMap[job.handler];\n if (typeof handler !== 'function') {\n ctx.logger.warn('[AppPlugin] job handler not found in bundle.functions — skipping', {\n appId, job: jobName, handler: job.handler,\n });\n continue;\n }\n try {\n await svc.schedule(\n jobName,\n job.schedule,\n async (jobCtx: any) => {\n await handler({ ...jobCtx, jobId: jobName, bundle: this.bundle });\n },\n );\n ok++;\n } catch (err: any) {\n ctx.logger.warn('[AppPlugin] Failed to schedule job', {\n appId, job: jobName, error: err?.message ?? String(err),\n });\n }\n }\n ctx.logger.info('[AppPlugin] Scheduled background jobs', { appId, count: ok });\n });\n }\n } catch (err: any) {\n ctx.logger.error('[AppPlugin] Failed to schedule background-job registration', err as Error, { appId });\n }\n\n // ── Org-Scoped App Catalog Sync ──────────────────────────────────\n // Emit `app:registered` so AppCatalogService (running on the\n // control-plane kernel) can mirror this app into `sys_app`. Skipped\n // for standalone (single-tenant) usages where no project context is\n // attached.\n this.emitCatalogEvent(ctx, 'app:registered', sys);\n\n // ── i18n Translation Loading ─────────────────────────────────────\n // Auto-load translation bundles from the app config into the\n // kernel's i18n service, so discovery and handlers stay consistent.\n await this.loadTranslations(ctx, appId);\n\n // Data Seeding\n // Collect seed data from multiple locations (top-level `data` preferred, `manifest.data` for backward compat)\n const seedDatasets: any[] = [];\n \n // 1. Top-level `data` field (new standard location on ObjectStackDefinition)\n if (Array.isArray(this.bundle.data)) {\n seedDatasets.push(...this.bundle.data);\n }\n \n // 2. Legacy: `manifest.data` (backward compatibility)\n const manifest = this.bundle.manifest || this.bundle;\n if (manifest && Array.isArray(manifest.data)) {\n seedDatasets.push(...manifest.data);\n }\n\n // Object names in seed data are used as-is — no FQN expansion.\n // Under the current naming convention, the object's short name IS\n // the canonical name and the physical table name.\n\n if (seedDatasets.length > 0) {\n ctx.logger.info(`[AppPlugin] Found ${seedDatasets.length} seed datasets for ${appId}`);\n\n // Pass seed datasets through unchanged — object names are canonical\n const normalizedDatasets = seedDatasets\n .filter((d: any) => d.object && Array.isArray(d.records))\n .map((d: any) => ({\n ...d,\n object: d.object,\n }));\n\n // Resolve the seed identity (os.user / os.org) BEFORE any seed\n // runs. Deterministically ensures a non-loginable system user\n // exists so identity-derived seed values (e.g.\n // `owner_id: cel`os.user.id``) resolve at boot — before the\n // first human sign-up. See ensureSeedIdentity().\n const seedIdentity = await this.ensureSeedIdentity(ql, ctx.logger);\n\n // Stash datasets on a kernel service so SecurityPlugin's\n // sys_organization insert hook can replay them per-tenant\n // (Salesforce-sandbox style: every new org gets its own\n // private copy of the artifact's demo data).\n //\n // We also register a `seed-replayer` callable so the\n // SecurityPlugin doesn't need to import @objectstack/runtime\n // (would create a circular workspace dep). The replayer\n // captures the SeedLoaderService closure and exposes a\n // narrow `(orgId) => Promise<summary>` surface.\n try {\n const kernel: any = (ctx as any).kernel;\n const existing = (() => {\n try { return kernel?.getService?.('seed-datasets'); } catch { return undefined; }\n })();\n const merged = Array.isArray(existing)\n ? [...existing, ...normalizedDatasets]\n : normalizedDatasets;\n const registerSvc = (name: string, value: any) => {\n if (kernel?.registerService) kernel.registerService(name, value);\n else if (typeof (ctx as any).registerService === 'function') (ctx as any).registerService(name, value);\n };\n registerSvc('seed-datasets', merged);\n\n const metadataNow = ctx.getService('metadata') as IMetadataService | undefined;\n const loggerRef = ctx.logger;\n const replayer = async (organizationId: string) => {\n if (!organizationId) return { inserted: 0, updated: 0, errors: [] as any[] };\n const md = metadataNow ?? (ctx.getService('metadata') as IMetadataService | undefined);\n if (!md) {\n loggerRef.warn('[seed-replayer] metadata service unavailable');\n return { inserted: 0, updated: 0, errors: [] as any[] };\n }\n const datasetsNow = (() => {\n try { return kernel?.getService?.('seed-datasets'); } catch { return merged; }\n })() ?? merged;\n if (!Array.isArray(datasetsNow) || datasetsNow.length === 0) {\n return { inserted: 0, updated: 0, errors: [] as any[] };\n }\n const seedLoader = new SeedLoaderService(ql, md, loggerRef);\n const { SeedLoaderRequestSchema } = await import('@objectstack/spec/data');\n const request = SeedLoaderRequestSchema.parse({\n datasets: datasetsNow,\n config: {\n defaultMode: 'upsert',\n multiPass: true,\n organizationId,\n // Bind os.user (system identity) and os.org (this\n // tenant) so identity-derived seed values resolve\n // per-org. org.id falls back to organizationId\n // inside the loader when identity.org is absent.\n identity: seedIdentity,\n },\n });\n const result = await seedLoader.load(request);\n return {\n inserted: result.summary.totalInserted,\n updated: result.summary.totalUpdated,\n errors: result.errors,\n };\n };\n registerSvc('seed-replayer', replayer);\n ctx.logger.info(`[Seeder] Registered ${normalizedDatasets.length} datasets + replayer on kernel (total datasets: ${merged.length})`);\n } catch (e: any) {\n ctx.logger.warn('[Seeder] Failed to register seed-datasets/seed-replayer service', { error: e?.message });\n }\n\n // Decide whether to also run the seed inline at AppPlugin\n // start. In multi-tenant mode, the per-org replay (driven\n // by OrgScopingPlugin's sys_organization middleware) is the\n // source of truth — running it here too would create NULL-\n // org rows that pollute reads and need a separate claim\n // step. So we skip it. Single-tenant deployments keep the\n // legacy behaviour: seed immediately at boot so there's\n // always demo data without needing an org insert.\n const multiTenant = String(readEnvWithDeprecation('OS_MULTI_ORG_ENABLED', 'OS_MULTI_TENANT') ?? 'false').toLowerCase() !== 'false';\n if (multiTenant) {\n ctx.logger.info('[Seeder] multi-tenant mode — skipping inline seed; per-org replay will run on sys_organization insert');\n } else {\n // Inline seed budget: large bundles (e.g. CRM Starter's 10\n // datasets) can easily exceed the kernel's plugin-start\n // timeout. We MUST NOT let seed work tear the kernel down —\n // a 500 on /auth and /data is far worse than a delayed seed.\n // Race the actual seed work against a soft budget; if we run\n // out of time, log loudly and let the kernel proceed.\n const seedBudgetMs = Number(process.env.OS_INLINE_SEED_BUDGET_MS ?? 8000);\n const seedPromise = (async () => {\n try {\n const metadata = ctx.getService('metadata') as IMetadataService | undefined;\n if (metadata) {\n const seedLoader = new SeedLoaderService(ql, metadata, ctx.logger);\n const { SeedLoaderRequestSchema } = await import('@objectstack/spec/data');\n const request = SeedLoaderRequestSchema.parse({\n datasets: normalizedDatasets,\n config: { defaultMode: 'upsert', multiPass: true, identity: seedIdentity },\n });\n const result = await seedLoader.load(request);\n const { totalInserted, totalUpdated, totalSkipped, totalErrored } = result.summary;\n if (result.success) {\n ctx.logger.info('[Seeder] Seed loading complete', {\n inserted: totalInserted,\n updated: totalUpdated,\n skipped: totalSkipped,\n errored: totalErrored,\n });\n } else {\n // LOUD FAILURE: dropped records were previously\n // invisible (the summary only logged errors.length and\n // omitted totalErrored). Report the count AND each\n // actionable reason so broken seeds can't pass silently.\n ctx.logger.warn(\n `[Seeder] Seed loading completed with ${totalErrored} dropped record(s) and ${result.errors.length} error(s) for ${appId}`,\n {\n inserted: totalInserted,\n updated: totalUpdated,\n skipped: totalSkipped,\n errored: totalErrored,\n },\n );\n for (const e of result.errors.slice(0, 20)) {\n ctx.logger.warn(`[Seeder] ✗ ${e.message}`);\n }\n if (result.errors.length > 20) {\n ctx.logger.warn(`[Seeder] …and ${result.errors.length - 20} more error(s)`);\n }\n }\n } else {\n // Fallback: basic insert when metadata service is not available\n ctx.logger.debug('[Seeder] No metadata service; using basic insert fallback');\n for (const dataset of normalizedDatasets) {\n ctx.logger.info(`[Seeder] Seeding ${dataset.records.length} records for ${dataset.object}`);\n for (const record of dataset.records) {\n try {\n await ql.insert(dataset.object, record, { context: { isSystem: true } } as any);\n } catch (err: any) {\n ctx.logger.warn(`[Seeder] Failed to insert ${dataset.object} record:`, { error: err.message });\n }\n }\n }\n ctx.logger.info('[Seeder] Data seeding complete.');\n }\n } catch (err: any) {\n // If SeedLoaderService fails (e.g., metadata not available), fall back to basic insert\n ctx.logger.warn('[Seeder] SeedLoaderService failed, falling back to basic insert', { error: err.message });\n for (const dataset of normalizedDatasets) {\n for (const record of dataset.records) {\n try {\n await ql.insert(dataset.object, record, { context: { isSystem: true } } as any);\n } catch (insertErr: any) {\n ctx.logger.warn(`[Seeder] Failed to insert ${dataset.object} record:`, { error: insertErr.message });\n }\n }\n }\n ctx.logger.info('[Seeder] Data seeding complete (fallback).');\n }\n })();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const budget = new Promise<'budget'>((resolve) => {\n timer = setTimeout(() => resolve('budget'), seedBudgetMs);\n });\n const winner = await Promise.race([seedPromise.then(() => 'done' as const), budget]);\n if (timer) clearTimeout(timer);\n if (winner === 'budget') {\n ctx.logger.warn(\n `[Seeder] Inline seed exceeded ${seedBudgetMs}ms budget for ${appId}; continuing in background to avoid blocking kernel start.`,\n );\n // Don't leave the promise unobserved.\n seedPromise.catch((err: any) => {\n ctx.logger.warn('[Seeder] Background seed failed after budget', { appId, error: err?.message ?? String(err) });\n });\n }\n }\n }\n }\n\n stop = async (ctx: PluginContext) => {\n const sys = this.bundle.manifest || this.bundle;\n this.emitCatalogEvent(ctx, 'app:unregistered', sys);\n }\n\n /**\n * Resolve the identity bound to `os.user` / `os.org` for seed CEL values.\n *\n * On a fresh boot there are zero users until the first human sign-up\n * (which the SeedLoader runs *before*), so identity-derived seeds like\n * `owner_id: cel`os.user.id`` had nothing to resolve against and were\n * dropped silently. To make seeds deterministic and self-sufficient we\n * upsert a single non-loginable **system user** (`usr_system`) and bind\n * it as `os.user`.\n *\n * Why a dedicated system user rather than the login admin:\n * - `sys_user` is better-auth-managed and schema-locked (ADR-0010); the\n * password lives in `sys_account`, so a *loginable* admin can only be\n * minted through better-auth (the CLI does this via HTTP sign-up after\n * boot). A raw insert here would bypass those invariants.\n * - `usr_system` is an owner identity only (no credential row), analogous\n * to Salesforce's \"Automated Process\" user. The human admin is created\n * independently and need not be the seed owner.\n *\n * Idempotent: matches by the stable id, inserts once, reuses thereafter.\n * Failures are non-fatal (logged) — records that actually need `os.user`\n * then fail loudly in the loader with an actionable message.\n */\n private async ensureSeedIdentity(\n ql: any,\n logger: PluginContext['logger'],\n ): Promise<{ user: { id: string; role: string; email: string } }> {\n // Deterministic, non-loginable service identity that owns seeded data.\n const SYSTEM_USER_ID = SystemUserId.SYSTEM;\n const SYSTEM_USER_EMAIL = 'system@objectstack.local';\n const identity = { user: { id: SYSTEM_USER_ID, role: 'system', email: SYSTEM_USER_EMAIL } };\n const opts = { context: { isSystem: true } } as any;\n\n try {\n const existing = await (ql as any).find(\n 'sys_user',\n { where: { id: SYSTEM_USER_ID }, limit: 1 },\n opts,\n );\n if (Array.isArray(existing) && existing.length > 0) {\n return identity;\n }\n await (ql as any).insert(\n 'sys_user',\n {\n id: SYSTEM_USER_ID,\n name: 'System',\n email: SYSTEM_USER_EMAIL,\n email_verified: true,\n role: 'system',\n },\n opts,\n );\n logger.info(\n `[Seeder] Provisioned deterministic system user (${SYSTEM_USER_ID}) as seed owner — binds os.user for identity-derived seed values`,\n );\n } catch (err: any) {\n // Non-fatal: identity-dependent records will fail loudly in the\n // loader; identity-free records still seed normally.\n logger.warn('[Seeder] Failed to ensure system seed user; os.user-dependent seeds may be dropped', {\n error: err?.message ?? String(err),\n });\n }\n return identity;\n }\n\n /**\n * Emit a kernel hook so the control-plane `AppCatalogService` can\n * upsert / delete the corresponding `sys_app` row. Silently no-ops\n * when no project context is attached (standalone single-tenant mode)\n * or when the kernel has no `trigger` API available.\n */\n private emitCatalogEvent(ctx: PluginContext, event: 'app:registered' | 'app:unregistered', sys: any): void {\n if (!this.projectContext) return;\n\n const trigger = (ctx as any).trigger;\n if (typeof trigger !== 'function') {\n ctx.logger.debug('[AppPlugin] kernel has no trigger() — skipping catalog hook', { event });\n return;\n }\n\n const appName = sys.name || sys.id;\n if (!appName) return;\n\n const payload = {\n environmentId: this.projectContext.environmentId,\n organizationId: this.projectContext.organizationId,\n projectName: this.projectContext.projectName,\n app: {\n name: appName,\n label: sys.label,\n icon: sys.icon,\n branding: sys.branding,\n isDefault: sys.isDefault ?? sys.is_default,\n active: sys.active !== false,\n },\n source: this.projectContext.source ?? (this.projectContext.packageId ? 'package' : 'user'),\n packageId: this.projectContext.packageId,\n };\n\n try {\n trigger.call(ctx, event, payload);\n } catch (err: any) {\n ctx.logger.warn('[AppPlugin] catalog hook trigger failed', { event, error: err?.message });\n }\n }\n\n /**\n * Auto-load i18n translation bundles from the app config into the\n * kernel's i18n service. Handles both `translations` (array of\n * TranslationBundle) and `i18n` config (default locale, etc.).\n *\n * Gracefully skips when the i18n service is not registered —\n * this keeps AppPlugin resilient across server/dev/mock environments.\n */\n private async loadTranslations(ctx: PluginContext, appId: string): Promise<void> {\n // ctx.getService throws when a service is not registered, so we\n // must use try/catch to gracefully skip when no i18n plugin is loaded.\n let i18nService: II18nService | undefined;\n try {\n i18nService = ctx.getService('i18n') as II18nService;\n } catch {\n // Service not registered — handled below\n }\n\n // Collect translation bundles early to determine if we have data\n const bundles: Array<Record<string, unknown>> = [];\n if (Array.isArray(this.bundle.translations)) {\n bundles.push(...this.bundle.translations);\n }\n const manifest = this.bundle.manifest || this.bundle;\n if (manifest && Array.isArray(manifest.translations) && manifest.translations !== this.bundle.translations) {\n bundles.push(...manifest.translations);\n }\n\n if (!i18nService) {\n if (bundles.length > 0) {\n // Auto-register the in-memory i18n fallback so the bundles\n // we already loaded server-side become discoverable through\n // `getService('i18n')` (used by the REST API to localize\n // view / action / object metadata). Without this step,\n // bundles authored in `defineStack({ translations })` were\n // silently dropped on standalone/dev stacks that didn't\n // explicitly install I18nServicePlugin.\n try {\n const mod = await import('@objectstack/core');\n const createMemoryI18n = (mod as any).createMemoryI18n;\n if (typeof createMemoryI18n === 'function') {\n const fallback = createMemoryI18n();\n (ctx as any).registerService('i18n', fallback);\n i18nService = fallback;\n ctx.logger.info(\n `[i18n] Auto-registered in-memory i18n fallback for \"${appId}\" (${bundles.length} bundle(s) detected). ` +\n 'Install I18nServicePlugin from @objectstack/service-i18n for file-based / production use.'\n );\n }\n } catch (err: any) {\n ctx.logger.warn(\n `[i18n] App \"${appId}\" has ${bundles.length} translation bundle(s) but auto-fallback failed: ${err?.message ?? err}.`\n );\n return;\n }\n if (!i18nService) {\n ctx.logger.warn(\n `[i18n] App \"${appId}\" has ${bundles.length} translation bundle(s) but no i18n service is registered.`\n );\n return;\n }\n } else {\n ctx.logger.debug('[i18n] No i18n service registered; skipping translation loading', { appId });\n return;\n }\n }\n\n // Apply i18n config (default locale, etc.)\n const i18nConfig = this.bundle.i18n || (this.bundle.manifest || this.bundle)?.i18n;\n if (i18nConfig?.defaultLocale && typeof i18nService.setDefaultLocale === 'function') {\n i18nService.setDefaultLocale(i18nConfig.defaultLocale);\n ctx.logger.debug('[i18n] Set default locale', { appId, locale: i18nConfig.defaultLocale });\n }\n\n if (bundles.length === 0) {\n return;\n }\n\n let loadedLocales = 0;\n for (const bundle of bundles) {\n // Each bundle is a TranslationBundle: Record<locale, TranslationData>\n for (const [locale, data] of Object.entries(bundle)) {\n if (data && typeof data === 'object') {\n try {\n i18nService.loadTranslations(locale, data as Record<string, unknown>);\n loadedLocales++;\n } catch (err: any) {\n ctx.logger.warn('[i18n] Failed to load translations', { appId, locale, error: err.message });\n }\n }\n }\n }\n\n // Emit diagnostic when the active i18n service is a fallback/stub\n const svcAny = i18nService as unknown as Record<string, unknown>;\n if (svcAny._fallback || svcAny._dev) {\n ctx.logger.info(\n `[i18n] Loaded ${loadedLocales} locale(s) into in-memory i18n fallback for \"${appId}\". ` +\n 'For production, consider registering I18nServicePlugin from @objectstack/service-i18n.'\n );\n } else {\n ctx.logger.info('[i18n] Loaded translation bundles', { appId, bundles: bundles.length, locales: loadedLocales });\n }\n }\n}\n\n// ─── Bundle hook & function collectors ──────────────────────────────\n// Hooks declared in `defineStack({ hooks })` end up at `bundle.hooks`;\n// some legacy bundles still nest them under `manifest.hooks`. We dedupe\n// (by reference) so the same array isn't bound twice when both shapes\n// happen to point at the same list.\n\n/** Collect declarative `Hook` definitions from a bundle (top-level + manifest). */\nexport function collectBundleHooks(bundle: any): any[] {\n const out: any[] = [];\n const seen = new Set<any>();\n const push = (arr: any) => {\n if (!Array.isArray(arr)) return;\n for (const h of arr) {\n if (h && !seen.has(h)) {\n seen.add(h);\n out.push(h);\n }\n }\n };\n push(bundle?.hooks);\n push(bundle?.manifest?.hooks);\n return out;\n}\n\n/**\n * Collect declarative actions from the bundle. Walks both root-level\n * `actions[]` and per-object `objects[*].actions[]`, attaching the parent\n * object name where applicable so `engine.registerAction(object, name, ...)`\n * sees the correct routing key.\n *\n * Each returned record is a shallow copy with `object` set when the action\n * originated under an object (and not already present on the action itself).\n */\nexport function collectBundleActions(\n bundle: any,\n): Array<{ name: string; object?: string; body?: unknown; type?: string; [k: string]: unknown }> {\n const out: any[] = [];\n const seen = new Set<any>();\n const push = (arr: any, parentObject?: string) => {\n if (!Array.isArray(arr)) return;\n for (const a of arr) {\n if (!a || typeof a !== 'object' || typeof a.name !== 'string') continue;\n if (seen.has(a)) continue;\n seen.add(a);\n const inferredObject =\n typeof a.object === 'string' ? a.object\n : typeof a.objectName === 'string' ? a.objectName\n : parentObject;\n out.push(inferredObject ? { ...a, object: inferredObject } : { ...a });\n }\n };\n push(bundle?.actions);\n push(bundle?.manifest?.actions);\n if (Array.isArray(bundle?.objects)) {\n for (const o of bundle.objects) push(o?.actions, o?.name);\n }\n if (Array.isArray(bundle?.manifest?.objects)) {\n for (const o of bundle.manifest.objects) push(o?.actions, o?.name);\n }\n return out;\n}\n\n/**\n * Collect a name → handler map from `bundle.functions`. Accepted shapes:\n *\n * - `{ functions: { foo: fn, bar: fn } }` ← preferred map form\n * - `{ functions: [{ name: 'foo', handler: fn }] }` ← array of records\n *\n * String-named hook handlers (`Hook.handler: 'foo'`) are resolved against\n * this map (and the engine's persistent function registry).\n */\nexport function collectBundleFunctions(bundle: any): Record<string, (ctx: any) => any> {\n const out: Record<string, (ctx: any) => any> = {};\n const merge = (src: any) => {\n if (!src) return;\n if (Array.isArray(src)) {\n for (const item of src) {\n if (item && typeof item.name === 'string' && typeof item.handler === 'function') {\n out[item.name] = item.handler;\n }\n }\n } else if (typeof src === 'object') {\n for (const [name, fn] of Object.entries(src)) {\n if (typeof fn === 'function') out[name] = fn as any;\n }\n }\n };\n merge(bundle?.functions);\n merge(bundle?.manifest?.functions);\n return out;\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Standalone (runtime-only) stack factory.\n *\n * Builds the minimal plugin list for embedding ObjectStack in another\n * framework: ObjectQL + Driver + Metadata, plus AppPlugin if a compiled\n * artifact is available. No authentication, no Studio data, no control\n * plane — REST routes are served unauthenticated.\n *\n * Auto-detects the appropriate driver from the database URL scheme:\n * - `memory://*` → InMemoryDriver\n * - `postgres[ql]://`, `pg://` → SqlDriver (pg)\n * - `mongodb[+srv]://` → MongoDBDriver (peer-dep `@objectstack/driver-mongodb`)\n * - `file:` / no scheme → SqlDriver (better-sqlite3)\n *\n * Unknown URL schemes throw — we never silently fall back to sqlite, since\n * that historically created bogus directories on disk (e.g. `mongodb:/`)\n * when an unsupported URL was treated as a file path.\n *\n * NOTE: `libsql://` / Turso support is provided by `@objectstack/driver-turso`,\n * which ships separately in the ObjectStack Cloud distribution. The open-core\n * runtime no longer dispatches `libsql://` URLs; cloud builds register the\n * Turso driver via their own stack composition (`cloud-stack.ts`).\n */\n\nimport { resolve as resolvePath } from 'node:path';\nimport { mkdirSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { z } from 'zod';\nimport { readEnvWithDeprecation } from '@objectstack/types';\nimport { loadArtifactBundle, isHttpUrl } from './load-artifact-bundle.js';\n\n/**\n * Resolve the ObjectStack home directory used to store cwd-independent\n * runtime data (default sqlite database, downloaded marketplace apps,\n * installed plugin cache).\n *\n * Resolution order:\n * 1. `OS_HOME` env var (absolute path; `~` expanded)\n * 2. `~/.objectstack` (cross-platform user-home default)\n *\n * The directory is created lazily by callers that actually write to it\n * (e.g. the sqlite driver's `mkdirSync(...)`); this helper does not\n * touch the filesystem.\n */\nexport function resolveObjectStackHome(): string {\n const raw = process.env.OS_HOME?.trim();\n if (raw && raw.length > 0) {\n if (raw.startsWith('~')) return resolvePath(homedir(), raw.slice(1).replace(/^[/\\\\]/, ''));\n return resolvePath(raw);\n }\n return resolvePath(homedir(), '.objectstack');\n}\n\nexport const StandaloneStackConfigSchema = z.object({\n databaseUrl: z.string().optional(),\n databaseAuthToken: z.string().optional(),\n databaseDriver: z.enum(['sqlite', 'sqlite-wasm', 'memory', 'postgres', 'mongodb']).optional(),\n environmentId: z.string().optional(),\n artifactPath: z.string().optional(),\n /**\n * Project root directory. When set (typically by the CLI after locating\n * `objectstack.config.ts`), the default sqlite database is placed under\n * `<projectRoot>/.objectstack/data/standalone.db` instead of the global\n * `~/.objectstack/data/standalone.db`. This keeps per-project data\n * scoped to the project folder so different examples / apps don't\n * share a single database by accident.\n *\n * Explicit `databaseUrl` / `OS_DATABASE_URL` / `OS_HOME` still take\n * precedence over this default.\n */\n projectRoot: z.string().optional(),\n});\n\nexport type StandaloneStackConfig = z.input<typeof StandaloneStackConfigSchema>;\n\nexport interface StandaloneStackResult {\n plugins: any[];\n api: { enableProjectScoping: false; projectResolution: 'none' };\n /**\n * Top-level metadata copied from the loaded artifact bundle (when an\n * artifact was successfully loaded). These are surfaced so callers\n * that wrap this result as a `defineStack()`-shaped config (e.g. the\n * CLI's `serve` command without a host `objectstack.config.ts`) can\n * still drive tier resolution, capability detection and driver\n * auto-registration off the artifact's declarations.\n */\n requires?: string[];\n objects?: any[];\n manifest?: any;\n}\n\ntype ResolvedDriverKind = 'memory' | 'postgres' | 'mongodb' | 'sqlite' | 'sqlite-wasm';\n\nfunction detectDriverFromUrl(dbUrl: string): ResolvedDriverKind {\n if (/^memory:\\/\\//i.test(dbUrl)) return 'memory';\n if (/^(postgres(ql)?|pg):\\/\\//i.test(dbUrl)) return 'postgres';\n if (/^mongodb(\\+srv)?:\\/\\//i.test(dbUrl)) return 'mongodb';\n if (/^wasm-sqlite:\\/\\//i.test(dbUrl)) return 'sqlite-wasm';\n if (/\\.wasm\\.db$/i.test(dbUrl)) return 'sqlite-wasm';\n if (/^file:/i.test(dbUrl)) return 'sqlite';\n // Bare path without a scheme — treat as a sqlite file path.\n if (!/^[a-z][a-z0-9+.-]*:\\/\\//i.test(dbUrl)) return 'sqlite';\n throw new Error(\n `[StandaloneStack] Unsupported database URL scheme: ${dbUrl}. ` +\n `Supported schemes: memory://, postgres://, pg://, mongodb://, mongodb+srv://, file:`\n );\n}\n\nexport async function createStandaloneStack(config?: StandaloneStackConfig): Promise<StandaloneStackResult> {\n const cfg = StandaloneStackConfigSchema.parse(config ?? {});\n\n const { ObjectQLPlugin } = await import('@objectstack/objectql');\n const { MetadataPlugin } = await import('@objectstack/metadata');\n const { DriverPlugin } = await import('./driver-plugin.js');\n const { AppPlugin } = await import('./app-plugin.js');\n\n const cwd = process.cwd();\n const environmentId = cfg.environmentId ?? process.env.OS_ENVIRONMENT_ID ?? 'proj_local';\n const artifactPathInput = cfg.artifactPath\n ?? process.env.OS_ARTIFACT_PATH\n ?? resolvePath(cwd, 'dist/objectstack.json');\n const artifactPath = isHttpUrl(artifactPathInput)\n ? artifactPathInput\n : (artifactPathInput.startsWith('/')\n ? artifactPathInput\n : resolvePath(cwd, artifactPathInput));\n\n const dbUrl = cfg.databaseUrl\n ?? readEnvWithDeprecation('OS_DATABASE_URL', 'DATABASE_URL')?.trim()\n ?? process.env.TURSO_DATABASE_URL?.trim()\n ?? (process.env.OS_HOME?.trim()\n ? `file:${resolvePath(resolveObjectStackHome(), 'data/standalone.db')}`\n : (cfg.projectRoot\n ? `file:${resolvePath(cfg.projectRoot, '.objectstack/data/standalone.db')}`\n : `file:${resolvePath(resolveObjectStackHome(), 'data/standalone.db')}`));\n // `databaseAuthToken` / `OS_DATABASE_AUTH_TOKEN` are preserved in the\n // config schema for cloud builds that compose their own turso driver;\n // the standalone (open-core) runtime no longer consumes them directly.\n const explicitDriver = cfg.databaseDriver\n ?? (process.env.OS_DATABASE_DRIVER?.trim() as ResolvedDriverKind | undefined);\n const dbDriver: ResolvedDriverKind = explicitDriver ?? detectDriverFromUrl(dbUrl);\n\n let driverPlugin: any;\n if (dbDriver === 'memory') {\n const { InMemoryDriver } = await import('@objectstack/driver-memory');\n driverPlugin = new DriverPlugin(new InMemoryDriver());\n } else if (dbDriver === 'postgres') {\n const { SqlDriver } = await import('@objectstack/driver-sql');\n driverPlugin = new DriverPlugin(\n new SqlDriver({\n client: 'pg',\n connection: dbUrl,\n pool: { min: 0, max: 5 },\n }) as any,\n );\n } else if (dbDriver === 'mongodb') {\n // MongoDB driver is an optional peer dependency. Importing it lazily\n // avoids forcing every standalone consumer to install the mongo SDK.\n let MongoDBDriver: any;\n try {\n ({ MongoDBDriver } = await import('@objectstack/driver-mongodb' as any));\n } catch (err: any) {\n throw new Error(\n `[StandaloneStack] mongodb URL detected but @objectstack/driver-mongodb is not installed. ` +\n `Add it as a dependency or pass an explicit driverPlugin. (${err?.message ?? err})`\n );\n }\n driverPlugin = new DriverPlugin(new MongoDBDriver({ url: dbUrl }) as any);\n } else if (dbDriver === 'sqlite-wasm') {\n const { SqliteWasmDriver } = await import('@objectstack/driver-sqlite-wasm' as any);\n const filename = dbUrl\n .replace(/^wasm-sqlite:(\\/\\/)?/i, '')\n .replace(/^file:(\\/\\/)?/i, '');\n if (filename && filename !== ':memory:') {\n mkdirSync(resolvePath(filename, '..'), { recursive: true });\n }\n driverPlugin = new DriverPlugin(\n new SqliteWasmDriver({\n filename: filename || ':memory:',\n persist: filename && filename !== ':memory:' ? 'on-write' : undefined,\n }) as any,\n );\n } else {\n // sqlite\n const { SqlDriver } = await import('@objectstack/driver-sql');\n const filename = dbUrl.replace(/^file:(\\/\\/)?/, '');\n if (!filename || /^[a-z][a-z0-9+.-]*:\\/\\//i.test(filename)) {\n throw new Error(\n `[StandaloneStack] sqlite driver was selected but the URL does not look like a file path: \"${dbUrl}\". ` +\n `Use file:/path/to/db.sqlite, or set OS_DATABASE_DRIVER explicitly.`\n );\n }\n mkdirSync(resolvePath(filename, '..'), { recursive: true });\n driverPlugin = new DriverPlugin(\n new SqlDriver({\n client: 'better-sqlite3',\n connection: { filename },\n useNullAsDefault: true,\n }),\n );\n }\n\n const artifactBundle = await loadArtifactBundle(artifactPath, {\n tag: '[StandaloneStack]',\n unwrapEnvelope: true,\n });\n if (artifactBundle) {\n const flowsCount = Array.isArray(artifactBundle?.flows) ? artifactBundle.flows.length : 'n/a';\n // eslint-disable-next-line no-console\n console.warn(\n `[StandaloneStack] artifact loaded: path=${artifactPath} keys=${Object.keys(artifactBundle).join(',')} flows=${flowsCount}`,\n );\n }\n\n const plugins: any[] = [\n driverPlugin,\n new MetadataPlugin({\n // Source-file scanner OFF — declarative metadata is loaded\n // from the compiled artifact, not from yaml/json files on\n // disk. Scanning would also recursively watch the project\n // root (incl. node_modules), which is expensive and prone\n // to EMFILE.\n watch: false,\n // Artifact-file HMR ON in non-production so edits to\n // `*.view.ts` / `*.flow.ts` (which the CLI dev-mode watcher\n // recompiles into `dist/objectstack.json`) are picked up by\n // the running server WITHOUT requiring a manual restart.\n // Uses polling under the hood (see plugin.ts) to avoid\n // `fs.watch` EMFILE on macOS / busy dev hosts.\n artifactWatch: process.env.NODE_ENV !== 'production',\n environmentId,\n artifactSource: { mode: 'local-file', path: artifactPath },\n }),\n new ObjectQLPlugin({ environmentId }),\n ];\n if (artifactBundle) plugins.push(new AppPlugin(artifactBundle));\n\n // Surface artifact-declared metadata so a caller using this result\n // directly as a `defineStack()`-shaped config (no host\n // `objectstack.config.ts`) can still drive CLI tier resolution\n // and driver auto-registration. We copy *references* — no clone — so\n // the caller can `{ ...originalConfig, ...standaloneStack }` without\n // double-merging large object arrays.\n const requires: string[] | undefined =\n Array.isArray(artifactBundle?.requires)\n ? (artifactBundle.requires.filter((c: unknown) => typeof c === 'string') as string[])\n : undefined;\n const objects: any[] | undefined =\n Array.isArray(artifactBundle?.objects) ? artifactBundle.objects : undefined;\n const manifest: any | undefined = artifactBundle?.manifest;\n\n return {\n plugins,\n api: {\n enableProjectScoping: false,\n projectResolution: 'none',\n },\n ...(requires ? { requires } : {}),\n ...(objects ? { objects } : {}),\n ...(manifest ? { manifest } : {}),\n };\n}\n","/**\n * Pre-seed the OWNING cloud organization into a freshly-provisioned\n * project DB.\n *\n * Why this exists\n * ---------------\n * Every project at the cloud control plane is owned by exactly one\n * `sys_organization` (cloud-side). Mirroring that org into the project\n * DB makes the project's primary org match the cloud team that owns\n * it, so the owner's session resolves an `activeOrganizationId` on\n * first sign-in instead of landing on the empty \"create your first\n * organization\" prompt.\n *\n * Subsequent JIT-provisioned members of the same cloud org get\n * attached to this same row (Phase 2 — claim-driven by the SSO\n * callback).\n *\n * Idempotency\n * -----------\n * Keyed by the cloud `organization_id`. Re-runs across cold-boots are\n * safe no-ops; a row with that id either already exists or gets\n * inserted on the first boot of the project worker.\n */\n\nimport type { ObjectKernel } from '@objectstack/core';\n\nexport interface ProjectOrgSeed {\n /** Cloud `sys_organization.id` of the project's owning org. Reused as the project-side `sys_organization.id` so cross-tier references stay consistent. */\n id: string;\n /** Display name copied from the cloud org. */\n name: string;\n /** URL slug copied from the cloud org. */\n slug?: string | null;\n /** Optional logo URL. */\n logo?: string | null;\n}\n\nconst SYS_ORG = 'sys_organization';\n\n/**\n * Insert the project's owning organization into the project's\n * `sys_organization` table.\n *\n * Returns:\n * - `'inserted'` — the row was newly seeded\n * - `'exists'` — a row with this id already existed (no-op)\n * - `'skipped'` — payload missing required fields (no-op)\n * - `'error'` — an unexpected failure; details logged via `logger.warn`\n * (we never throw — org seed is best-effort)\n */\nexport async function seedProjectOrganization(\n kernel: ObjectKernel,\n seed: ProjectOrgSeed,\n logger?: { info?: (msg: string, ctx?: any) => void; warn?: (msg: string, ctx?: any) => void },\n): Promise<'inserted' | 'exists' | 'skipped' | 'error'> {\n if (!seed?.id || !seed?.name) return 'skipped';\n\n try {\n const ql: any = kernel.getService('objectql');\n if (!ql?.insert || !ql?.find) {\n logger?.warn?.('[seedProjectOrganization] objectql service unavailable', { orgId: seed.id });\n return 'skipped';\n }\n\n try {\n const existing = await ql.find(SYS_ORG, { where: { id: seed.id } } as any);\n const rows = Array.isArray(existing) ? existing : (existing?.value ?? []);\n if (Array.isArray(rows) && rows.length > 0) return 'exists';\n } catch {\n // schema may not be fully synced on first cold-boot; fall\n // through to insert — the DB layer will enforce uniqueness.\n }\n\n const nowIso = new Date().toISOString();\n await ql.insert(SYS_ORG, {\n id: seed.id,\n name: seed.name,\n slug: seed.slug ?? null,\n logo: seed.logo ?? null,\n metadata: null,\n created_at: nowIso,\n });\n\n logger?.info?.('[seedProjectOrganization] org seeded', {\n orgId: seed.id,\n name: seed.name,\n });\n return 'inserted';\n } catch (err: any) {\n logger?.warn?.('[seedProjectOrganization] failed (non-fatal)', {\n orgId: seed.id,\n error: err?.message,\n });\n return 'error';\n }\n}\n\n/**\n * Insert a `sys_member` row linking a user to an organization with a\n * given role. Idempotent on (user_id, organization_id).\n *\n * Used in tandem with `seedProjectOrganization` to bind the project\n * owner to the mirrored cloud org so the owner's first sign-in\n * already resolves an `activeOrganizationId` instead of landing on\n * the empty \"create your first organization\" prompt.\n *\n * Returns the same status enum as the org/owner seed helpers.\n */\nexport async function seedProjectMember(\n kernel: ObjectKernel,\n args: {\n userId: string;\n organizationId: string;\n role?: 'owner' | 'admin' | 'member';\n },\n logger?: { info?: (msg: string, ctx?: any) => void; warn?: (msg: string, ctx?: any) => void },\n): Promise<'inserted' | 'exists' | 'skipped' | 'error'> {\n const { userId, organizationId } = args;\n const role = args.role ?? 'member';\n if (!userId || !organizationId) return 'skipped';\n\n try {\n const ql: any = kernel.getService('objectql');\n if (!ql?.insert || !ql?.find) {\n logger?.warn?.('[seedProjectMember] objectql service unavailable', { userId, organizationId });\n return 'skipped';\n }\n\n try {\n const existing = await ql.find('sys_member', {\n where: { user_id: userId, organization_id: organizationId },\n } as any);\n const rows = Array.isArray(existing) ? existing : (existing?.value ?? []);\n if (Array.isArray(rows) && rows.length > 0) return 'exists';\n } catch {\n // see comment in seedProjectOrganization\n }\n\n const nowIso = new Date().toISOString();\n // sys_member's primary key is generated by the org plugin; we\n // pre-generate a stable id of the form `mem_<short>` to match\n // the existing convention used by the cloud control plane.\n const memId = `mem_${Math.random().toString(36).slice(2, 14)}`;\n await ql.insert('sys_member', {\n id: memId,\n organization_id: organizationId,\n user_id: userId,\n role,\n created_at: nowIso,\n });\n\n logger?.info?.('[seedProjectMember] member seeded', {\n userId,\n organizationId,\n role,\n });\n return 'inserted';\n } catch (err: any) {\n logger?.warn?.('[seedProjectMember] failed (non-fatal)', {\n userId,\n organizationId,\n error: err?.message,\n });\n return 'error';\n }\n}\n","/**\n * Pre-seed the project owner into a freshly-provisioned project DB.\n *\n * Why this exists\n * ---------------\n * When a user creates a project on the cloud control plane, the project\n * gets a brand-new isolated database. On first access, the SSO callback\n * would otherwise treat the project owner as just another anonymous JIT\n * user — no admin role, no membership, no recognition that *this is the\n * person who owns this project*. The owner then has to manually promote\n * themselves via the org membership UI, which is friction the user does\n * not deserve to pay.\n *\n * Worse: better-auth's `accountLinking` safety check rejects implicit\n * link of an unverified local row with an unverified OAuth identity\n * (`error=account_not_linked`). Pre-seeding with `emailVerified: true`\n * (cloud already verified them upstream) makes the link clean.\n *\n * Idempotency\n * -----------\n * The seed is keyed by the cloud `userId`. If a `sys_user` row with that\n * id already exists in the project DB, this is a no-op — safe to call\n * on every cold-boot. SecurityPlugin's `sys_user` insert middleware\n * (mounted by ArtifactKernelFactory) auto-creates the personal\n * organization + `sys_member(owner)` binding as a side effect of the\n * insert, so callers do not need to wire membership themselves.\n */\n\nimport type { ObjectKernel } from '@objectstack/core';\n\nexport interface ProjectOwnerSeed {\n /** Cloud `sys_user.id` of the project creator. Used as the project-side `sys_user.id` so SSO callbacks link by id, not by email-match. */\n userId: string;\n /** Verified email at cloud — copied here so the link check passes without a project-side verification flow. */\n email: string;\n /** Display name; nullable to tolerate users who never set one. */\n name?: string | null;\n /** Avatar URL; nullable. */\n image?: string | null;\n}\n\nconst SYS_USER = 'sys_user';\n\n/**\n * Insert the project owner into the project's `sys_user` table.\n *\n * Returns:\n * - `'inserted'` — the row was newly seeded\n * - `'exists'` — a row with this id already existed (no-op)\n * - `'skipped'` — payload missing required fields (no-op)\n * - `'error'` — an unexpected failure; details logged via `logger.warn`\n * (we never throw — owner seed is best-effort)\n */\nexport async function seedProjectOwner(\n kernel: ObjectKernel,\n seed: ProjectOwnerSeed,\n logger?: { info?: (msg: string, ctx?: any) => void; warn?: (msg: string, ctx?: any) => void },\n): Promise<'inserted' | 'exists' | 'skipped' | 'error'> {\n if (!seed?.userId || !seed?.email) return 'skipped';\n\n try {\n const ql: any = kernel.getService('objectql');\n if (!ql?.insert || !ql?.find) {\n logger?.warn?.('[seedProjectOwner] objectql service unavailable', { userId: seed.userId });\n return 'skipped';\n }\n\n // Idempotency check: bail if the owner is already present. We key\n // off `id` (not email) so re-runs are safe even if the user later\n // changes their cloud email.\n try {\n const existing = await ql.find(SYS_USER, { where: { id: seed.userId } } as any);\n const rows = Array.isArray(existing) ? existing : (existing?.value ?? []);\n if (Array.isArray(rows) && rows.length > 0) return 'exists';\n } catch {\n // `find` may legitimately fail on cold-start before the schema\n // is fully synced. Fall through to the insert — uniqueness will\n // also be enforced at the DB layer.\n }\n\n const nowIso = new Date().toISOString();\n await ql.insert(SYS_USER, {\n id: seed.userId,\n email: seed.email,\n name: seed.name ?? seed.email.split('@')[0] ?? 'Owner',\n image: seed.image ?? null,\n // Cloud already verified the upstream email. Marking it verified\n // here is what unblocks better-auth's accountLinking check on\n // the first SSO callback (alongside the trustedProviders config\n // in plugin-auth/auth-manager.ts).\n email_verified: true,\n created_at: nowIso,\n updated_at: nowIso,\n });\n\n logger?.info?.('[seedProjectOwner] owner seeded', {\n userId: seed.userId,\n email: seed.email,\n });\n return 'inserted';\n } catch (err: any) {\n // Common benign cases: race with another cold-boot, or unique\n // constraint violation if two requests interleave. Log + swallow.\n logger?.warn?.('[seedProjectOwner] failed (non-fatal)', {\n userId: seed.userId,\n error: err?.message,\n });\n return 'error';\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n// Export Kernels\nexport { ObjectKernel } from '@objectstack/core';\n\n// Export Runtime\nexport { Runtime } from './runtime.js';\nexport type { RuntimeConfig } from './runtime.js';\n\n// Export Standalone Stack\nexport { createStandaloneStack, resolveObjectStackHome } from './standalone-stack.js';\nexport type { StandaloneStackConfig, StandaloneStackResult } from './standalone-stack.js';\n\n// Export Default Host (artifact-first, no objectstack.config.ts required)\nexport { createDefaultHostConfig, resolveDefaultArtifactPath } from './default-host.js';\nexport type { DefaultHostConfigOptions, DefaultHostConfigResult } from './default-host.js';\n\n// Export Plugins\nexport { DriverPlugin } from './driver-plugin.js';\nexport { AppPlugin, collectBundleHooks, collectBundleFunctions, collectBundleActions } from './app-plugin.js';\nexport { SeedLoaderService } from './seed-loader.js';\n// External Datasource Federation — boot-validation gate (ADR-0015, Gate 2)\nexport { ExternalValidationPlugin, createExternalValidationPlugin } from './external-validation-plugin.js';\nexport type { ExternalSchemaDriftEvent } from './external-validation-plugin.js';\n// NOTE: the runtime-UI datasource lifecycle host glue (ADR-0015 Addendum —\n// default driver factory + secret binder) was extracted into the private\n// `@objectstack/datasource-admin` package and no longer ships here.\nexport { createDispatcherPlugin } from './dispatcher-plugin.js';\nexport type { DispatcherPluginConfig } from './dispatcher-plugin.js';\nexport { createSystemEnvironmentPlugin, SYSTEM_ENVIRONMENT_ID } from './system-environment-plugin.js';\nexport type { SystemEnvironmentPluginConfig } from './system-environment-plugin.js';\n\n// Export HTTP Server Components\nexport { HttpServer } from './http-server.js';\nexport { HttpDispatcher } from './http-dispatcher.js';\nexport type { HttpProtocolContext, HttpDispatcherResult } from './http-dispatcher.js';\nexport { MiddlewareManager } from './middleware.js';\n\n// ── Security primitives ───────────────────────────────────────────────\n// Adapter-agnostic helpers for response hardening (CSP/HSTS/XCTO/…)\n// and per-IP token-bucket rate limiting. The dispatcher plugin wires\n// security headers automatically; rate limiting is exposed as a\n// primitive so adapters can mount it at the appropriate layer (see\n// `docs/guide/hardening.md`).\nexport {\n buildSecurityHeaders,\n type SecurityHeadersOptions,\n RateLimiter,\n DEFAULT_RATE_LIMITS,\n type RateLimitBucketConfig,\n type RateLimitDecision,\n type RateLimitDefaults,\n type RateLimitStore,\n} from './security/index.js';\n\n// ── Observability primitives ──────────────────────────────────────────\n// Request-id propagation (X-Request-Id + W3C traceparent), pluggable\n// MetricsRegistry, and pluggable ErrorReporter. The dispatcher plugin\n// wraps every route with instrumentation when these are configured;\n// see `docs/guide/observability.md`.\nexport {\n extractRequestId,\n generateRequestId,\n resolveRequestId,\n parseTraceparent,\n formatTraceparent,\n type TraceContext,\n NoopMetricsRegistry,\n InMemoryMetricsRegistry,\n RUNTIME_METRICS,\n type MetricsRegistry,\n type MetricSample,\n NoopErrorReporter,\n InMemoryErrorReporter,\n type ErrorReporter,\n type CapturedError,\n ObservabilityServicePlugin,\n OBSERVABILITY_METRICS_SERVICE,\n OBSERVABILITY_ERRORS_SERVICE,\n resolveMetrics,\n resolveErrorReporter,\n type ObservabilityServicePluginOptions,\n} from './observability/index.js';\n\n// Export Artifact Loader\nexport { loadArtifactBundle, mergeRuntimeModule, isHttpUrl, readArtifactSource } from './load-artifact-bundle.js';\nexport type { LoadArtifactBundleOptions } from './load-artifact-bundle.js';\n\n// ── ObjectOS Cloud Runtime (artifact-fetching shared multi-tenant host) ───────\n// Boot a host process that resolves incoming hostnames to projects and\n// dispatches every request to the matching per-project ObjectKernel. The\n// artifact is fetched either from an HTTP control plane (apps/cloud or\n// the hosted ObjectStack Cloud) or from a local JSON file for single-\n// project dev workflows. See `cloud/objectos-stack.ts`.\nexport { createObjectOSStack } from './cloud/objectos-stack.js';\nexport type { ObjectOSStackConfig, ObjectOSStackResult } from './cloud/objectos-stack.js';\nexport { MarketplaceProxyPlugin } from './cloud/marketplace-proxy-plugin.js';\nexport type { MarketplaceProxyPluginConfig } from './cloud/marketplace-proxy-plugin.js';\nexport { MarketplaceInstallLocalPlugin } from './cloud/marketplace-install-local-plugin.js';\nexport type { MarketplaceInstallLocalPluginConfig } from './cloud/marketplace-install-local-plugin.js';\nexport { RuntimeConfigPlugin } from './cloud/runtime-config-plugin.js';\nexport type { RuntimeConfigPluginConfig } from './cloud/runtime-config-plugin.js';\nexport { DEFAULT_CLOUD_URL, resolveCloudUrl } from './cloud/cloud-url.js';\nexport { ArtifactApiClient } from './cloud/artifact-api-client.js';\nexport type {\n ArtifactApiClientConfig,\n EnvironmentArtifactResponse,\n EnvironmentRuntimeConfig,\n ResolvedHostname,\n} from './cloud/artifact-api-client.js';\nexport { FileArtifactApiClient } from './cloud/file-artifact-api-client.js';\nexport type { FileArtifactApiClientConfig } from './cloud/file-artifact-api-client.js';\nexport { ArtifactEnvironmentRegistry } from './cloud/artifact-environment-registry.js';\nexport type { ArtifactEnvironmentRegistryConfig } from './cloud/artifact-environment-registry.js';\nexport { ArtifactKernelFactory } from './cloud/artifact-kernel-factory.js';\nexport type { ArtifactKernelFactoryConfig } from './cloud/artifact-kernel-factory.js';\nexport { AuthProxyPlugin } from './cloud/auth-proxy-plugin.js';\nexport { KernelManager } from './cloud/kernel-manager.js';\nexport type { EnvironmentKernelFactory, KernelManagerConfig } from './cloud/kernel-manager.js';\nexport type { EnvironmentDriverRegistry } from './cloud/environment-registry.js';\nexport {\n PLATFORM_SSO_PROVIDER_ID,\n derivePlatformSsoClientId,\n derivePlatformSsoClientSecret,\n buildPlatformSsoRedirectUri,\n seedPlatformSsoClient,\n backfillPlatformSsoClients,\n} from './cloud/platform-sso.js';\nexport type {\n SeedPlatformSsoClientOptions,\n BackfillPlatformSsoClientsOptions,\n} from './cloud/platform-sso.js';\n\n// Export Sandbox (script body runner) — engine choice is quickjs-emscripten.\n// See packages/runtime/src/sandbox/script-runner.ts for the decision rationale.\nexport { UnimplementedScriptRunner, QuickJSScriptRunner, SandboxError, hookBodyRunnerFactory, actionBodyRunnerFactory } from './sandbox/index.js';\nexport type {\n ScriptRunner,\n ScriptContext,\n ScriptOrigin,\n ScriptResult,\n ScriptRunOptions,\n QuickJSScriptRunnerOptions,\n} from './sandbox/index.js';\n\n// Re-export from @objectstack/rest\nexport {\n RestServer,\n RouteManager,\n RouteGroupBuilder,\n createRestApiPlugin,\n} from '@objectstack/rest';\nexport type {\n RouteEntry,\n RestApiPluginConfig,\n} from '@objectstack/rest';\n\n// Export Types\nexport * from '@objectstack/core';\nexport { readEnvWithDeprecation, _resetEnvDeprecationWarnings } from '@objectstack/types';\n\n\n\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectKernel, Plugin, IHttpServer, ObjectKernelConfig } from '@objectstack/core';\nimport {\n ClusterServicePlugin,\n MetadataClusterBridgePlugin,\n type ClusterServicePluginOptions,\n} from '@objectstack/service-cluster';\nimport type { ClusterCapabilityConfigInput } from '@objectstack/spec/kernel';\n\nexport interface RuntimeConfig {\n /**\n * Optional existing server instance (e.g. Hono, Express app)\n * If provided, Runtime will use it as the 'http.server' service.\n * If not provided, Runtime expects a server plugin (like HonoServerPlugin) to be registered manually.\n */\n server?: IHttpServer;\n\n /**\n * Kernel Configuration\n */\n kernel?: ObjectKernelConfig;\n\n /**\n * Cluster service configuration.\n *\n * - Omit (default): a single-node `memory` cluster is auto-registered.\n * - `false`: skip auto-registration entirely. Register your own\n * `ClusterServicePlugin` if you need it later.\n * - `ClusterCapabilityConfigInput`: forwarded to `defineCluster()`.\n * - `{ cluster: IClusterService }`: bring your own instance.\n *\n * See `content/docs/concepts/cluster-semantics.mdx` for driver options.\n */\n cluster?: false | ClusterCapabilityConfigInput | ClusterServicePluginOptions;\n}\n\n/**\n * ObjectStack Runtime\n * \n * High-level entry point for bootstrapping an ObjectStack application.\n * Wraps ObjectKernel and provides standard orchestration for:\n * - HTTP Server binding\n * - Plugin Management\n * \n * REST API is opt-in — register it explicitly:\n * ```ts\n * import { createRestApiPlugin } from '@objectstack/rest';\n * runtime.use(createRestApiPlugin());\n * ```\n */\nexport class Runtime {\n readonly kernel: ObjectKernel;\n \n constructor(config: RuntimeConfig = {}) {\n this.kernel = new ObjectKernel(config.kernel);\n \n // If external server provided, register it immediately\n if (config.server) {\n this.kernel.registerService('http.server', config.server);\n }\n\n // Auto-register cluster service (memory driver by default) unless\n // explicitly opted out. Plugins resolve it via\n // `ctx.getService<IClusterService>('cluster')`.\n if (config.cluster !== false) {\n const opts = this.normalizeClusterOptions(config.cluster);\n this.kernel.use(new ClusterServicePlugin(opts));\n // Bridge metadata cache invalidation across nodes. Late-binds\n // via kernel:ready so it picks up a metadata service whether\n // it's registered by a plugin or directly.\n this.kernel.use(new MetadataClusterBridgePlugin());\n }\n }\n\n private normalizeClusterOptions(\n raw: RuntimeConfig['cluster'],\n ): ClusterServicePluginOptions {\n if (!raw) return {};\n // Discriminate by shape: presence of `cluster` (instance) or\n // explicit `config` key means it's already an options bag.\n if (\n typeof raw === 'object' &&\n ('cluster' in raw || 'config' in raw) &&\n !('driver' in raw)\n ) {\n return raw as ClusterServicePluginOptions;\n }\n // Otherwise treat as `ClusterCapabilityConfigInput`.\n return { config: raw as ClusterCapabilityConfigInput };\n }\n \n /**\n * Register a plugin\n */\n use(plugin: Plugin) {\n this.kernel.use(plugin);\n return this;\n }\n \n /**\n * Start the runtime\n * 1. Initializes all plugins (init phase)\n * 2. Starts all plugins (start phase)\n */\n async start() {\n await this.kernel.bootstrap();\n return this;\n }\n \n /**\n * Get the kernel instance\n */\n getKernel() {\n return this.kernel;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Default host config — built-in fallback used by `objectstack start`\n * (and `objectstack serve`) when the project does NOT ship an explicit\n * `objectstack.config.ts`.\n *\n * Goal: an `objectstack build` artifact (`dist/objectstack.json`) is\n * fully self-describing — it carries the manifest, objects, views,\n * flows and a `requires: [...]` capability list. That should be enough\n * to boot a runtime, with zero hand-written host code.\n *\n * Boot mode: **standalone only**. This module deliberately has zero\n * dependency on the cloud distribution — cloud / multi-environment hosts\n * ship their own bootstrap and write their own `objectstack.config.ts`.\n *\n * Resolution order for the artifact path:\n * 1. `options.artifactPath` (explicit caller override)\n * 2. `OS_ARTIFACT_PATH` env var (file path **or** `http(s)://` URL)\n * 3. `<cwd>/dist/objectstack.json`\n *\n * The returned object is shaped like the result of `defineStack()` —\n * `{ plugins, api, requires, objects, manifest }` — so the CLI can use\n * it interchangeably with a user-authored stack config.\n */\n\nimport { resolve as resolvePath } from 'node:path';\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { createStandaloneStack, resolveObjectStackHome, type StandaloneStackConfig, type StandaloneStackResult } from './standalone-stack.js';\nimport { isHttpUrl } from './load-artifact-bundle.js';\n\nexport interface DefaultHostConfigOptions extends StandaloneStackConfig {\n /**\n * When true (the default), throws if no artifact source can be\n * resolved (no explicit `artifactPath`, no `OS_ARTIFACT_PATH` env,\n * and `<cwd>/dist/objectstack.json` does not exist).\n *\n * Set to false to allow booting an empty kernel — useful for tests\n * that want to assemble plugins manually after the stack is built.\n */\n requireArtifact?: boolean;\n}\n\nexport type DefaultHostConfigResult = StandaloneStackResult;\n\n/**\n * Resolve the artifact source for a default-host boot.\n *\n * Returns the explicit override, then `OS_ARTIFACT_PATH`, then the\n * canonical `<cwd>/dist/objectstack.json` if it exists on disk.\n * Returns `undefined` if none of these are available.\n *\n * URLs (`http(s)://`) are returned as-is — they are validated lazily by\n * the loader, since we cannot stat a remote resource cheaply.\n */\nexport function resolveDefaultArtifactPath(\n explicitPath?: string,\n cwd: string = process.cwd(),\n): string | undefined {\n const candidate = explicitPath\n ?? process.env.OS_ARTIFACT_PATH\n ?? resolvePath(cwd, 'dist/objectstack.json');\n\n if (isHttpUrl(candidate)) return candidate;\n if (explicitPath || process.env.OS_ARTIFACT_PATH) return candidate;\n return existsSync(candidate) ? candidate : undefined;\n}\n\n/**\n * Build a `defineStack()`-shaped config from an `objectstack build`\n * artifact, with no `objectstack.config.ts` required.\n *\n * @example\n * // packages/cli/src/commands/serve.ts\n * if (!fs.existsSync(absolutePath)) {\n * config = await createDefaultHostConfig();\n * }\n */\nexport async function createDefaultHostConfig(\n options: DefaultHostConfigOptions = {},\n): Promise<DefaultHostConfigResult> {\n const { requireArtifact = true, ...standaloneOpts } = options;\n\n let resolvedArtifact = resolveDefaultArtifactPath(standaloneOpts.artifactPath);\n if (!resolvedArtifact && requireArtifact) {\n throw new Error(\n '[createDefaultHostConfig] No artifact source available. ' +\n 'Set OS_ARTIFACT_PATH (file path or http(s):// URL), ' +\n 'place the artifact at <cwd>/dist/objectstack.json, ' +\n 'or pass `{ artifactPath: ... }` explicitly. ' +\n 'To boot an empty kernel anyway, pass `{ requireArtifact: false }`.',\n );\n }\n\n // Empty-boot path: synthesize a minimal artifact stub inside the\n // ObjectStack home directory so MetadataPlugin has a real file to\n // read (and to watch for marketplace installs that land later).\n if (!resolvedArtifact && !requireArtifact) {\n const home = resolveObjectStackHome();\n const stubPath = resolvePath(home, 'dist/objectstack.json');\n if (!existsSync(stubPath)) {\n mkdirSync(resolvePath(stubPath, '..'), { recursive: true });\n writeFileSync(\n stubPath,\n JSON.stringify(\n {\n manifest: {\n id: 'com.objectstack.empty',\n name: 'empty',\n version: '0.0.0',\n type: 'app',\n description: 'Empty starter kernel — install apps via the Studio marketplace.',\n },\n objects: [],\n views: [],\n apps: [],\n flows: [],\n requires: [],\n },\n null,\n 2,\n ),\n 'utf8',\n );\n }\n resolvedArtifact = stubPath;\n }\n\n return createStandaloneStack({\n ...standaloneOpts,\n artifactPath: resolvedArtifact,\n });\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Plugin, PluginContext } from '@objectstack/core';\nimport {\n ExternalSchemaMismatchError,\n type SchemaDiffEntry,\n} from '@objectstack/spec/shared';\n\n/**\n * Structural subset of `IExternalDatasourceService` used here, to avoid a hard\n * dependency on the service package from runtime.\n */\ninterface ExternalDatasourceServiceLike {\n validateAll(): Promise<{\n ok: boolean;\n results: Array<{ ok: boolean; datasource: string; object: string; diffs: SchemaDiffEntry[] }>;\n }>;\n}\n\ninterface MetadataServiceLike {\n get?: (type: string, name: string) => Promise<unknown>;\n list?: (type: string) => Promise<unknown[]>;\n}\n\ninterface DatasourceDef {\n name?: string;\n schemaMode?: string;\n external?: {\n validation?: {\n onMismatch?: 'fail' | 'warn' | 'ignore';\n checkIntervalMs?: number;\n };\n };\n}\n\n/**\n * Payload of the `external.schema.drift` event emitted on the kernel bus by the\n * background drift checker (ADR-0015 §5.2). Consumed by `audit` / `notification`\n * services. One event per drifted federated object.\n */\nexport interface ExternalSchemaDriftEvent {\n datasource: string;\n object: string;\n diffs: SchemaDiffEntry[];\n}\n\n/**\n * Boot-validation plugin — Gate 2 of ADR-0015 §5.2.\n *\n * On `kernel:ready`, validates every federated object against its remote table\n * (via the `external-datasource` service) and applies the datasource's\n * `external.validation.onMismatch` policy:\n * - `fail` → throws `ExternalSchemaMismatchError` (aborts boot) — default,\n * - `warn` → logs the diff and continues,\n * - `ignore` → does nothing.\n *\n * No-op when the `external-datasource` service is not registered (federation\n * unused).\n */\nexport class ExternalValidationPlugin implements Plugin {\n name = 'com.objectstack.external-validation';\n type = 'standard';\n version = '1.0.0';\n\n /** Active background drift-check timers, keyed by datasource name. */\n private driftTimers = new Map<string, ReturnType<typeof setInterval>>();\n\n init = (_ctx: PluginContext): void => {\n // Nothing to register; validation runs on kernel:ready (see start()).\n };\n\n start = (ctx: PluginContext): void => {\n // Subscribe to kernel-ready so validation runs after every plugin (drivers,\n // services, manifests) has been registered.\n ctx.hook('kernel:ready', async () => {\n await this.runValidation(ctx);\n // Boot validation done; arm any background drift checks (ADR-0015 §5.2).\n await this.scheduleDriftChecks(ctx);\n });\n };\n\n /** Tear down background drift-check timers (idempotent). */\n stop = (): void => {\n for (const timer of this.driftTimers.values()) clearInterval(timer);\n this.driftTimers.clear();\n };\n\n /** Exposed for testing; invoked from the kernel:ready handler. */\n async runValidation(ctx: PluginContext): Promise<void> {\n const svc = safeGet<ExternalDatasourceServiceLike>(ctx, 'external-datasource');\n if (!svc?.validateAll) {\n ctx.logger?.debug?.('[external-validation] service not registered; skipping');\n return;\n }\n\n const metadata = safeGet<MetadataServiceLike>(ctx, 'metadata');\n let report: Awaited<ReturnType<ExternalDatasourceServiceLike['validateAll']>>;\n try {\n report = await svc.validateAll();\n } catch (err) {\n ctx.logger?.warn?.('[external-validation] validateAll failed', { err });\n return;\n }\n\n const failures = report.results.filter((r) => !r.ok);\n if (failures.length === 0) {\n ctx.logger?.info?.('[external-validation] all federated objects match their remote schema', {\n objects: report.results.length,\n });\n return;\n }\n\n for (const r of failures) {\n const mode = await resolveOnMismatch(metadata, r.datasource);\n if (mode === 'ignore') continue;\n if (mode === 'warn') {\n ctx.logger?.warn?.('[external-validation] external schema drift', {\n datasource: r.datasource,\n object: r.object,\n diffs: r.diffs,\n });\n continue;\n }\n // mode === 'fail' (default)\n throw new ExternalSchemaMismatchError(r.datasource, r.object, r.diffs);\n }\n }\n\n /**\n * Arm a background drift checker for every federated datasource that declares\n * `external.validation.checkIntervalMs`. Each fires on its own interval and\n * emits `external.schema.drift` events — it never throws or aborts the\n * process, since drift past boot is observational, not fatal.\n *\n * No-op when metadata can't be enumerated or no datasource opts in. Re-arming\n * (e.g. a second `kernel:ready`) first clears existing timers so intervals\n * don't accumulate.\n */\n async scheduleDriftChecks(ctx: PluginContext): Promise<void> {\n this.stop();\n const metadata = safeGet<MetadataServiceLike>(ctx, 'metadata');\n if (!metadata?.list) return;\n\n let datasources: unknown[];\n try {\n datasources = await metadata.list('datasource');\n } catch (err) {\n ctx.logger?.warn?.('[external-validation] could not list datasources for drift checks', { err });\n return;\n }\n\n for (const def of datasources as DatasourceDef[]) {\n const interval = def?.external?.validation?.checkIntervalMs;\n const name = def?.name;\n if (!name || typeof interval !== 'number' || interval <= 0) continue;\n\n const timer = setInterval(() => {\n // Fire-and-forget: the checker swallows its own errors.\n void this.runDriftCheck(ctx, name);\n }, interval);\n // Don't let the drift timer keep the process alive on its own.\n (timer as { unref?: () => void }).unref?.();\n this.driftTimers.set(name, timer);\n ctx.logger?.info?.('[external-validation] armed background drift check', {\n datasource: name,\n intervalMs: interval,\n });\n }\n }\n\n /**\n * Re-validate one datasource's federated objects and emit an\n * `external.schema.drift` event per mismatch. Exposed for testing; invoked\n * from the interval armed by {@link scheduleDriftChecks}. Never throws.\n *\n * @returns the number of drift events emitted.\n */\n async runDriftCheck(ctx: PluginContext, datasource: string): Promise<number> {\n const svc = safeGet<ExternalDatasourceServiceLike>(ctx, 'external-datasource');\n if (!svc?.validateAll) return 0;\n\n let report: Awaited<ReturnType<ExternalDatasourceServiceLike['validateAll']>>;\n try {\n report = await svc.validateAll();\n } catch (err) {\n ctx.logger?.warn?.('[external-validation] drift check validateAll failed', {\n datasource,\n err,\n });\n return 0;\n }\n\n const drifted = report.results.filter((r) => !r.ok && r.datasource === datasource);\n for (const r of drifted) {\n const event: ExternalSchemaDriftEvent = {\n datasource: r.datasource,\n object: r.object,\n diffs: r.diffs,\n };\n try {\n await ctx.trigger('external.schema.drift', event);\n } catch (err) {\n ctx.logger?.warn?.('[external-validation] failed to emit drift event', {\n datasource,\n object: r.object,\n err,\n });\n }\n }\n if (drifted.length > 0) {\n ctx.logger?.warn?.('[external-validation] background drift detected', {\n datasource,\n objects: drifted.map((r) => r.object),\n });\n }\n return drifted.length;\n }\n}\n\n/** Convenience factory mirroring the createXxxPlugin convention. */\nexport function createExternalValidationPlugin(): ExternalValidationPlugin {\n return new ExternalValidationPlugin();\n}\n\nasync function resolveOnMismatch(\n metadata: MetadataServiceLike | undefined,\n datasource: string,\n): Promise<'fail' | 'warn' | 'ignore'> {\n try {\n const ds = (await metadata?.get?.('datasource', datasource)) as DatasourceDef | undefined;\n return ds?.external?.validation?.onMismatch ?? 'fail';\n } catch {\n return 'fail';\n }\n}\n\nfunction safeGet<T>(ctx: PluginContext, name: string): T | undefined {\n try {\n return ctx.getService<T>(name);\n } catch {\n return undefined;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectKernel, getEnv, resolveLocale } from '@objectstack/core';\nimport { CoreServiceName } from '@objectstack/spec/system';\nimport { pluralToSingular, PLURAL_TO_SINGULAR } from '@objectstack/spec/shared';\nimport type { ExecutionContext } from '@objectstack/spec/kernel';\nimport type { KernelManager } from './cloud/kernel-manager.js';\nimport { setPackageDisabled } from './package-state-store.js';\n\n/** Minimal local interface — full EnvironmentScopeManager was removed in Phase R. */\ninterface EnvironmentScopeManager {\n touch(environmentId: string): void;\n}\nimport {\n resolveExecutionContext,\n isPermissionDeniedError,\n} from './security/resolve-execution-context.js';\n\n/** Browser-safe UUID generator — prefers Web Crypto, falls back to RFC 4122 v4 */\nfunction randomUUID(): string {\n if (globalThis.crypto && typeof globalThis.crypto.randomUUID === 'function') {\n return globalThis.crypto.randomUUID();\n }\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\nexport interface HttpProtocolContext {\n request: any;\n response?: any;\n environmentId?: string; // Resolved environment ID\n dataDriver?: any; // IDataDriver - Resolved environment-scoped driver\n /**\n * Identity envelope resolved by `resolveExecutionContext` and threaded\n * into every ObjectQL call so the SecurityPlugin middleware can apply\n * RBAC/RLS/FLS. Optional — anonymous requests carry an empty context.\n */\n executionContext?: ExecutionContext;\n}\n\nexport interface HttpDispatcherResult {\n handled: boolean;\n response?: {\n status: number;\n body?: any;\n headers?: Record<string, string>;\n };\n result?: any; // For flexible return types or direct response objects (Response/NextResponse)\n}\n\n/**\n * Optional configuration passed to the dispatcher constructor. Supports the\n * legacy `enforceProjectMembership` toggle plus the new multi-kernel\n * scheduling hook required by ADR-0003's cloud runtime mode.\n */\nexport interface HttpDispatcherOptions {\n enforceProjectMembership?: boolean;\n /**\n * Optional {@link KernelManager}. When present, the dispatcher resolves\n * `context.environmentId` first and then routes the request against the\n * project's dedicated kernel via `kernelManager.getOrCreate(environmentId)`.\n * Requests that fail to resolve a environmentId fall through to the\n * constructor-supplied kernel (self-hosted / legacy behavior).\n */\n kernelManager?: KernelManager;\n /**\n * Optional {@link EnvironmentScopeManager}. When present, `touch(environmentId)` is\n * called on every scoped request so idle projects are evicted after TTL.\n */\n scopeManager?: EnvironmentScopeManager;\n}\n\n/**\n * @deprecated Use `createDispatcherPlugin()` from `@objectstack/runtime` instead.\n * This class will be removed in v2. Prefer the plugin-based approach:\n * ```ts\n * import { createDispatcherPlugin } from '@objectstack/runtime';\n * kernel.use(createDispatcherPlugin({ prefix: '/api/v1' }));\n * ```\n */\nexport class HttpDispatcher {\n private kernel: any; // Casting to any to access dynamic props like services, graphql\n private defaultKernel: ObjectKernel;\n private envRegistry?: any; // EnvironmentDriverRegistry\n private defaultProject?: { environmentId: string; orgId?: string };\n private kernelManager?: KernelManager;\n private scopeManager?: EnvironmentScopeManager;\n /**\n * When `true`, scoped data-plane routes enforce a\n * `sys_environment_member` lookup and return 403 for non-members.\n * Defaults to `true` when a environmentId is resolvable — legacy callers\n * can opt out via the third constructor argument (see\n * `DispatcherConfig.enforceProjectMembership`).\n */\n private enforceMembership: boolean;\n /**\n * In-memory cache of positive membership checks, keyed by\n * `${environmentId}:${userId}`. Entries expire 60 seconds after insertion\n * — a short TTL is acceptable because a user whose access was just\n * revoked sees stale access for at most one minute.\n */\n private membershipCache: Map<string, number> = new Map();\n private static readonly MEMBERSHIP_CACHE_TTL_MS = 60_000;\n /** Well-known system project id — bypassed for any authenticated user. */\n private static readonly SYSTEM_ENVIRONMENT_ID = '00000000-0000-0000-0000-000000000001';\n /** Well-known platform org id — members bypass project membership. */\n private static readonly PLATFORM_ORG_ID = '00000000-0000-0000-0000-000000000000';\n\n constructor(kernel: ObjectKernel, envRegistry?: any, options?: HttpDispatcherOptions) {\n this.kernel = kernel;\n this.defaultKernel = kernel;\n const resolveService = (name: string): any => {\n try { return (kernel as any).getService?.(name); } catch { return undefined; }\n };\n this.envRegistry = envRegistry ?? resolveService('env-registry');\n this.enforceMembership = options?.enforceProjectMembership ?? true;\n this.kernelManager = options?.kernelManager ?? resolveService('kernel-manager');\n this.scopeManager = options?.scopeManager ?? resolveService('scope-manager');\n // Single-project default is resolved lazily on first request — the\n // plugin that registers it (`createSingleEnvironmentPlugin`) may run\n // its `init()` after the HttpDispatcher is constructed.\n }\n\n private resolveDefaultProject(): { environmentId: string; orgId?: string } | undefined {\n if (this.defaultProject) return this.defaultProject;\n try {\n const v = (this.kernel as any).getService?.('default-project');\n if (v?.environmentId) {\n this.defaultProject = v;\n return v;\n }\n } catch {\n // service not registered — single-environment plugin not in stack\n }\n return undefined;\n }\n\n private success(data: any, meta?: any) {\n return {\n status: 200,\n body: { success: true, data, meta }\n };\n }\n\n private error(message: string, code: number = 500, details?: any) {\n return {\n status: code,\n body: { success: false, error: { message, code, details } }\n };\n }\n\n /**\n * 404 Route Not Found — no route is registered for this path.\n */\n private routeNotFound(route: string) {\n return {\n status: 404,\n body: {\n success: false,\n error: {\n code: 404,\n message: `Route Not Found: ${route}`,\n type: 'ROUTE_NOT_FOUND' as const,\n route,\n hint: 'No route is registered for this path. Check the API discovery endpoint for available routes.',\n },\n },\n };\n }\n\n /**\n * Direct data service dispatch — replaces broker.call('data.*').\n * Tries protocol service first (supports expand/populate), falls back to ObjectQL.\n *\n * @param dataDriver - Optional environment-scoped driver to use instead of kernel default\n * @param scopeId - Optional project ID for scoped service resolution (SharedProjectPlugin mode)\n */\n private async callData(\n action: string,\n params: any,\n dataDriver?: any,\n scopeId?: string,\n executionContext?: ExecutionContext,\n ): Promise<any> {\n const protocol = await this.resolveService('protocol', scopeId);\n const qlService = dataDriver ?? await this.getObjectQLService(scopeId);\n const ql = qlService ?? await this.resolveService('objectql', scopeId);\n const qlOpts = executionContext ? { context: executionContext } : undefined;\n const findOpts = (extra?: any) => {\n const base = qlOpts ? { ...qlOpts } : {};\n return extra ? { ...base, ...extra } : (qlOpts ? base : undefined);\n };\n\n if (action === 'create') {\n if (ql) {\n const res = await ql.insert(params.object, params.data, qlOpts);\n const record = { ...params.data, ...res };\n return { object: params.object, id: record.id, record };\n }\n throw { statusCode: 503, message: 'Data service not available' };\n }\n\n if (action === 'get') {\n if (protocol && typeof protocol.getData === 'function') {\n return await protocol.getData({ object: params.object, id: params.id, expand: params.expand, select: params.select, context: executionContext });\n }\n if (ql) {\n let all = await ql.find(params.object, findOpts({ where: { id: params.id }, limit: 1 }));\n if (all && (all as any).value) all = (all as any).value;\n if (!all) all = [];\n const match = (all as any[]).find((i: any) => i.id === params.id);\n return match ? { object: params.object, id: params.id, record: match } : null;\n }\n throw { statusCode: 503, message: 'Data service not available' };\n }\n\n if (action === 'update') {\n if (ql && params.id) {\n let all = await ql.find(params.object, findOpts({ where: { id: params.id }, limit: 1 }));\n if (all && (all as any).value) all = (all as any).value;\n if (!all) all = [];\n const existing = (all as any[]).find((i: any) => i.id === params.id);\n if (!existing) throw new Error('[ObjectStack] Not Found');\n await ql.update(params.object, params.data, findOpts({ where: { id: params.id } }));\n return { object: params.object, id: params.id, record: { ...existing, ...params.data } };\n }\n throw { statusCode: 503, message: 'Data service not available' };\n }\n\n if (action === 'delete') {\n if (ql) {\n await ql.delete(params.object, findOpts({ where: { id: params.id } }));\n return { object: params.object, id: params.id, deleted: true };\n }\n throw { statusCode: 503, message: 'Data service not available' };\n }\n\n if (action === 'query' || action === 'find') {\n if (protocol && typeof protocol.findData === 'function') {\n // Build query: use explicit params.query if provided, otherwise extract query fields from params\n const query = params.query || (() => {\n const { object, ...rest } = params;\n return rest;\n })();\n return await protocol.findData({ object: params.object, query, context: executionContext });\n }\n if (ql) {\n let all = await ql.find(params.object, qlOpts);\n if (!Array.isArray(all) && all && (all as any).value) all = (all as any).value;\n if (!all) all = [];\n return { object: params.object, records: all, total: all.length };\n }\n throw { statusCode: 503, message: 'Data service not available' };\n }\n\n if (action === 'batch') {\n // Batch operations — not yet supported via direct service dispatch\n return { object: params.object, results: [] };\n }\n\n throw { statusCode: 400, message: `Unknown data action: ${action}` };\n }\n\n /**\n * Parse a project UUID out of a scoped URL path such as\n * `/api/v1/environments/abc-123/data/task` or `/projects/abc-123/meta`.\n * Returns `undefined` when the path does not match the scoped pattern.\n */\n /**\n * Parse an environment UUID out of a scoped URL path such as\n * `/api/v1/environments/abc-123/data/task` or `/environments/abc-123/meta`.\n * Returns `undefined` when the path does not match the scoped pattern.\n */\n private extractEnvironmentIdFromPath(path: string): string | undefined {\n if (!path) return undefined;\n const m = path.match(/\\/environments\\/([^/?#]+)/);\n if (!m) return undefined;\n const candidate = m[1];\n // Guard against matching control-plane routes like /cloud/environments.\n // `/environments/<id>` directly nested under the API prefix wins;\n // `/cloud/environments/<id>` is a CRUD endpoint on the control plane.\n if (path.includes('/cloud/environments/')) return undefined;\n return candidate;\n }\n\n /**\n * Resolve environment context for incoming request.\n *\n * Precedence:\n * 0. URL path matches `/environments/:environmentId/...` OR request.params.environmentId set by router\n * → envRegistry.resolveById(id)\n * 1. request.headers.host → envRegistry.resolveByHostname(host)\n * 2. request.headers['x-environment-id'] → envRegistry.resolveById(id)\n * 3. session.activeEnvironmentId → envRegistry.resolveById(id)\n * 4. session.activeOrganizationId → find default project → envRegistry.resolveById(id)\n * 5. single-environment default (registered by `createSingleEnvironmentPlugin`)\n * → envRegistry.resolveById(defaultProject.environmentId). Lets bare\n * `/api/v1/data/...` URLs resolve to the lone project in\n * `cloudUrl: 'local'` deployments.\n *\n * Skip for paths: /auth, /cloud, /health, /discovery (NOT /meta when scoped,\n * so project-scoped meta routes can resolve their project).\n */\n private async resolveEnvironmentContext(context: HttpProtocolContext, path: string): Promise<void> {\n // Skip environment resolution for control-plane routes only.\n // NOTE: /meta is intentionally not in this list — a scoped\n // /projects/:id/meta path still needs the project resolved so the\n // protocol can scope its answer.\n // NOTE: /auth was removed — per-project AuthPlugin needs the\n // hostname-resolved environmentId so the dispatcher kernel-swap routes\n // to the project's auth manager (not the host's).\n const skipPaths = ['/cloud', '/health', '/discovery'];\n if (skipPaths.some(p => path.startsWith(p))) {\n return;\n }\n\n // If no environment registry, skip\n if (!this.envRegistry) {\n return;\n }\n\n // Headers may arrive as a Fetch API `Headers` instance (Hono's\n // `c.req.raw`) — where `.host` / `['x-environment-id']` both return\n // undefined — or as a plain object (Vercel's incoming message\n // shape). Normalise to a single `.get(name)` accessor so both\n // layouts resolve correctly.\n const headers = context.request?.headers;\n const getHeader = (name: string): string | undefined => {\n if (!headers) return undefined;\n const h: any = headers;\n if (typeof h.get === 'function') {\n const v = h.get(name);\n return v == null ? undefined : String(v);\n }\n const lower = name.toLowerCase();\n for (const k of Object.keys(h)) {\n if (k.toLowerCase() === lower) {\n const v = h[k];\n return Array.isArray(v) ? v[0] : (v == null ? undefined : String(v));\n }\n }\n return undefined;\n };\n\n try {\n // 0. Try URL-param / path-embedded environmentId (highest precedence).\n const urlEnvironmentId = this.extractEnvironmentIdFromPath(path)\n ?? context.request?.params?.environmentId;\n if (urlEnvironmentId) {\n const driver = await this.envRegistry.resolveById(urlEnvironmentId);\n if (driver) {\n context.environmentId = urlEnvironmentId;\n context.dataDriver = driver;\n return;\n }\n }\n\n // 1. Try hostname resolution\n const host = getHeader('host');\n if (host) {\n // Strip port if present (e.g., \"localhost:3000\" → \"localhost\")\n const hostname = host.split(':')[0];\n const result = await this.envRegistry.resolveByHostname(hostname);\n if (result) {\n context.environmentId = result.environmentId;\n context.dataDriver = result.driver;\n return;\n }\n }\n\n // 2. Try X-Environment-Id header\n const envIdHeader = getHeader('x-environment-id');\n if (envIdHeader) {\n const driver = await this.envRegistry.resolveById(envIdHeader);\n if (driver) {\n context.environmentId = envIdHeader;\n context.dataDriver = driver;\n return;\n }\n }\n\n // 3. Try session.activeEnvironmentId\n try {\n const authService: any = await this.getService(CoreServiceName.enum.auth);\n const sessionData = await authService?.api?.getSession?.({\n headers: context.request?.headers,\n });\n\n const activeEnvironmentId = sessionData?.session?.activeEnvironmentId ?? sessionData?.session?.activeEnvironmentId;\n if (activeEnvironmentId) {\n const driver = await this.envRegistry.resolveById(activeEnvironmentId);\n if (driver) {\n context.environmentId = activeEnvironmentId;\n context.dataDriver = driver;\n return;\n }\n }\n\n // 4. Try default environment for organization\n const activeOrganizationId = sessionData?.session?.activeOrganizationId;\n if (activeOrganizationId) {\n // Query control plane for default environment\n const qlService = await this.getObjectQLService();\n const ql = qlService ?? await this.resolveService('objectql');\n if (ql) {\n let rows = await ql.find('sys_environment', {\n where: {\n organization_id: activeOrganizationId,\n is_default: true\n },\n limit: 1\n } as any);\n if (rows && (rows as any).value) rows = (rows as any).value;\n if (Array.isArray(rows) && rows[0]) {\n const defaultEnv = rows[0];\n const driver = await this.envRegistry.resolveById(defaultEnv.id);\n if (driver) {\n context.environmentId = defaultEnv.id;\n context.dataDriver = driver;\n return;\n }\n }\n }\n }\n } catch (sessionError) {\n // Session resolution failed, continue without environment context\n console.debug('[HttpDispatcher] Session resolution failed:', sessionError);\n }\n\n // 5. Single-project default fallback. Registered by\n // `createSingleEnvironmentPlugin()` in `cloudUrl: 'local'` boot\n // shapes (apps/objectos default). Lets bare URLs like\n // `/api/v1/data/account` resolve to the lone project.\n if (this.defaultProject?.environmentId || this.resolveDefaultProject()) {\n const def = this.defaultProject!;\n const driver = await this.envRegistry.resolveById(def.environmentId);\n if (driver) {\n context.environmentId = def.environmentId;\n context.dataDriver = driver;\n return;\n }\n }\n } catch (error) {\n console.error('[HttpDispatcher] Environment resolution failed:', error);\n }\n }\n\n /**\n * Check whether the authenticated user is a member of\n * `context.environmentId`. Runs after {@link resolveEnvironmentContext}\n * and is a no-op when:\n *\n * - Membership enforcement is disabled via the constructor.\n * - The route is control-plane (`/auth/*`, `/cloud/*`, `/health`,\n * `/discovery`) — already skipped upstream.\n * - No `environmentId` was resolved (e.g. unscoped legacy routes).\n * - The project is the well-known system project (bypassed so any\n * authenticated user can read platform metadata).\n * - The user's active organization is the platform org (staff).\n *\n * Positive results are cached for 60 seconds to avoid hitting the\n * control-plane on every request. A failed check returns a 403\n * response object that callers should surface directly — no further\n * dispatch happens.\n */\n private async enforceProjectMembership(\n context: HttpProtocolContext,\n path: string,\n ): Promise<{ status: number; body: any } | null> {\n if (!this.enforceMembership) return null;\n\n // Control-plane paths — never gated by project membership.\n const skipPaths = ['/auth', '/cloud', '/health', '/discovery'];\n if (skipPaths.some(p => path.startsWith(p))) return null;\n\n const environmentId = context.environmentId;\n if (!environmentId) return null; // Unscoped legacy routes fall through.\n\n // System project is always reachable by any authenticated user.\n if (environmentId === HttpDispatcher.SYSTEM_ENVIRONMENT_ID) return null;\n\n // Read the session. If auth is not wired up, fail open — tests\n // and single-tenant setups run without auth.\n let userId: string | undefined;\n let activeOrganizationId: string | undefined;\n try {\n const authService: any = await this.resolveService(CoreServiceName.enum.auth);\n const sessionData = await authService?.api?.getSession?.({\n headers: context.request?.headers,\n });\n userId = sessionData?.user?.id ?? sessionData?.session?.userId;\n activeOrganizationId = sessionData?.session?.activeOrganizationId;\n } catch {\n // Auth resolution failed — do not block the request on RBAC.\n return null;\n }\n\n if (!userId) return null; // Anonymous requests — upstream auth will decide.\n\n // Platform-org members bypass project membership.\n if (activeOrganizationId === HttpDispatcher.PLATFORM_ORG_ID) return null;\n\n // Check cache.\n const cacheKey = `${environmentId}:${userId}`;\n const cached = this.membershipCache.get(cacheKey);\n const now = Date.now();\n if (cached && now - cached < HttpDispatcher.MEMBERSHIP_CACHE_TTL_MS) {\n return null; // Recently verified as a member.\n }\n if (cached) {\n this.membershipCache.delete(cacheKey); // expired\n }\n\n // Query sys_environment_member (control plane).\n try {\n const qlService = await this.getObjectQLService();\n const ql = qlService ?? await this.resolveService('objectql');\n if (!ql) return null; // No QL — cannot enforce; fail open.\n\n let rows = await ql.find('sys_environment_member', {\n where: { environment_id: environmentId, user_id: userId },\n limit: 1,\n } as any);\n if (rows && (rows as any).value) rows = (rows as any).value;\n const isMember = Array.isArray(rows) && rows.length > 0;\n\n if (isMember) {\n this.membershipCache.set(cacheKey, now);\n return null;\n }\n\n return this.error(\n `Forbidden: user ${userId} is not a member of project ${environmentId}`,\n 403,\n { environmentId, userId, type: 'PROJECT_MEMBERSHIP_REQUIRED' },\n );\n } catch (err) {\n // Control-plane lookup failure — log and fail open rather than\n // break the request. Tightening this is deferred to Phase 4.\n console.debug('[HttpDispatcher] Membership check failed:', err);\n return null;\n }\n }\n\n /**\n * Generates the discovery JSON response for the API root.\n *\n * Uses the same async `resolveService()` fallback chain that request\n * handlers use, so the reported service status is always consistent\n * with the actual runtime availability.\n */\n async getDiscoveryInfo(prefix: string) {\n // Resolve all services through the same async fallback chain\n // that request handlers (handleI18n, handleAuth, …) use.\n const [\n authSvc, graphqlSvc, searchSvc, realtimeSvc, filesSvc,\n analyticsSvc, workflowSvc, aiSvc, notificationSvc, i18nSvc,\n uiSvc, automationSvc, cacheSvc, queueSvc, jobSvc,\n ] = await Promise.all([\n this.resolveService(CoreServiceName.enum.auth),\n this.resolveService(CoreServiceName.enum.graphql),\n this.resolveService(CoreServiceName.enum.search),\n this.resolveService(CoreServiceName.enum.realtime),\n this.resolveService(CoreServiceName.enum['file-storage']),\n this.resolveService(CoreServiceName.enum.analytics),\n this.resolveService(CoreServiceName.enum.workflow),\n this.resolveService(CoreServiceName.enum.ai),\n this.resolveService(CoreServiceName.enum.notification),\n this.resolveService(CoreServiceName.enum.i18n),\n this.resolveService(CoreServiceName.enum.ui),\n this.resolveService(CoreServiceName.enum.automation),\n this.resolveService(CoreServiceName.enum.cache),\n this.resolveService(CoreServiceName.enum.queue),\n this.resolveService(CoreServiceName.enum.job),\n ]);\n\n const hasAuth = !!authSvc;\n const hasGraphQL = !!(graphqlSvc || this.kernel.graphql);\n const hasSearch = !!searchSvc;\n const hasWebSockets = !!realtimeSvc;\n const hasFiles = !!filesSvc;\n const hasAnalytics = !!analyticsSvc;\n const hasWorkflow = !!workflowSvc;\n const hasAi = !!aiSvc;\n const hasNotification = !!notificationSvc;\n const hasI18n = !!i18nSvc;\n const hasUi = !!uiSvc;\n const hasAutomation = !!automationSvc;\n const hasCache = !!cacheSvc;\n const hasQueue = !!queueSvc;\n const hasJob = !!jobSvc;\n\n // Routes are only exposed when a plugin provides the service\n const routes = {\n data: `${prefix}/data`,\n metadata: `${prefix}/meta`,\n packages: `${prefix}/packages`,\n auth: hasAuth ? `${prefix}/auth` : undefined,\n ui: hasUi ? `${prefix}/ui` : undefined,\n graphql: hasGraphQL ? `${prefix}/graphql` : undefined,\n storage: hasFiles ? `${prefix}/storage` : undefined,\n analytics: hasAnalytics ? `${prefix}/analytics` : undefined,\n automation: hasAutomation ? `${prefix}/automation` : undefined,\n workflow: hasWorkflow ? `${prefix}/workflow` : undefined,\n realtime: hasWebSockets ? `${prefix}/realtime` : undefined,\n notifications: hasNotification ? `${prefix}/notifications` : undefined,\n ai: hasAi ? `${prefix}/ai` : undefined,\n i18n: hasI18n ? `${prefix}/i18n` : undefined,\n };\n\n // Build per-service status map\n // handlerReady: true means the dispatcher has a real, bound handler for this route.\n // handlerReady: false means the route is present in the discovery table but may not\n // yet have a concrete implementation or may be served by a stub.\n const svcAvailable = (route?: string, provider?: string) => ({\n enabled: true, status: 'available' as const, handlerReady: true, route, provider,\n });\n const svcUnavailable = (name: string) => ({\n enabled: false, status: 'unavailable' as const, handlerReady: false,\n message: `Install a ${name} plugin to enable`,\n });\n\n // Derive locale info from actual i18n service when available\n let locale = { default: 'en', supported: ['en'], timezone: 'UTC' };\n if (hasI18n && i18nSvc) {\n const defaultLocale = typeof i18nSvc.getDefaultLocale === 'function'\n ? i18nSvc.getDefaultLocale() : 'en';\n const locales = typeof i18nSvc.getLocales === 'function'\n ? i18nSvc.getLocales() : [];\n locale = {\n default: defaultLocale,\n supported: locales.length > 0 ? locales : [defaultLocale],\n timezone: 'UTC',\n };\n }\n\n return {\n name: 'ObjectOS',\n version: '1.0.0',\n environment: getEnv('NODE_ENV', 'development'),\n routes,\n endpoints: routes, // Alias for backward compatibility with some clients\n features: {\n graphql: hasGraphQL,\n search: hasSearch,\n websockets: hasWebSockets,\n files: hasFiles,\n analytics: hasAnalytics,\n ai: hasAi,\n workflow: hasWorkflow,\n notifications: hasNotification,\n i18n: hasI18n,\n },\n services: {\n // Kernel-provided (always available via protocol implementation)\n metadata: { enabled: true, status: 'degraded' as const, handlerReady: true, route: routes.metadata, provider: 'kernel', message: 'In-memory registry; DB persistence pending' },\n data: svcAvailable(routes.data, 'kernel'),\n // Plugin-provided — only available when a plugin registers the service\n auth: hasAuth ? svcAvailable(routes.auth) : svcUnavailable('auth'),\n automation: hasAutomation ? svcAvailable(routes.automation) : svcUnavailable('automation'),\n analytics: hasAnalytics ? svcAvailable(routes.analytics) : svcUnavailable('analytics'),\n cache: hasCache ? svcAvailable() : svcUnavailable('cache'),\n queue: hasQueue ? svcAvailable() : svcUnavailable('queue'),\n job: hasJob ? svcAvailable() : svcUnavailable('job'),\n ui: hasUi ? svcAvailable(routes.ui) : svcUnavailable('ui'),\n workflow: hasWorkflow ? svcAvailable(routes.workflow) : svcUnavailable('workflow'),\n realtime: hasWebSockets ? svcAvailable(routes.realtime) : svcUnavailable('realtime'),\n notification: hasNotification ? svcAvailable(routes.notifications) : svcUnavailable('notification'),\n ai: hasAi ? svcAvailable(routes.ai) : svcUnavailable('ai'),\n i18n: hasI18n ? svcAvailable(routes.i18n) : svcUnavailable('i18n'),\n graphql: hasGraphQL ? svcAvailable(routes.graphql) : svcUnavailable('graphql'),\n 'file-storage': hasFiles ? svcAvailable(routes.storage) : svcUnavailable('file-storage'),\n search: hasSearch ? svcAvailable() : svcUnavailable('search'),\n },\n locale,\n };\n }\n\n /**\n * Handles GraphQL requests\n */\n async handleGraphQL(body: { query: string; variables?: any }, context: HttpProtocolContext) {\n if (!body || !body.query) {\n throw { statusCode: 400, message: 'Missing query in request body' };\n }\n \n if (typeof this.kernel.graphql !== 'function') {\n throw { statusCode: 501, message: 'GraphQL service not available' };\n }\n\n return this.kernel.graphql(body.query, body.variables, { \n request: context.request \n });\n }\n\n /**\n * Handles Auth requests\n * path: sub-path after /auth/\n */\n async handleAuth(path: string, method: string, body: any, context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n // 1. Try generic Auth Service\n const authService = await this.getService(CoreServiceName.enum.auth);\n if (authService && typeof authService.handler === 'function') {\n const response = await authService.handler(context.request, context.response);\n return { handled: true, result: response };\n }\n\n // 2. Mock fallback for MSW/test environments when no auth service is registered\n const normalizedPath = path.replace(/^\\/+/, '');\n return this.mockAuthFallback(normalizedPath, method, body);\n }\n\n /**\n * Provides mock auth responses for core better-auth endpoints when\n * AuthPlugin is not loaded (e.g. MSW/browser-only environments).\n * This ensures registration/sign-in flows do not 404 in mock mode.\n */\n private mockAuthFallback(path: string, method: string, body: any): HttpDispatcherResult {\n const m = method.toUpperCase();\n const MOCK_SESSION_EXPIRY_MS = 86_400_000; // 24 hours\n\n // POST sign-up/email\n if ((path === 'sign-up/email' || path === 'register') && m === 'POST') {\n const id = `mock_${randomUUID()}`;\n return {\n handled: true,\n response: {\n status: 200,\n body: {\n user: { id, name: body?.name || 'Mock User', email: body?.email || 'mock@test.local', emailVerified: false, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() },\n session: { id: `session_${id}`, userId: id, token: `mock_token_${id}`, expiresAt: new Date(Date.now() + MOCK_SESSION_EXPIRY_MS).toISOString() },\n },\n },\n };\n }\n\n // POST sign-in/email or login\n if ((path === 'sign-in/email' || path === 'login') && m === 'POST') {\n const id = `mock_${randomUUID()}`;\n return {\n handled: true,\n response: {\n status: 200,\n body: {\n user: { id, name: 'Mock User', email: body?.email || 'mock@test.local', emailVerified: true, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() },\n session: { id: `session_${id}`, userId: id, token: `mock_token_${id}`, expiresAt: new Date(Date.now() + MOCK_SESSION_EXPIRY_MS).toISOString() },\n },\n },\n };\n }\n\n // GET get-session\n if (path === 'get-session' && m === 'GET') {\n return {\n handled: true,\n response: { status: 200, body: { session: null, user: null } },\n };\n }\n\n // POST sign-out\n if (path === 'sign-out' && m === 'POST') {\n return {\n handled: true,\n response: { status: 200, body: { success: true } },\n };\n }\n\n return { handled: false };\n }\n\n /**\n * Handles Metadata requests\n * Standard: /metadata/:type/:name\n * Fallback for backward compat: /metadata (all objects), /metadata/:objectName (get object)\n */\n async handleMetadata(path: string, _context: HttpProtocolContext, method?: string, body?: any, query?: any): Promise<HttpDispatcherResult> {\n const parts = path.replace(/^\\/+/, '').split('/').filter(Boolean);\n \n // GET /metadata/types\n if (parts[0] === 'types') {\n // PRIORITY 1: Try protocol service — it returns BOTH legacy\n // `types: string[]` AND the richer `entries` array (with\n // JSON Schemas, allowOrgOverride flags, domain, etc) needed by\n // the metadata admin UI. It internally also merges\n // MetadataService runtime types, so this path is strictly richer.\n const protocol = await this.resolveService('protocol');\n if (protocol && typeof protocol.getMetaTypes === 'function') {\n try {\n const result = await protocol.getMetaTypes({});\n return { handled: true, response: this.success(result) };\n } catch (e: any) {\n console.warn('[HttpDispatcher] protocol.getMetaTypes() failed:', e?.message);\n }\n }\n // PRIORITY 2: MetadataService fallback (types only, no entries)\n const metadataService = await this.resolveService('metadata', _context.environmentId);\n if (metadataService && typeof (metadataService as any).getRegisteredTypes === 'function') {\n try {\n const types = await (metadataService as any).getRegisteredTypes();\n return { handled: true, response: this.success({ types }) };\n } catch (e: any) {\n console.warn('[HttpDispatcher] MetadataService.getRegisteredTypes() failed:', e.message);\n }\n }\n // Last resort: hardcoded defaults\n return { handled: true, response: this.success({ types: ['object', 'app', 'plugin'] }) };\n }\n\n // GET /metadata/objects/:name/state/:field?from=:state\n // ADR-0020 D3.3 introspection: the legal next states declared by the\n // object's `state_machine` validation rule for `:field`. Lets UIs /\n // AI authors ask \"from here, where can this record go?\" instead of\n // hard-coding the transition table. Returns `next: null` when no FSM\n // governs the field, `next: []` for a declared dead-end state.\n if (parts.length === 4 && (parts[0] === 'objects' || parts[0] === 'object') && parts[2] === 'state' && (!method || method === 'GET')) {\n const name = parts[1];\n const field = parts[3];\n const from = query?.from !== undefined ? String(query.from) : undefined;\n const qlService = await this.getObjectQLService();\n const schema = qlService?.registry?.getObject(name);\n if (!schema) return { handled: true, response: this.error('Object not found', 404) };\n // Dynamic import (matches the runtime convention for @objectstack/objectql)\n // so the dispatcher module graph doesn't statically pull in the objectql barrel.\n const { legalNextStates } = await import('@objectstack/objectql');\n const next = from === undefined ? null : legalNextStates(schema, field, from);\n return { handled: true, response: this.success({ object: name, field, from: from ?? null, next }) };\n }\n\n // GET /metadata/:type/:name(/:subname...)/published → get published version\n // Supports compound names like `lead/views/all_leads/published`.\n if (parts.length >= 3 && parts[parts.length - 1] === 'published' && (!method || method === 'GET')) {\n const type = parts[0];\n const name = parts.slice(1, -1).join('/');\n const metadataService = await this.getService(CoreServiceName.enum.metadata);\n if (metadataService && typeof (metadataService as any).getPublished === 'function') {\n const data = await (metadataService as any).getPublished(type, name);\n if (data === undefined) return { handled: true, response: this.error('Not found', 404) };\n return { handled: true, response: this.success(data) };\n }\n // Fallback — try MetadataService via resolveService\n const metaSvc = await this.resolveService('metadata', _context.environmentId);\n if (metaSvc && typeof (metaSvc as any).getPublished === 'function') {\n try {\n const fallbackData = await (metaSvc as any).getPublished(type, name);\n if (fallbackData !== undefined) return { handled: true, response: this.success(fallbackData) };\n } catch { /* fall through */ }\n }\n return { handled: true, response: this.error('Not found', 404) };\n }\n\n // /metadata/:type/:name where :name may itself contain slashes\n // (e.g. /metadata/lead/views/all_leads → type='lead', name='views/all_leads').\n // Compound names are how the client expresses sub-resources of a type\n // (a view of an object, a flow under an automation, etc.) and the\n // metadata service treats the full string as the lookup key.\n if (parts.length >= 2) {\n const type = parts[0];\n const name = parts.slice(1).join('/');\n // Extract optional package filter from query string\n const packageId = query?.package || undefined;\n\n // PUT /metadata/:type/:name (Save)\n if (method === 'PUT' && body) {\n // Try to get the protocol service directly\n const protocol = await this.resolveService('protocol');\n\n if (protocol && typeof protocol.saveMetaItem === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const result = await protocol.saveMetaItem({ type, name, item: body, organizationId, ...(packageId ? { packageId } : {}) });\n return { handled: true, response: this.success(result) };\n } catch (e: any) {\n return { handled: true, response: this.error(e.message, 400) };\n }\n }\n\n // Fallback: try MetadataService directly\n const metaSvc = await this.resolveService('metadata', _context.environmentId);\n if (metaSvc && typeof (metaSvc as any).saveItem === 'function') {\n try {\n const data = await (metaSvc as any).saveItem(type, name, body);\n return { handled: true, response: this.success(data) };\n } catch (e: any) {\n return { handled: true, response: this.error(e.message || 'Save not supported', 501) };\n }\n }\n return { handled: true, response: this.error('Save not supported', 501) };\n }\n\n try {\n // Try specific calls based on type\n if (type === 'objects' || type === 'object') {\n // Check whether the kernel is project-scoped. When it is,\n // the process-wide SchemaRegistry is unsafe to query\n // directly — it would return objects that other projects\n // wrote in this same process. Route through the Protocol\n // service (which filters sys_metadata by environment_id) in that\n // case, and fall back to the registry only for the\n // unscoped (single-kernel / control-plane) path.\n const protocol = await this.resolveService('protocol') as any;\n const scopedEnv = typeof protocol?.getProjectId === 'function'\n ? protocol.getProjectId()\n : protocol?.environmentId;\n const scoped = scopedEnv !== undefined;\n\n if (scoped && typeof protocol.getMetaItem === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const data = await protocol.getMetaItem({ type: 'object', name, organizationId });\n // Protocol returns `{ type, name, item }` — only\n // treat the lookup as a hit when item is present.\n if (data && (data.item ?? data)) {\n return { handled: true, response: this.success(data) };\n }\n } catch { /* fall through to registry / 404 */ }\n }\n\n const qlService = await this.getObjectQLService();\n if (qlService?.registry) {\n const data = qlService.registry.getObject(name);\n if (data) return { handled: true, response: this.success(data) };\n }\n\n // Last-ditch protocol attempt for unscoped kernels whose\n // registry missed (e.g. object persisted to DB but not\n // yet hydrated). Skip when we already tried above.\n if (!scoped && protocol && typeof protocol.getMetaItem === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const data = await protocol.getMetaItem({ type: 'object', name, organizationId });\n if (data && (data.item ?? data)) {\n return { handled: true, response: this.success(data) };\n }\n } catch { /* fall through to 404 */ }\n }\n return { handled: true, response: this.error('Not found', 404) };\n }\n\n // Normalize plural URL paths to singular registry type names\n const singularType = pluralToSingular(type);\n\n // Try Protocol Service First (Preferred)\n const protocol = await this.resolveService('protocol');\n if (protocol && typeof protocol.getMetaItem === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const data = await protocol.getMetaItem({ type: singularType, name, packageId, organizationId });\n return { handled: true, response: this.success(data) };\n } catch (e: any) {\n // Protocol might throw if not found or not supported\n }\n }\n\n // Try MetadataService for runtime-registered types\n const metaSvc = await this.resolveService('metadata', _context.environmentId);\n if (metaSvc && typeof (metaSvc as any).getItem === 'function') {\n try {\n const data = await (metaSvc as any).getItem(singularType, name);\n if (data) return { handled: true, response: this.success(data) };\n } catch { /* not found */ }\n }\n return { handled: true, response: this.error('Not found', 404) };\n } catch (e: any) {\n // Fallback: treat first part as object name if only 1 part (handled below)\n // But here we are deep in 2 parts. Must be an error.\n return { handled: true, response: this.error(e.message, 404) };\n }\n }\n \n // GET /metadata/:type (List items of type) OR /metadata/:objectName (Legacy)\n if (parts.length === 1) {\n const typeOrName = parts[0];\n // Extract optional package filter from query string\n const packageId = query?.package || undefined;\n\n // Try protocol service first for any type\n const protocol = await this.resolveService('protocol');\n if (protocol && typeof protocol.getMetaItems === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const data = await protocol.getMetaItems({ type: typeOrName, packageId, organizationId });\n // Return any valid response from protocol (including empty items arrays)\n if (data && (data.items !== undefined || Array.isArray(data))) {\n return { handled: true, response: this.success(data) };\n }\n } catch {\n // Protocol doesn't know this type, fall through\n }\n }\n\n // Try MetadataService directly for runtime-registered metadata (agents, tools, etc.)\n const metadataService = await this.getService(CoreServiceName.enum.metadata);\n if (metadataService && typeof (metadataService as any).list === 'function') {\n try {\n let items = await (metadataService as any).list(typeOrName);\n // Respect package filter: MetadataService.list() returns ALL items,\n // so filter by _packageId when a specific package is requested.\n if (packageId && items && items.length > 0) {\n items = items.filter((item: any) => item?._packageId === packageId);\n }\n if (items && items.length > 0) {\n return { handled: true, response: this.success({ type: typeOrName, items }) };\n }\n } catch (e: any) {\n // MetadataService doesn't know this type or failed, continue to other fallbacks\n // Sanitize typeOrName to prevent log injection (CodeQL warning)\n const sanitizedType = String(typeOrName).replace(/[\\r\\n\\t]/g, '');\n console.debug(`[HttpDispatcher] MetadataService.list() failed for type:`, sanitizedType, 'error:', e.message);\n }\n }\n\n // Try ObjectQL registry directly for object/type lookups\n const qlService = await this.getObjectQLService();\n if (qlService?.registry) {\n if (typeOrName === 'objects') {\n const objs = qlService.registry.getAllObjects(packageId);\n return { handled: true, response: this.success({ type: 'object', items: objs }) };\n }\n // Try listing items of the given type\n const items = qlService.registry.listItems?.(typeOrName, packageId);\n if (items && items.length > 0) {\n return { handled: true, response: this.success({ type: typeOrName, items }) };\n }\n // Legacy: treat as object name\n const obj = qlService.registry.getObject(typeOrName);\n if (obj) return { handled: true, response: this.success(obj) };\n }\n return { handled: true, response: this.error('Not found', 404) };\n }\n\n // GET /metadata — return available metadata types\n if (parts.length === 0) {\n // Prefer protocol service for the rich `entries` array (with\n // JSON Schemas etc); fall back to MetadataService types-only.\n const protocol = await this.resolveService('protocol');\n if (protocol && typeof protocol.getMetaTypes === 'function') {\n try {\n const result = await protocol.getMetaTypes({});\n return { handled: true, response: this.success(result) };\n } catch { /* fall through */ }\n }\n const metadataService = await this.resolveService('metadata', _context.environmentId);\n if (metadataService && typeof (metadataService as any).getRegisteredTypes === 'function') {\n try {\n const types = await (metadataService as any).getRegisteredTypes();\n return { handled: true, response: this.success({ types }) };\n } catch { /* fall through */ }\n }\n return { handled: true, response: this.success({ types: ['object', 'app', 'plugin'] }) };\n }\n \n return { handled: false };\n }\n\n /**\n * Handles Data requests\n * path: sub-path after /data/ (e.g. \"contacts\", \"contacts/123\", \"contacts/query\")\n */\n async handleData(path: string, method: string, body: any, query: any, _context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n const parts = path.replace(/^\\/+/, '').split('/');\n const objectName = parts[0];\n\n if (!objectName) {\n return { handled: true, response: this.error('Object name required', 400) };\n }\n\n // Check if environment is resolved for data-plane requests\n if (!_context.dataDriver && this.envRegistry) {\n return {\n handled: true,\n response: this.error('Project not resolved. Please specify X-Environment-Id header or ensure hostname maps to a project.', 428)\n };\n }\n\n const m = method.toUpperCase();\n\n // 1. Custom Actions (query, batch)\n if (parts.length > 1) {\n const action = parts[1];\n\n // POST /data/:object/query\n if (action === 'query' && m === 'POST') {\n // Spec: returns FindDataResponse = { object, records, total?, hasMore? }\n const result = await this.callData('query', { object: objectName, ...body }, _context.dataDriver, _context.environmentId, _context.executionContext);\n return { handled: true, response: this.success(result) };\n }\n\n // GET /data/:object/:id\n if (parts.length === 2 && m === 'GET') {\n const id = parts[1];\n // Spec: Only select/expand are allowlisted query params for GET by ID.\n // All other query parameters are discarded to prevent parameter pollution.\n const { select, expand } = query || {};\n const allowedParams: Record<string, unknown> = {};\n if (select != null) allowedParams.select = select;\n if (expand != null) allowedParams.expand = expand;\n // Spec: returns GetDataResponse = { object, id, record }\n const result = await this.callData('get', { object: objectName, id, ...allowedParams }, _context.dataDriver, _context.environmentId, _context.executionContext);\n return { handled: true, response: this.success(result) };\n }\n\n // PATCH /data/:object/:id\n if (parts.length === 2 && m === 'PATCH') {\n const id = parts[1];\n // Spec: returns UpdateDataResponse = { object, id, record }\n const result = await this.callData('update', { object: objectName, id, data: body }, _context.dataDriver, _context.environmentId, _context.executionContext);\n return { handled: true, response: this.success(result) };\n }\n\n // DELETE /data/:object/:id\n if (parts.length === 2 && m === 'DELETE') {\n const id = parts[1];\n // Spec: returns DeleteDataResponse = { object, id, deleted }\n const result = await this.callData('delete', { object: objectName, id }, _context.dataDriver, _context.environmentId, _context.executionContext);\n return { handled: true, response: this.success(result) };\n }\n } else {\n // GET /data/:object (List)\n if (m === 'GET') {\n // ── Normalize HTTP transport params → Spec canonical (QueryAST) ──\n // HTTP GET query params use transport-level names (filter, sort, top,\n // skip, select, expand) which are normalized here to canonical\n // QueryAST field names (where, orderBy, limit, offset, fields,\n // expand) before forwarding to the data service layer.\n // The protocol.ts findData() method performs a deeper normalization\n // pass, but pre-normalizing here ensures the data service always receives\n // Spec-canonical keys.\n const normalized: Record<string, unknown> = { ...query };\n\n // filter/filters → where\n // Note: `filter` is the canonical HTTP *transport* parameter name\n // (see HttpFindQueryParamsSchema). It is normalized here to the\n // canonical *QueryAST* field name `where` before data dispatch.\n // `filters` (plural) is a deprecated alias for `filter`.\n if (normalized.filter != null || normalized.filters != null) {\n normalized.where = normalized.where ?? normalized.filter ?? normalized.filters;\n delete normalized.filter;\n delete normalized.filters;\n }\n // select → fields\n if (normalized.select != null && normalized.fields == null) {\n normalized.fields = normalized.select;\n delete normalized.select;\n }\n // sort → orderBy\n if (normalized.sort != null && normalized.orderBy == null) {\n normalized.orderBy = normalized.sort;\n delete normalized.sort;\n }\n // top → limit\n if (normalized.top != null && normalized.limit == null) {\n normalized.limit = normalized.top;\n delete normalized.top;\n }\n // skip → offset\n if (normalized.skip != null && normalized.offset == null) {\n normalized.offset = normalized.skip;\n delete normalized.skip;\n }\n\n // Spec: returns FindDataResponse = { object, records, total?, hasMore? }\n const result = await this.callData('query', { object: objectName, query: normalized }, _context.dataDriver, _context.environmentId, _context.executionContext);\n return { handled: true, response: this.success(result) };\n }\n\n // POST /data/:object (Create)\n if (m === 'POST') {\n // Spec: returns CreateDataResponse = { object, id, record }\n const result = await this.callData('create', { object: objectName, data: body }, _context.dataDriver, _context.environmentId, _context.executionContext);\n const res = this.success(result);\n res.status = 201;\n return { handled: true, response: res };\n }\n }\n\n return { handled: false };\n }\n\n /**\n * Handles Analytics requests\n * path: sub-path after /analytics/\n */\n async handleAnalytics(path: string, method: string, body: any, _context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n const analyticsService = await this.getService(CoreServiceName.enum.analytics);\n if (!analyticsService) return { handled: false }; // 404 handled by caller if unhandled\n\n const m = method.toUpperCase();\n const subPath = path.replace(/^\\/+/, '');\n\n // POST /analytics/query\n if (subPath === 'query' && m === 'POST') {\n const result = await analyticsService.query(body);\n return { handled: true, response: this.success(result) };\n }\n\n // GET /analytics/meta\n if (subPath === 'meta' && m === 'GET') {\n const result = await analyticsService.getMeta();\n return { handled: true, response: this.success(result) };\n }\n\n // POST /analytics/sql (Dry-run or debug)\n if (subPath === 'sql' && m === 'POST') {\n // Assuming service has generateSql method\n const result = await analyticsService.generateSql(body);\n return { handled: true, response: this.success(result) };\n }\n\n return { handled: false };\n }\n\n /**\n * Handles in-app notification requests (ADR-0030) — the\n * `/api/v1/notifications` surface backed by the messaging service's inbox\n * read API. Reads the L5 `sys_inbox_message` + `sys_notification_receipt`\n * join; mark-read upserts the receipt keyed `(notification_id, user_id,\n * channel:'inbox')`. The routes are `auth: true`, so an authenticated user\n * is required.\n *\n * Routes (path is the sub-path after `/notifications`):\n * GET '' → listInbox (query: read, type, limit)\n * POST /read → markRead (body: { ids: string[] })\n * POST /read/all → markAllRead\n */\n async handleNotification(path: string, method: string, body: any, query: any, context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n const service = await this.resolveService(CoreServiceName.enum.notification, context.environmentId) as any;\n if (!service || typeof service.listInbox !== 'function') return { handled: false };\n\n const userId: string | undefined = context.executionContext?.userId;\n if (!userId) {\n return { handled: true, response: this.error('Authentication required', 401) };\n }\n\n const m = method.toUpperCase();\n const subPath = path.replace(/^\\/+/, '').replace(/\\/+$/, '');\n\n // GET /notifications — list the user's inbox joined with read-state.\n if (subPath === '' && m === 'GET') {\n const read = query?.read === undefined ? undefined : String(query.read) === 'true';\n const limit = query?.limit ? Number(query.limit) : undefined;\n const type = query?.type ? String(query.type) : undefined;\n const result = await service.listInbox(userId, { read, type, limit });\n return { handled: true, response: this.success(result) };\n }\n\n // POST /notifications/read — mark specific notifications read.\n if (subPath === 'read' && m === 'POST') {\n const ids: string[] = Array.isArray(body?.ids) ? body.ids.map((x: unknown) => String(x)) : [];\n const result = await service.markRead(userId, ids);\n return { handled: true, response: this.success(result) };\n }\n\n // POST /notifications/read/all — mark all of the user's inbox read.\n if (subPath === 'read/all' && m === 'POST') {\n const result = await service.markAllRead(userId);\n return { handled: true, response: this.success(result) };\n }\n\n return { handled: false };\n }\n\n /**\n * Handles i18n requests\n * path: sub-path after /i18n/\n *\n * Routes:\n * GET /locales → getLocales\n * GET /translations/:locale → getTranslations (locale from path)\n * GET /translations?locale=xx → getTranslations (locale from query)\n * GET /labels/:object/:locale → getFieldLabels (both from path)\n * GET /labels/:object?locale=xx → getFieldLabels (locale from query)\n */\n async handleI18n(path: string, method: string, query: any, _context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n const i18nService = await this.getService(CoreServiceName.enum.i18n);\n if (!i18nService) return { handled: true, response: this.error('i18n service not available', 501) };\n\n const m = method.toUpperCase();\n const parts = path.replace(/^\\/+/, '').split('/').filter(Boolean);\n\n if (m !== 'GET') return { handled: false };\n\n // GET /i18n/locales\n if (parts[0] === 'locales' && parts.length === 1) {\n const locales = i18nService.getLocales();\n return { handled: true, response: this.success({ locales }) };\n }\n\n // GET /i18n/translations/:locale OR /i18n/translations?locale=xx\n if (parts[0] === 'translations') {\n const locale = parts[1] ? decodeURIComponent(parts[1]) : query?.locale;\n if (!locale) return { handled: true, response: this.error('Missing locale parameter', 400) };\n\n let translations = i18nService.getTranslations(locale);\n\n // Locale fallback: try resolving to an available locale when\n // the exact code yields empty translations (e.g. zh → zh-CN).\n if (Object.keys(translations).length === 0) {\n const availableLocales = typeof i18nService.getLocales === 'function'\n ? i18nService.getLocales() : [];\n const resolved = resolveLocale(locale, availableLocales);\n if (resolved && resolved !== locale) {\n translations = i18nService.getTranslations(resolved);\n return { handled: true, response: this.success({ locale: resolved, requestedLocale: locale, translations }) };\n }\n }\n\n return { handled: true, response: this.success({ locale, translations }) };\n }\n\n // GET /i18n/labels/:object/:locale OR /i18n/labels/:object?locale=xx\n if (parts[0] === 'labels' && parts.length >= 2) {\n const objectName = decodeURIComponent(parts[1]);\n let locale = parts[2] ? decodeURIComponent(parts[2]) : query?.locale;\n if (!locale) return { handled: true, response: this.error('Missing locale parameter', 400) };\n\n // Locale fallback for labels endpoint\n const availableLocales = typeof i18nService.getLocales === 'function'\n ? i18nService.getLocales() : [];\n const resolved = resolveLocale(locale, availableLocales);\n if (resolved) locale = resolved;\n\n if (typeof i18nService.getFieldLabels === 'function') {\n const labels = i18nService.getFieldLabels(objectName, locale);\n return { handled: true, response: this.success({ object: objectName, locale, labels }) };\n }\n // Fallback: derive field labels from full translation bundle\n const translations = i18nService.getTranslations(locale);\n const prefix = `o.${objectName}.fields.`;\n const labels: Record<string, string> = {};\n for (const [key, value] of Object.entries(translations)) {\n if (key.startsWith(prefix)) {\n labels[key.substring(prefix.length)] = value as string;\n }\n }\n return { handled: true, response: this.success({ object: objectName, locale, labels }) };\n }\n\n return { handled: false };\n }\n\n /**\n * Handles Package Management requests\n * \n * REST Endpoints:\n * - GET /packages → list all installed packages\n * - GET /packages/:id → get a specific package\n * - POST /packages → install a new package\n * - DELETE /packages/:id → uninstall a package\n * - PATCH /packages/:id/enable → enable a package\n * - PATCH /packages/:id/disable → disable a package\n * - POST /packages/:id/publish → publish a package (metadata snapshot)\n * - POST /packages/:id/revert → revert a package to last published state\n * \n * Uses ObjectQL SchemaRegistry directly (via the 'objectql' service).\n */\n async handlePackages(path: string, method: string, body: any, query: any, _context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n const m = method.toUpperCase();\n const parts = path.replace(/^\\/+/, '').split('/').filter(Boolean);\n\n // Try to get SchemaRegistry from the ObjectQL service\n const qlService = await this.getObjectQLService();\n const registry = qlService?.registry;\n\n // If no registry available, return 503\n if (!registry) {\n return { handled: true, response: this.error('Package service not available', 503) };\n }\n\n try {\n // GET /packages → list packages\n if (parts.length === 0 && m === 'GET') {\n let packages = registry.getAllPackages();\n // Apply optional filters\n if (query?.status) {\n packages = packages.filter((p: any) => p.status === query.status);\n }\n if (query?.type) {\n packages = packages.filter((p: any) => p.manifest?.type === query.type);\n }\n return { handled: true, response: this.success({ packages, total: packages.length }) };\n }\n\n // POST /packages → install package\n if (parts.length === 0 && m === 'POST') {\n const pkg = registry.installPackage(body.manifest || body, body.settings);\n const res = this.success(pkg);\n res.status = 201;\n return { handled: true, response: res };\n }\n\n // PATCH /packages/:id/enable\n if (parts.length === 2 && parts[1] === 'enable' && m === 'PATCH') {\n const id = decodeURIComponent(parts[0]);\n const pkg = registry.enablePackage(id);\n if (!pkg) return { handled: true, response: this.error(`Package '${id}' not found`, 404) };\n try {\n setPackageDisabled(_context?.environmentId, id, false);\n } catch (err) {\n console.warn('[handlePackages] failed to persist enable state', { id, error: (err as Error)?.message });\n }\n return { handled: true, response: this.success(pkg) };\n }\n\n // PATCH /packages/:id/disable\n if (parts.length === 2 && parts[1] === 'disable' && m === 'PATCH') {\n const id = decodeURIComponent(parts[0]);\n const pkg = registry.disablePackage(id);\n if (!pkg) return { handled: true, response: this.error(`Package '${id}' not found`, 404) };\n try {\n setPackageDisabled(_context?.environmentId, id, true);\n } catch (err) {\n console.warn('[handlePackages] failed to persist disable state', { id, error: (err as Error)?.message });\n }\n return { handled: true, response: this.success(pkg) };\n }\n\n // POST /packages/:id/publish → publish package metadata\n if (parts.length === 2 && parts[1] === 'publish' && m === 'POST') {\n const id = decodeURIComponent(parts[0]);\n const metadataService = await this.getService(CoreServiceName.enum.metadata);\n if (metadataService && typeof (metadataService as any).publishPackage === 'function') {\n const result = await (metadataService as any).publishPackage(id, body || {});\n return { handled: true, response: this.success(result) };\n }\n return { handled: true, response: this.error('Metadata service not available', 503) };\n }\n\n // POST /packages/:id/revert → revert package to last published state\n if (parts.length === 2 && parts[1] === 'revert' && m === 'POST') {\n const id = decodeURIComponent(parts[0]);\n const metadataService = await this.getService(CoreServiceName.enum.metadata);\n if (metadataService && typeof (metadataService as any).revertPackage === 'function') {\n await (metadataService as any).revertPackage(id);\n return { handled: true, response: this.success({ success: true }) };\n }\n return { handled: true, response: this.error('Metadata service not available', 503) };\n }\n\n // GET /packages/:id/export → assemble a portable manifest from\n // sys_metadata overlay rows bound to this package (offline export).\n if (parts.length === 2 && parts[1] === 'export' && m === 'GET') {\n const id = decodeURIComponent(parts[0]);\n const manifest = await this.assemblePackageManifest(id, registry, _context);\n if (!manifest) {\n return { handled: true, response: this.error(`Package '${id}' not found`, 404) };\n }\n return { handled: true, response: this.success(manifest) };\n }\n\n // GET /packages/:id → get package\n if (parts.length === 1 && m === 'GET') {\n const id = decodeURIComponent(parts[0]);\n const pkg = registry.getPackage(id);\n if (!pkg) return { handled: true, response: this.error(`Package '${id}' not found`, 404) };\n return { handled: true, response: this.success(pkg) };\n }\n\n // DELETE /packages/:id → uninstall package\n if (parts.length === 1 && m === 'DELETE') {\n const id = decodeURIComponent(parts[0]);\n const success = registry.uninstallPackage(id);\n if (!success) return { handled: true, response: this.error(`Package '${id}' not found`, 404) };\n return { handled: true, response: this.success({ success: true }) };\n }\n } catch (e: any) {\n return { handled: true, response: this.error(e.message, e.statusCode || 500) };\n }\n\n return { handled: false };\n }\n\n /**\n * Assemble a portable, offline-installable package manifest from the\n * `sys_metadata` overlay rows bound to `packageId`.\n *\n * The resulting shape mirrors what `marketplace-install-local` →\n * `manifestService.register()` → `engine.registerApp()` consumes:\n * `{ id, name, version, objects:[…], views:[…], flows:[…], … }`\n * where each category key is the PLURAL manifest name and its value is\n * an array of clean metadata bodies (provenance decorations stripped).\n *\n * Only the metadata categories that `registerApp` can actually consume\n * are exported. `datasources` and `emailTemplates` are intentionally\n * excluded (not registered by the import path). `tools` / `skills` ARE\n * round-tripped: they are registered by `registerApp` on import and\n * surfaced by `getMetaItems('tool' | 'skill')` on export.\n *\n * @returns the manifest object, or `null` if the package id is unknown\n * AND has no overlay-authored metadata.\n */\n private async assemblePackageManifest(\n packageId: string,\n registry: any,\n context: HttpProtocolContext,\n ): Promise<Record<string, any> | null> {\n const protocol = await this.resolveService('protocol');\n if (!protocol || typeof protocol.getMetaItems !== 'function') return null;\n\n const organizationId = await this.resolveActiveOrganizationId(context);\n\n // Provenance / overlay-bookkeeping keys that must never leak into a\n // portable manifest. Stripped at top level only — nested field bodies\n // are left untouched.\n const PROVENANCE_KEYS = new Set([\n '_packageId', '_packageVersionId', '_provenance', '_state',\n '_version', '_organizationId', '_source', '_id', '_rowId',\n ]);\n const clean = (item: any) => {\n if (!item || typeof item !== 'object') return item;\n const out: Record<string, any> = {};\n for (const [k, v] of Object.entries(item)) {\n if (k.startsWith('_') || PROVENANCE_KEYS.has(k)) continue;\n out[k] = v;\n }\n return out;\n };\n\n // Categories the local-install register path understands. Excludes\n // datasources / emailTemplates (not consumed by registerApp).\n const exportPluralKeys = Object.keys(PLURAL_TO_SINGULAR).filter(\n (k) => k !== 'datasources' && k !== 'emailTemplates',\n );\n\n const manifest: Record<string, any> = {};\n let total = 0;\n for (const plural of exportPluralKeys) {\n const singular = PLURAL_TO_SINGULAR[plural];\n let items: any[] = [];\n try {\n // getMetaItems applies the packageId filter at the\n // registry/overlay query level, so the returned items are\n // already scoped to this package — no client-side re-filter.\n const res = await protocol.getMetaItems({ type: singular, packageId, organizationId });\n items = Array.isArray(res?.items) ? res.items : [];\n } catch {\n // Unknown/unsupported type for this runtime — skip.\n continue;\n }\n if (items.length === 0) continue;\n manifest[plural] = items.map(clean);\n total += items.length;\n }\n\n const pkg = (() => {\n try { return registry?.getPackage?.(packageId); } catch { return undefined; }\n })();\n\n if (total === 0 && !pkg) return null;\n\n manifest.id = packageId;\n manifest.name = pkg?.manifest?.name ?? pkg?.name ?? packageId;\n manifest.version = pkg?.manifest?.version ?? pkg?.version ?? '1.0.0';\n if (pkg?.manifest?.label ?? pkg?.label) {\n manifest.label = pkg?.manifest?.label ?? pkg?.label;\n }\n return manifest;\n }\n\n /**\n * Cloud / Environment Control-Plane routes.\n *\n * - GET /cloud/drivers → list registered ObjectQL drivers (for env provisioning)\n * - GET /cloud/environments → list\n * - POST /cloud/environments → provision (driver: memory | turso | <any registered driver>)\n * - GET /cloud/environments/:id → detail (+ db, credential, membership)\n * - PATCH /cloud/environments/:id → update displayName / plan / status / isDefault / metadata\n * - DELETE /cloud/environments/:id[?force=1] → cascade-delete the project (cred/member/package install rows + physical DB)\n * - DELETE /cloud/organizations/:id → cascade-delete every project (and its DB) for the org, then drop the org\n * - POST /cloud/environments/:id/retry → re-run provisioning for a failed environment\n * - POST /cloud/environments/:id/activate → mark as active for session (stub)\n * - POST /cloud/environments/:id/credentials/rotate → rotate credential\n * - GET /cloud/environments/:id/members → list members\n * - GET /cloud/environments/:id/packages → list installed packages\n * - POST /cloud/environments/:id/packages → install package into env\n * - GET /cloud/environments/:id/packages/:pkgId → get installation detail\n * - PATCH /cloud/environments/:id/packages/:pkgId/enable → enable package\n * - PATCH /cloud/environments/:id/packages/:pkgId/disable → disable package\n * - DELETE /cloud/environments/:id/packages/:pkgId → uninstall (scope=platform forbidden)\n * - POST /cloud/environments/:id/packages/:pkgId/upgrade → upgrade to newer version\n *\n * Driver binding\n * --------------\n * Environments are not tied to any specific driver. At provisioning time the\n * caller passes `driver` (a short name such as `memory`, `turso`, or any\n * future `sql` / `postgres` driver). The dispatcher validates the name\n * against the kernel's registered driver services (`driver.<name>`) and\n * derives an appropriate placeholder `database_url` for the chosen driver.\n * If `driver` is omitted, the dispatcher auto-selects the first available\n * in preference order: turso → memory → any other registered driver.\n *\n * Backed by ObjectQL sys_environment / sys_environment_credential /\n * sys_environment_member tables (registered by\n * `@objectstack/service-tenant`'s `createTenantPlugin`).\n * Physical database addressing (database_url, database_driver, etc.)\n * is stored directly on the sys_environment row.\n */\n /**\n * Resolve the calling user id from the request session, if any.\n * Returns `undefined` for anonymous calls or when auth is not wired up.\n */\n private async resolveActiveOrganizationId(context: HttpProtocolContext): Promise<string | undefined> {\n try {\n const authService: any = await this.resolveService(CoreServiceName.enum.auth);\n const rawHeaders = context.request?.headers;\n let headers: any = rawHeaders;\n if (rawHeaders && typeof rawHeaders === 'object' && typeof (rawHeaders as any).get !== 'function') {\n try {\n const h = new Headers();\n for (const [k, v] of Object.entries(rawHeaders as Record<string, any>)) {\n if (v == null) continue;\n h.set(k, Array.isArray(v) ? v.join(', ') : String(v));\n }\n headers = h;\n } catch {\n headers = rawHeaders;\n }\n }\n const apiObj = authService?.auth?.api ?? authService?.api;\n const sessionData = await apiObj?.getSession?.call(apiObj, { headers });\n const oid = sessionData?.session?.activeOrganizationId;\n return typeof oid === 'string' && oid.length > 0 ? oid : undefined;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Handles Storage requests\n * path: sub-path after /storage/\n */\n async handleStorage(path: string, method: string, file: any, context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n const storageService = await this.getService(CoreServiceName.enum['file-storage']) || this.kernel.services?.['file-storage'];\n if (!storageService) {\n return { handled: true, response: this.error('File storage not configured', 501) };\n }\n \n const m = method.toUpperCase();\n const parts = path.replace(/^\\/+/, '').split('/');\n \n // POST /storage/upload\n if (parts[0] === 'upload' && m === 'POST') {\n if (!file) {\n return { handled: true, response: this.error('No file provided', 400) };\n }\n const result = await storageService.upload(file, { request: context.request });\n return { handled: true, response: this.success(result) };\n }\n \n // GET /storage/file/:id\n if (parts[0] === 'file' && parts[1] && m === 'GET') {\n const id = parts[1];\n const result = await storageService.download(id, { request: context.request });\n \n // Result can be URL (redirect), Stream/Blob, or metadata\n if (result.url && result.redirect) {\n // Must be handled by adapter to do actual redirect\n return { handled: true, result: { type: 'redirect', url: result.url } };\n }\n \n if (result.stream) {\n // Must be handled by adapter to pipe stream\n return { \n handled: true, \n result: { \n type: 'stream', \n stream: result.stream, \n headers: {\n 'Content-Type': result.mimeType || 'application/octet-stream',\n 'Content-Length': result.size\n }\n } \n };\n }\n \n return { handled: true, response: this.success(result) };\n }\n \n return { handled: false };\n }\n\n /**\n * Handles UI requests\n * path: sub-path after /ui/\n */\n async handleUi(path: string, query: any, _context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n const parts = path.replace(/^\\/+/, '').split('/').filter(Boolean);\n \n // GET /ui/view/:object (with optional type param)\n if (parts[0] === 'view' && parts[1]) {\n const objectName = parts[1];\n // Support both path param /view/obj/list AND query param /view/obj?type=list\n const type = parts[2] || query?.type || 'list';\n\n const protocol = await this.resolveService('protocol');\n \n if (protocol && typeof protocol.getUiView === 'function') {\n try {\n const result = await protocol.getUiView({ object: objectName, type });\n return { handled: true, response: this.success(result) };\n } catch (e: any) {\n return { handled: true, response: this.error(e.message, 500) };\n }\n } else {\n return { handled: true, response: this.error('Protocol service not available', 503) };\n }\n }\n\n return { handled: false };\n }\n\n /**\n * Handles Automation requests\n * path: sub-path after /automation/\n *\n * Routes:\n * GET / → listFlows\n * GET /actions → getActionDescriptors (ADR-0018; ?paradigm/?source/?category filters)\n * GET /connectors → getConnectorDescriptors (ADR-0022; ?type filter)\n * GET /:name → getFlow\n * POST / → createFlow (registerFlow)\n * PUT /:name → updateFlow\n * DELETE /:name → deleteFlow (unregisterFlow)\n * POST /:name/trigger → execute (legacy: trigger/:name also supported)\n * POST /:name/toggle → toggleFlow\n * GET /:name/runs → listRuns\n * GET /:name/runs/:runId → getRun\n * POST /:name/runs/:runId/resume → resume a paused run (screen input / ADR-0019)\n * GET /:name/runs/:runId/screen → the screen a paused run awaits\n */\n async handleAutomation(path: string, method: string, body: any, context: HttpProtocolContext, query?: any): Promise<HttpDispatcherResult> {\n const automationService = await this.getService(CoreServiceName.enum.automation);\n if (!automationService) return { handled: false };\n\n const m = method.toUpperCase();\n const parts = path.replace(/^\\/+/, '').split('/').filter(Boolean);\n\n // Legacy: POST /automation/trigger/:name\n if (parts[0] === 'trigger' && parts[1] && m === 'POST') {\n const triggerName = parts[1];\n if (typeof automationService.trigger === 'function') {\n const result = await automationService.trigger(triggerName, body, { request: context.request });\n return { handled: true, response: this.success(result) };\n }\n // Fallback to execute\n if (typeof automationService.execute === 'function') {\n const result = await automationService.execute(triggerName, body);\n return { handled: true, response: this.success(result) };\n }\n }\n\n // GET / → listFlows\n if (parts.length === 0 && m === 'GET') {\n if (typeof automationService.listFlows === 'function') {\n const names = await automationService.listFlows();\n return { handled: true, response: this.success({ flows: names, total: names.length, hasMore: false }) };\n }\n }\n\n // POST / → createFlow\n if (parts.length === 0 && m === 'POST') {\n if (typeof automationService.registerFlow === 'function') {\n automationService.registerFlow(body?.name, body);\n return { handled: true, response: this.success(body) };\n }\n }\n\n // GET /actions → list registered action descriptors (ADR-0018).\n // MUST precede the `/:name → getFlow` catch-all below, otherwise a\n // flow lookup for a flow literally named \"actions\" would shadow it.\n // Backs the designer palette + flow validation; the registry is open\n // and marketplace-extensible (built-in + plugin-contributed actions).\n if (parts[0] === 'actions' && parts.length === 1 && m === 'GET') {\n if (typeof automationService.getActionDescriptors === 'function') {\n let actions = automationService.getActionDescriptors() ?? [];\n // Optional filters mirror descriptor fields.\n if (query?.paradigm) {\n actions = actions.filter((a: any) => Array.isArray(a?.paradigms) && a.paradigms.includes(query.paradigm));\n }\n if (query?.source) {\n actions = actions.filter((a: any) => a?.source === query.source);\n }\n if (query?.category) {\n actions = actions.filter((a: any) => a?.category === query.category);\n }\n return { handled: true, response: this.success({ actions, total: actions.length }) };\n }\n // Service present but does not implement the optional method:\n // report an empty (but valid) registry rather than a 404.\n return { handled: true, response: this.success({ actions: [], total: 0 }) };\n }\n\n // GET /connectors → list registered connector descriptors (ADR-0022).\n // Like /actions, MUST precede the `/:name → getFlow` catch-all so a flow\n // named \"connectors\" cannot shadow it. Backs the designer's\n // `connector_action` connector/action/input pickers; the registry is\n // empty in baseline and populated by connector plugins (e.g.\n // @objectstack/connector-rest, @objectstack/connector-slack).\n if (parts[0] === 'connectors' && parts.length === 1 && m === 'GET') {\n if (typeof automationService.getConnectorDescriptors === 'function') {\n let connectors = automationService.getConnectorDescriptors() ?? [];\n // Optional filter mirrors the descriptor's connector type.\n if (query?.type) {\n connectors = connectors.filter((c: any) => c?.type === query.type);\n }\n return { handled: true, response: this.success({ connectors, total: connectors.length }) };\n }\n // Service present but does not implement the optional method:\n // report an empty (but valid) registry rather than a 404.\n return { handled: true, response: this.success({ connectors: [], total: 0 }) };\n }\n\n // Routes with :name\n if (parts.length >= 1) {\n const name = parts[0];\n\n // POST /:name/trigger → execute\n if (parts[1] === 'trigger' && m === 'POST') {\n if (typeof automationService.execute === 'function') {\n const ctxBody = body && typeof body === 'object' ? body : {};\n // Translate UI/SDK request shape `{recordId, objectName, params}`\n // into the canonical AutomationContext shape expected by the engine.\n // Key transformations:\n // - `recordId` is exposed in `params.recordId` AND aliased to\n // `<objectName>Id` (camelCase) so flow variables like `leadId`,\n // `caseId`, `opportunityId` resolve from a single REST contract.\n // - `objectName` is mapped to the canonical `object` field.\n // - The user identity from the auth context (if any) is forwarded\n // as `userId` so node executors / template interpolation can\n // expand `{$User.Id}`.\n const recordId = ctxBody.recordId;\n const objectName = ctxBody.objectName ?? ctxBody.object;\n const baseParams = (ctxBody.params && typeof ctxBody.params === 'object') ? { ...ctxBody.params } : {};\n // Back-compat: when callers POST a flat body (no `params` wrapper),\n // forward unknown top-level keys as flow params so the original\n // `{ foo: 'bar' }` payload is not silently dropped.\n if (!ctxBody.params) {\n const reserved = new Set(['recordId', 'objectName', 'object', 'event', 'params']);\n for (const [k, v] of Object.entries(ctxBody)) {\n if (reserved.has(k)) continue;\n if (baseParams[k] === undefined) baseParams[k] = v;\n }\n }\n if (recordId !== undefined && baseParams.recordId === undefined) {\n baseParams.recordId = recordId;\n }\n if (recordId !== undefined && objectName) {\n const alias = `${String(objectName).replace(/_([a-z])/g, (_: string, c: string) => c.toUpperCase())}Id`;\n if (baseParams[alias] === undefined) baseParams[alias] = recordId;\n }\n const automationContext: any = {\n params: baseParams,\n object: objectName,\n event: ctxBody.event ?? 'manual',\n };\n const userIdFromAuth = (context as any)?.user?.id ?? (context as any)?.userId;\n if (userIdFromAuth) automationContext.userId = userIdFromAuth;\n const result = await automationService.execute(name, automationContext);\n return { handled: true, response: this.success(result) };\n }\n }\n\n // POST /:name/toggle → toggleFlow\n if (parts[1] === 'toggle' && m === 'POST') {\n if (typeof automationService.toggleFlow === 'function') {\n await automationService.toggleFlow(name, body?.enabled ?? true);\n return { handled: true, response: this.success({ name, enabled: body?.enabled ?? true }) };\n }\n }\n\n // POST /:name/runs/:runId/resume → resume a paused run (screen-flow\n // runtime / ADR-0019). Body `{ inputs }` = a screen node's collected\n // values, applied as bare flow variables; `output`/`branchLabel` also\n // forwarded for approval-style resumes. Returns the next paused\n // `{ screen }` (multi-screen) or the completed result.\n if (parts[1] === 'runs' && parts[2] && parts[3] === 'resume' && m === 'POST') {\n if (typeof automationService.resume === 'function') {\n const b = (body && typeof body === 'object') ? body : {};\n const inputs = (b.inputs ?? b.variables);\n const signal: any = {};\n if (inputs && typeof inputs === 'object') signal.variables = inputs;\n if (b.output && typeof b.output === 'object') signal.output = b.output;\n if (typeof b.branchLabel === 'string') signal.branchLabel = b.branchLabel;\n const result = await automationService.resume(parts[2], signal);\n return { handled: true, response: this.success(result) };\n }\n return { handled: true, response: this.error('Resume not supported', 501) };\n }\n\n // GET /:name/runs/:runId/screen → the screen a paused run awaits\n // (refresh-safe re-fetch for the UI flow-runner).\n if (parts[1] === 'runs' && parts[2] && parts[3] === 'screen' && m === 'GET') {\n if (typeof automationService.getSuspendedScreen === 'function') {\n const screen = automationService.getSuspendedScreen(parts[2]);\n if (!screen) return { handled: true, response: this.error('No pending screen for run', 404) };\n return { handled: true, response: this.success({ runId: parts[2], screen }) };\n }\n return { handled: true, response: this.error('Screen lookup not supported', 501) };\n }\n\n // GET /:name/runs/:runId → getRun\n if (parts[1] === 'runs' && parts[2] && !parts[3] && m === 'GET') {\n if (typeof automationService.getRun === 'function') {\n const run = await automationService.getRun(parts[2]);\n if (!run) return { handled: true, response: this.error('Execution not found', 404) };\n return { handled: true, response: this.success(run) };\n }\n }\n\n // GET /:name/runs → listRuns\n if (parts[1] === 'runs' && !parts[2] && m === 'GET') {\n if (typeof automationService.listRuns === 'function') {\n const options = query ? { limit: query.limit ? Number(query.limit) : undefined, cursor: query.cursor } : undefined;\n const runs = await automationService.listRuns(name, options);\n return { handled: true, response: this.success({ runs, hasMore: false }) };\n }\n }\n\n // GET /:name → getFlow (no sub-path)\n if (parts.length === 1 && m === 'GET') {\n if (typeof automationService.getFlow === 'function') {\n const flow = await automationService.getFlow(name);\n if (!flow) return { handled: true, response: this.error('Flow not found', 404) };\n return { handled: true, response: this.success(flow) };\n }\n }\n\n // PUT /:name → updateFlow\n if (parts.length === 1 && m === 'PUT') {\n if (typeof automationService.registerFlow === 'function') {\n automationService.registerFlow(name, body?.definition ?? body);\n return { handled: true, response: this.success(body?.definition ?? body) };\n }\n }\n\n // DELETE /:name → deleteFlow\n if (parts.length === 1 && m === 'DELETE') {\n if (typeof automationService.unregisterFlow === 'function') {\n automationService.unregisterFlow(name);\n return { handled: true, response: this.success({ name, deleted: true }) };\n }\n }\n }\n \n return { handled: false };\n }\n\n private getServicesMap(): Record<string, any> {\n if (this.kernel.services instanceof Map) {\n return Object.fromEntries(this.kernel.services);\n }\n return this.kernel.services || {};\n }\n\n private async getService(name: CoreServiceName) {\n return this.resolveService(name);\n }\n\n /**\n * Resolve any service by name, supporting async factories.\n * Fallback chain: getServiceAsync(scopeId) → getServiceAsync → getService (sync) → context.getService → services map.\n * Only returns when a non-null service is found; otherwise falls through to the next step.\n *\n * When `scopeId` is provided, tries the SCOPED factory on `defaultKernel` first (SharedProjectPlugin\n * mode). Falls back to the current `kernel` for singleton / legacy services.\n */\n private async resolveService(name: string, scopeId?: string) {\n // Prefer scoped lookup on defaultKernel when scopeId is given (shared-kernel / multi-environment mode)\n if (scopeId && typeof this.defaultKernel.getServiceAsync === 'function') {\n try {\n const svc = await this.defaultKernel.getServiceAsync(name, scopeId);\n if (svc != null) return svc;\n } catch {\n // Not a scoped service — fall through to singleton resolution\n }\n }\n // Prefer async resolution to support factory-based services (e.g. auth, analytics, protocol)\n if (typeof this.kernel.getServiceAsync === 'function') {\n try {\n const svc = await this.kernel.getServiceAsync(name);\n if (svc != null) return svc;\n } catch {\n // Service not registered or async resolution failed — fall through\n }\n }\n if (typeof this.kernel.getService === 'function') {\n try {\n const svc = await this.kernel.getService(name);\n if (svc != null) return svc;\n } catch {\n // Service not registered or sync resolution threw \"is async\" — fall through\n }\n }\n if (this.kernel?.context?.getService) {\n try {\n const svc = await this.kernel.context.getService(name);\n if (svc != null) return svc;\n } catch {\n // Service not registered — fall through\n }\n }\n const services = this.getServicesMap();\n return services[name];\n }\n\n /**\n * Get the ObjectQL service which provides access to SchemaRegistry.\n * Tries multiple access patterns since kernel structure varies.\n */\n private async getObjectQLService(scopeId?: string): Promise<any> {\n // 1. Try via resolveService (handles scoped, async factories, sync, context, and map)\n try {\n const svc = await this.resolveService('objectql', scopeId);\n if (svc?.registry) return svc;\n } catch { /* service not available */ }\n return null;\n }\n\n /**\n * Handle action invocation routes (`/actions/...`).\n *\n * Dispatches a named, server-registered action handler (registered via\n * `engine.registerAction(objectName, actionName, handler)`) over HTTP.\n * Three URL shapes are accepted to keep the client contract flexible:\n *\n * - `POST /actions/:object/:action` — record-scoped action\n * - `POST /actions/:object/:action/:recordId` — record-scoped action with id in URL\n * - `POST /actions/global/:action` — wildcard (\"*\") action\n *\n * Body shape: `{ recordId?: string, params?: Record<string, unknown> }`.\n * The handler is invoked with an `ActionContext` of:\n * `{ record, user, engine, params }`\n * where `engine` exposes the slimmed CRUD surface used by CRM handlers\n * (`insert`, `update`, `delete`, `find`).\n */\n async handleActions(path: string, method: string, body: any, _context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n if (method.toUpperCase() !== 'POST') {\n return { handled: true, response: this.error('Method not allowed', 405) };\n }\n const parts = path.replace(/^\\/+|\\/+$/g, '').split('/').filter(Boolean);\n if (parts.length < 2) {\n return { handled: true, response: this.error('Path must be /actions/:object/:action', 400) };\n }\n const objectName = parts[0];\n const actionName = parts[1];\n const recordIdFromPath = parts[2];\n\n // Resolve project scope so the right project kernel's ObjectQL is\n // used. For bare URLs the URL prefix already stripped any `/projects/:id`\n // segment, so fall back to the single-environment default if unset.\n if (!_context.environmentId) {\n const def = this.resolveDefaultProject();\n if (def?.environmentId) _context.environmentId = def.environmentId;\n }\n\n // Replicate the kernel swap that `dispatcher.handle()` does for\n // data/meta/automation routes. Action routes are registered on the\n // raw HTTP server and skip the `handle()` chain, so without this\n // swap `getObjectQLService` would resolve the control-plane kernel\n // (where the CRM bundle's actions are NOT registered).\n let projectQl: any = null;\n if (this.kernelManager && _context.environmentId && _context.environmentId !== 'platform') {\n try {\n const projectKernel: any = await this.kernelManager.getOrCreate(_context.environmentId);\n if (projectKernel) {\n this.kernel = projectKernel;\n // Resolve the project kernel's own ObjectQL DIRECTLY so we\n // bypass the control-plane's scoped factory (which would\n // hand back a different instance with no registered\n // actions/hooks for this project's bundle).\n if (typeof projectKernel.getServiceAsync === 'function') {\n projectQl = await projectKernel.getServiceAsync('objectql').catch(() => null);\n }\n }\n } catch {\n // fall back to defaultKernel — getObjectQLService will report\n // \"Data engine not available\" if no engine is reachable.\n }\n }\n\n const ql: any = projectQl ?? await this.getObjectQLService(_context?.environmentId);\n if (!ql || typeof ql.executeAction !== 'function') {\n return { handled: true, response: this.error('Data engine not available', 503) };\n }\n\n // Resolve the handler — fall back to wildcard '*' if the object-specific key is missing.\n // Since engine.executeAction throws when the key is unknown, we probe via the internal\n // map by attempting the call inside a try/catch and rotating to '*'.\n const tryExecute = async (obj: string) => {\n return ql.executeAction(obj, actionName, actionContext);\n };\n\n const reqBody = body && typeof body === 'object' ? body : {};\n const recordId = recordIdFromPath ?? reqBody.recordId;\n const reqParams = (reqBody.params && typeof reqBody.params === 'object') ? reqBody.params : {};\n\n // Load the record (best-effort) so handlers can rely on `ctx.record`.\n let record: Record<string, unknown> = {};\n if (recordId && objectName !== 'global') {\n try {\n const got = await this.callData('get', { object: objectName, id: recordId }, _context.dataDriver, _context.environmentId, _context.executionContext);\n if (got?.record) record = got.record;\n } catch { /* record may not exist for new-record actions; pass empty */ }\n }\n if (record && (record as any).id == null && recordId) (record as any).id = recordId;\n\n // Slim engine facade matching the ActionContext.engine shape used by CRM handlers.\n const engineFacade = {\n async insert(object: string, data: Record<string, unknown>): Promise<{ id: string }> {\n const res = await ql.insert(object, data);\n const id = (res && (res as any).id) ?? (data as any).id;\n return { id };\n },\n async update(object: string, id: string, data: Record<string, unknown>): Promise<void> {\n await ql.update(object, data, { where: { id } });\n },\n async delete(object: string, id: string): Promise<void> {\n await ql.delete(object, { where: { id } });\n },\n async find(object: string, query: Record<string, unknown>): Promise<Array<Record<string, unknown>>> {\n const opts = query && Object.keys(query).length ? { where: query } : undefined;\n const rows = await ql.find(object, opts as any);\n return Array.isArray(rows) ? rows : ((rows as any)?.value ?? []);\n },\n };\n\n const userIdFromAuth = (_context as any)?.user?.id ?? (_context as any)?.userId ?? 'system';\n const userFromAuth = (_context as any)?.user ?? { id: userIdFromAuth, name: userIdFromAuth };\n\n const actionContext: any = {\n record,\n user: userFromAuth,\n engine: engineFacade,\n params: { ...reqParams, recordId, objectName },\n };\n\n try {\n // Try object-specific first; on \"not found\" error, fall back to wildcard.\n let result: any;\n try {\n result = await tryExecute(objectName);\n } catch (err: any) {\n const msg = String(err?.message ?? err ?? '');\n if (/not found/i.test(msg) && objectName !== '*') {\n result = await tryExecute('*');\n } else {\n throw err;\n }\n }\n return { handled: true, response: this.success({ success: true, data: result }) };\n } catch (err: any) {\n const msg = err?.message ?? String(err);\n return { handled: true, response: this.success({ success: false, error: msg }) };\n }\n }\n\n /**\n * Handle AI service routes (/ai/chat, /ai/models, /ai/conversations, etc.)\n * Resolves the AI service and its built-in route handlers, then dispatches.\n */\n async handleAI(subPath: string, method: string, body: any, query: any, context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n let aiService: any;\n try {\n aiService = await this.resolveService('ai');\n } catch {\n // AI service not registered\n }\n\n if (!aiService) {\n return {\n handled: true,\n response: {\n status: 404,\n body: { success: false, error: { message: 'AI service is not configured', code: 404 } },\n },\n };\n }\n\n // The AI service exposes route definitions via buildAIRoutes.\n // We match the request path against known AI route patterns.\n const fullPath = `/api/v1${subPath}`;\n\n // Build a simple param-extracting matcher for route patterns like /api/v1/ai/conversations/:id\n const matchRoute = (pattern: string, path: string): Record<string, string> | null => {\n const patternParts = pattern.split('/');\n const pathParts = path.split('/');\n if (patternParts.length !== pathParts.length) return null;\n const params: Record<string, string> = {};\n for (let i = 0; i < patternParts.length; i++) {\n if (patternParts[i].startsWith(':')) {\n params[patternParts[i].substring(1)] = pathParts[i];\n } else if (patternParts[i] !== pathParts[i]) {\n return null;\n }\n }\n return params;\n };\n\n // Try to get route definitions from the AI service's cached routes\n const routes = (this.kernel as any).__aiRoutes as Array<{\n method: string; path: string; handler: (req: any) => Promise<any>;\n }> | undefined;\n\n if (!routes) {\n return {\n handled: true,\n response: {\n status: 503,\n body: { success: false, error: { message: 'AI service routes not yet initialized', code: 503 } },\n },\n };\n }\n\n for (const route of routes) {\n if (route.method !== method) continue;\n const params = matchRoute(route.path, fullPath);\n if (params === null) continue;\n\n // Resolve `req.user` from the already-resolved ExecutionContext so\n // AI route handlers can attribute the call to the authenticated\n // actor (drives auto-titled conversations, permission-aware\n // tools, HITL conversation linkage, …). Falls back to undefined\n // for anonymous requests — the route's own `auth: true` guard\n // is enforced by upstream middleware.\n const ec: any = context.executionContext;\n const user = ec?.userId\n ? {\n userId: ec.userId,\n id: ec.userId,\n displayName: ec.userDisplayName ?? ec.userName ?? ec.userId,\n email: ec.userEmail,\n roles: Array.isArray(ec.roles) ? ec.roles : [],\n permissions: Array.isArray(ec.permissions) ? ec.permissions : [],\n organizationId: ec.tenantId,\n }\n : undefined;\n\n const result = await route.handler({\n body,\n params,\n query,\n headers: context.request?.headers,\n user,\n });\n\n if (result.stream && result.events) {\n // Return a streaming result for the adapter to handle\n return {\n handled: true,\n result: {\n type: 'stream',\n contentType: result.vercelDataStream\n ? 'text/plain; charset=utf-8'\n : 'text/event-stream',\n events: result.events,\n vercelDataStream: result.vercelDataStream,\n headers: {\n 'Content-Type': result.vercelDataStream\n ? 'text/plain; charset=utf-8'\n : 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n },\n },\n };\n }\n\n return {\n handled: true,\n response: {\n status: result.status,\n body: result.body,\n },\n };\n }\n\n return {\n handled: true,\n response: this.routeNotFound(subPath),\n };\n }\n\n /**\n * Main Dispatcher Entry Point\n * Routes the request to the appropriate handler based on path and precedence\n */\n async dispatch(method: string, path: string, body: any, query: any, context: HttpProtocolContext, prefix?: string): Promise<HttpDispatcherResult> {\n let cleanPath = path.replace(/\\/$/, ''); // Remove trailing slash if present, but strict on clean paths\n\n // ── Environment Resolution ──\n // Resolve environment context for data-plane requests before routing\n await this.resolveEnvironmentContext(context, cleanPath);\n\n // ── Multi-Kernel Routing (ADR-0003 cloud mode) ──\n // When a KernelManager is wired in, per-request routing targets the\n // project's dedicated kernel. Self-hosted / legacy deployments leave\n // `kernelManager` unset and continue using the constructor kernel.\n // Reserved virtual id 'platform' addresses the control plane through\n // the regular project URL family — never spin up a per-project kernel\n // for it (there is no projects row to look up).\n if (this.kernelManager && context.environmentId && context.environmentId !== 'platform') {\n this.kernel = await this.kernelManager.getOrCreate(context.environmentId);\n } else {\n this.kernel = this.defaultKernel;\n }\n\n // Touch scope for TTL/LRU tracking in shared-kernel mode\n if (this.scopeManager && context.environmentId && context.environmentId !== 'platform') {\n this.scopeManager.touch(context.environmentId);\n }\n\n // ── Identity Resolution (RBAC/RLS/FLS context) ──\n // Resolve once per request; SecurityPlugin middleware reads\n // ctx.userId/roles/permissions/tenantId via opCtx.context.\n try {\n context.executionContext = await resolveExecutionContext({\n getService: (n: string) => this.resolveService(n, context.environmentId),\n getQl: () => Promise.resolve(this.getObjectQLService(context.environmentId)),\n request: context.request,\n });\n } catch {\n // anonymous request — leave executionContext undefined\n }\n\n // ── Project Membership Enforcement ──\n // Once the environmentId is known, gate scoped data/meta/AI/automation\n // routes on `sys_environment_member`. Control-plane paths, the system\n // project, and platform-org members bypass this check.\n const forbidden = await this.enforceProjectMembership(context, cleanPath);\n if (forbidden) {\n return { handled: true, response: forbidden };\n }\n\n // Strip the `/environments/:environmentId` prefix so the protocol dispatchers\n // below (meta, data, ui, automation, …) see the same shape whether\n // the caller used host-based routing, `X-Environment-Id`, or a scoped URL.\n const scopedMatch = cleanPath.match(/^\\/projects\\/[^/]+(\\/.*)?$/);\n if (scopedMatch) {\n cleanPath = scopedMatch[1] ?? '';\n }\n\n // 0. Discovery Endpoint (GET /discovery or GET /)\n // Standard route: /discovery (protocol-compliant)\n // Legacy route: / (empty path, for backward compatibility — MSW strips base URL)\n try {\n if ((cleanPath === '/discovery' || cleanPath === '') && method === 'GET') {\n const info = await this.getDiscoveryInfo(prefix ?? '');\n return { \n handled: true, \n response: this.success(info) \n };\n }\n\n // 0b. Health Endpoint (GET /health)\n if (cleanPath === '/health' && method === 'GET') {\n return {\n handled: true,\n response: this.success({\n status: 'ok',\n timestamp: new Date().toISOString(),\n version: '1.0.0',\n uptime: typeof process !== 'undefined' ? process.uptime() : undefined,\n }),\n };\n }\n\n // 0c. Plan-A diagnostics removed; the seed-replay and oauth2/callback\n // probes were temporary debugging tools used during the SSO rollout.\n\n // 1. System Protocols (Prefix-based)\n if (cleanPath.startsWith('/auth')) {\n return this.handleAuth(cleanPath.substring(5), method, body, context);\n }\n \n if (cleanPath.startsWith('/meta')) {\n return this.handleMetadata(cleanPath.substring(5), context, method, body, query);\n }\n\n if (cleanPath.startsWith('/data')) {\n return this.handleData(cleanPath.substring(5), method, body, query, context);\n }\n \n if (cleanPath.startsWith('/graphql')) {\n if (method === 'POST') return this.handleGraphQL(body, context);\n // GraphQL usually GET for Playground is handled by middleware but we can return 405 or handle it\n }\n\n if (cleanPath.startsWith('/storage')) {\n return this.handleStorage(cleanPath.substring(8), method, body, context); // body here is file/stream for upload\n }\n \n if (cleanPath.startsWith('/ui')) {\n return this.handleUi(cleanPath.substring(3), query, context);\n }\n\n if (cleanPath.startsWith('/automation')) {\n return this.handleAutomation(cleanPath.substring(11), method, body, context, query);\n }\n\n if (cleanPath.startsWith('/actions')) {\n return this.handleActions(cleanPath.substring(8), method, body, context);\n }\n \n if (cleanPath.startsWith('/analytics')) {\n return this.handleAnalytics(cleanPath.substring(10), method, body, context);\n }\n\n // In-app notifications (ADR-0030) — inbox list + receipt mark-read,\n // backed by the messaging service registered under the `notification` slot.\n if (cleanPath.startsWith('/notifications')) {\n return this.handleNotification(cleanPath.substring(14), method, body, query, context);\n }\n\n if (cleanPath.startsWith('/packages')) {\n return this.handlePackages(cleanPath.substring(9), method, body, query, context);\n }\n\n if (cleanPath.startsWith('/i18n')) {\n return this.handleI18n(cleanPath.substring(5), method, query, context);\n }\n\n // AI Service — delegate to the registered AI route handlers\n if (cleanPath.startsWith('/ai')) {\n return this.handleAI(cleanPath, method, body, query, context);\n }\n\n // OpenAPI Specification\n if (cleanPath === '/openapi.json' && method === 'GET') {\n try {\n const metaSvc = await this.resolveService('metadata', context.environmentId);\n if (metaSvc && typeof (metaSvc as any).generateOpenApi === 'function') {\n const result = await (metaSvc as any).generateOpenApi({});\n return { handled: true, response: this.success(result) };\n }\n } catch (e) {\n // If not implemented, fall through or return 404\n }\n }\n\n // 2. Custom API Endpoints (Registry lookup)\n // Check if there is a custom endpoint defined for this path\n const result = await this.handleApiEndpoint(cleanPath, method, body, query, context);\n if (result.handled) return result;\n\n // 3. Fallback — return semantic 404 with diagnostic info\n return {\n handled: true,\n response: this.routeNotFound(cleanPath),\n };\n } catch (e) {\n if (isPermissionDeniedError(e)) {\n return {\n handled: true,\n response: this.error(e.message, 403, { code: 'PERMISSION_DENIED', ...(e.details ?? {}) }),\n };\n }\n throw e;\n }\n }\n\n /**\n * Handles Custom API Endpoints defined in metadata\n */\n async handleApiEndpoint(path: string, method: string, body: any, query: any, context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n try {\n // Attempt to find a matching endpoint in the registry\n const metaSvc = await this.resolveService('metadata', context.environmentId);\n if (!metaSvc || typeof (metaSvc as any).matchEndpoint !== 'function') {\n return { handled: false };\n }\n const endpoint = await (metaSvc as any).matchEndpoint({ path, method });\n \n if (endpoint) {\n // Execute the endpoint target logic\n if (endpoint.type === 'flow') {\n const automationSvc = await this.resolveService('automation');\n if (!automationSvc || typeof (automationSvc as any).runFlow !== 'function') {\n return { handled: true, response: this.error('Automation service not available', 503) };\n }\n const result = await (automationSvc as any).runFlow({ \n flowId: endpoint.target, \n inputs: { ...query, ...body, _request: context.request } \n });\n return { handled: true, response: this.success(result) };\n }\n \n if (endpoint.type === 'script') {\n const automationSvc = await this.resolveService('automation');\n if (!automationSvc || typeof (automationSvc as any).runScript !== 'function') {\n return { handled: true, response: this.error('Automation service not available', 503) };\n }\n const result = await (automationSvc as any).runScript({ \n scriptName: endpoint.target, \n context: { ...query, ...body, request: context.request } \n });\n return { handled: true, response: this.success(result) };\n }\n\n if (endpoint.type === 'object_operation') {\n // e.g. Proxy to an object action\n if (endpoint.objectParams) {\n const { object, operation } = endpoint.objectParams;\n // Map standard CRUD operations\n if (operation === 'find') {\n const result = await this.callData('query', { object, query });\n // Spec: FindDataResponse = { object, records, total?, hasMore? }\n return { handled: true, response: this.success(result.records, { total: result.total }) };\n }\n if (operation === 'get' && query.id) {\n const result = await this.callData('get', { object, id: query.id });\n return { handled: true, response: this.success(result) };\n }\n if (operation === 'create') {\n const result = await this.callData('create', { object, data: body });\n return { handled: true, response: this.success(result) };\n }\n }\n }\n\n if (endpoint.type === 'proxy') {\n return { \n handled: true, \n response: { \n status: 200, \n body: { proxy: true, target: endpoint.target, note: 'Proxy execution requires http-client service' } \n } \n };\n }\n }\n } catch (e) {\n // If matchEndpoint fails (e.g. not found), we just return not handled\n // so we can fallback to 404 or other handlers\n }\n\n return { handled: false };\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * resolveExecutionContext — REST entry-point identity resolver.\n *\n * Builds an {@link ExecutionContext} from an incoming HTTP request by combining:\n * - better-auth Bearer/Session cookies (`authService.api.getSession`)\n * - API Key headers (`X-API-Key` / `Authorization: ApiKey <token>`) — first\n * via better-auth's apiKey plugin if available, otherwise a direct lookup\n * against the `sys_api_key` system object.\n * - `sys_member` lookup for `(userId, activeOrganizationId)` to populate\n * organization-scoped roles, plus any extra permission sets bound through\n * the `sys_user_permission_set` / `sys_role_permission_set` link tables.\n *\n * The resolver is intentionally non-fatal: when auth is not wired up or any\n * of the dependent services are unavailable, it returns the partial context\n * that can be reconstructed (even an empty `{ isSystem: false, roles: [],\n * permissions: [] }`). Permission enforcement is the SecurityPlugin's job.\n */\n\nimport type { ExecutionContext } from '@objectstack/spec/kernel';\n\ninterface ResolveOptions {\n /** Function returning a service from the active kernel (or undefined). */\n getService: (name: string) => Promise<any> | any;\n /** Function returning the data engine (ObjectQL) for the active scope. */\n getQl: () => Promise<any> | any;\n /** The raw incoming HTTP request (Fetch Request, Node IncomingMessage, …). */\n request: any;\n}\n\nfunction readHeader(headers: any, name: string): string | undefined {\n if (!headers) return undefined;\n const lower = name.toLowerCase();\n if (typeof headers.get === 'function') {\n const v = headers.get(name) ?? headers.get(lower);\n return v == null ? undefined : String(v);\n }\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === lower) {\n const v = headers[key];\n return Array.isArray(v) ? v[0] : v == null ? undefined : String(v);\n }\n }\n return undefined;\n}\n\nfunction extractApiKey(headers: any): string | undefined {\n const x = readHeader(headers, 'x-api-key');\n if (x) return x.trim();\n const auth = readHeader(headers, 'authorization');\n if (!auth) return undefined;\n const m = auth.match(/^ApiKey\\s+(.+)$/i);\n return m ? m[1].trim() : undefined;\n}\n\n/**\n * Convert the dispatcher's plain `Record<string,string>` headers map into\n * a Web `Headers` instance so libraries like better-auth (which reads via\n * `headers.get('cookie')`) work uniformly.\n */\nfunction toHeaders(input: any): any {\n if (!input) return new Headers();\n if (typeof Headers !== 'undefined' && input instanceof Headers) return input;\n const h = new Headers();\n if (typeof input.entries === 'function') {\n for (const [k, v] of input.entries()) h.set(String(k), String(v));\n return h;\n }\n for (const k of Object.keys(input)) {\n const v = (input as any)[k];\n if (v == null) continue;\n h.set(String(k), Array.isArray(v) ? v.join(',') : String(v));\n }\n return h;\n}\n\nfunction safeJsonParse<T>(s: string, fallback: T): T {\n try { return JSON.parse(s) as T; } catch { return fallback; }\n}\n\nasync function tryFind(ql: any, object: string, where: any, limit = 100): Promise<any[]> {\n if (!ql || typeof ql.find !== 'function') return [];\n try {\n let rows = await ql.find(object, { where, limit, context: { isSystem: true } } as any);\n if (rows && (rows as any).value) rows = (rows as any).value;\n return Array.isArray(rows) ? rows : [];\n } catch {\n return [];\n }\n}\n\n/**\n * Resolve the {@link ExecutionContext} for an inbound request.\n *\n * Always resolves — never throws. Anonymous requests yield\n * `{ isSystem: false, roles: [], permissions: [] }`.\n */\nexport async function resolveExecutionContext(opts: ResolveOptions): Promise<ExecutionContext> {\n const headers = opts.request?.headers;\n const ctx: ExecutionContext = {\n roles: [],\n permissions: [],\n systemPermissions: [],\n isSystem: false,\n };\n\n let userId: string | undefined;\n let tenantId: string | undefined;\n\n // 1. API Key path — takes precedence over session, since callers explicitly\n // opt in to API-key auth via the header.\n const apiKey = extractApiKey(headers);\n if (apiKey) {\n try {\n const authService: any = await opts.getService('auth');\n // better-auth apiKey plugin (if enabled) exposes a verify endpoint.\n const verify = authService?.api?.verifyApiKey ?? authService?.api?.apiKey?.verify;\n if (typeof verify === 'function') {\n const res = await verify({ body: { key: apiKey } });\n const payload = res?.key ?? res;\n if (payload?.userId) userId = payload.userId;\n if (payload?.organizationId) tenantId = payload.organizationId;\n if (Array.isArray(payload?.permissions)) {\n ctx.permissions!.push(...payload.permissions);\n }\n if (Array.isArray(payload?.scopes)) {\n ctx.permissions!.push(...payload.scopes);\n }\n }\n } catch {\n // ignore — fall through to direct lookup\n }\n\n if (!userId) {\n // Direct lookup against sys_api_key — supports keys provisioned outside\n // of better-auth (legacy or self-managed).\n const ql = await opts.getQl();\n const rows = await tryFind(ql, 'sys_api_key', { key: apiKey, active: true }, 1);\n const row = rows[0];\n if (row) {\n userId = row.user_id ?? row.userId;\n tenantId = row.organization_id ?? row.organizationId;\n if (Array.isArray(row.scopes)) ctx.permissions!.push(...row.scopes);\n }\n }\n }\n\n // 2. Session / Bearer path — fall back when API key did not resolve a user.\n if (!userId) {\n try {\n const authService: any = await opts.getService('auth');\n // The auth service surfaces its better-auth API either as `.api`\n // (legacy direct mount) or via `await getApi()` (lazy plugin).\n // Try both so we don't silently degrade to anonymous when the\n // shape differs across plugin versions.\n let api: any = authService?.api;\n if (!api && typeof authService?.getApi === 'function') {\n api = await authService.getApi();\n }\n const headersInstance = toHeaders(headers);\n const sessionData = await api?.getSession?.({ headers: headersInstance });\n userId = sessionData?.user?.id ?? sessionData?.session?.userId;\n tenantId = tenantId ?? sessionData?.session?.activeOrganizationId;\n ctx.accessToken = sessionData?.session?.token ?? ctx.accessToken;\n } catch {\n // no auth configured — return anonymous context\n }\n }\n\n if (userId) ctx.userId = userId;\n if (tenantId) ctx.tenantId = tenantId;\n\n if (!userId) return ctx;\n\n // 3. Resolve organization-scoped roles via sys_member, then merge any\n // permission sets bound via the link tables. All lookups go through\n // ObjectQL with `isSystem: true` to avoid recursion through the\n // SecurityPlugin middleware.\n const ql = await opts.getQl();\n if (!ql) return ctx;\n\n const memberWhere: any = tenantId\n ? { user_id: userId, organization_id: tenantId }\n : { user_id: userId };\n const members = await tryFind(ql, 'sys_member', memberWhere, 50);\n for (const m of members) {\n if (m.role && typeof m.role === 'string') {\n // better-auth stores comma-separated roles for multi-role membership.\n for (const r of m.role.split(',').map((s: string) => s.trim()).filter(Boolean)) {\n if (!ctx.roles!.includes(r)) ctx.roles!.push(r);\n }\n }\n }\n\n // 3a. Resolve fellow-organization user IDs so RLS can scope identity\n // tables (`sys_user`) to collaborators in the active org via\n // `id IN (current_user.org_user_ids)`. Without this, the default\n // `id = current_user.id` policy on sys_user makes @-mention pickers,\n // owner/assignee lookups and reviewer selectors all return just the\n // current user. Hard-capped at 1000 members per request — large\n // enterprises should plug in a cache or directory adapter.\n if (tenantId) {\n const orgMembers = await tryFind(\n ql,\n 'sys_member',\n { organization_id: tenantId },\n 1000,\n );\n const orgUserIds = Array.from(\n new Set(\n orgMembers\n .map((m) => m.user_id ?? m.userId)\n .filter((v): v is string => typeof v === 'string' && v.length > 0),\n ),\n );\n // Always include self even if the sys_member lookup misfires (e.g.\n // API key auth where the user is recognised but not in sys_member).\n if (!orgUserIds.includes(userId)) orgUserIds.push(userId);\n (ctx as any).org_user_ids = orgUserIds;\n } else {\n // No active org → at minimum the user can see themselves.\n (ctx as any).org_user_ids = [userId];\n }\n\n // Resolve user-scoped permission sets.\n const upsRows = await tryFind(\n ql,\n 'sys_user_permission_set',\n tenantId\n ? { user_id: userId, organization_id: tenantId }\n : { user_id: userId },\n 100,\n );\n const psIds = new Set<string>(\n upsRows.map((r) => r.permission_set_id ?? r.permissionSetId).filter(Boolean),\n );\n\n // Resolve role-bound permission sets.\n if (ctx.roles!.length > 0) {\n const roleRows = await tryFind(ql, 'sys_role', { name: { $in: ctx.roles } }, 100);\n const roleIds = roleRows.map((r) => r.id).filter(Boolean);\n if (roleIds.length > 0) {\n const rpsRows = await tryFind(\n ql,\n 'sys_role_permission_set',\n { role_id: { $in: roleIds } },\n 500,\n );\n for (const r of rpsRows) {\n const id = r.permission_set_id ?? r.permissionSetId;\n if (id) psIds.add(id);\n }\n }\n }\n\n if (psIds.size > 0) {\n // Surface permission set names through ctx.permissions so downstream\n // SecurityPlugin can look them up. We store the canonical `name` field.\n const psRows = await tryFind(\n ql,\n 'sys_permission_set',\n { id: { $in: Array.from(psIds) } },\n 500,\n );\n const tabRank: Record<string, number> = {\n hidden: 0,\n default_off: 1,\n default_on: 2,\n visible: 3,\n };\n const mergedTabs: Record<string, 'visible' | 'hidden' | 'default_on' | 'default_off'> = {};\n for (const ps of psRows) {\n if (ps.name && !ctx.permissions!.includes(ps.name)) {\n ctx.permissions!.push(ps.name);\n }\n // System permissions may be stored as JSON string in DB rows.\n const sysPerms = typeof ps.system_permissions === 'string'\n ? safeJsonParse(ps.system_permissions, [])\n : (ps.system_permissions ?? ps.systemPermissions);\n if (Array.isArray(sysPerms)) {\n for (const p of sysPerms) {\n if (typeof p === 'string' && !ctx.systemPermissions!.includes(p)) {\n ctx.systemPermissions!.push(p);\n }\n }\n }\n const tabs = typeof ps.tab_permissions === 'string'\n ? safeJsonParse(ps.tab_permissions, {})\n : (ps.tab_permissions ?? ps.tabPermissions);\n if (tabs && typeof tabs === 'object') {\n for (const [app, val] of Object.entries(tabs as Record<string, unknown>)) {\n if (typeof val !== 'string' || !(val in tabRank)) continue;\n const cur = mergedTabs[app];\n if (!cur || tabRank[val] > tabRank[cur]) {\n mergedTabs[app] = val as 'visible' | 'hidden' | 'default_on' | 'default_off';\n }\n }\n }\n }\n if (Object.keys(mergedTabs).length > 0) {\n ctx.tabPermissions = mergedTabs;\n }\n }\n\n return ctx;\n}\n\n/**\n * Typed sentinel error thrown by SecurityPlugin (and re-thrown here) when an\n * operation is denied. The dispatcher catches it and translates to HTTP 403.\n *\n * Kept structurally identical to {@link `@objectstack/plugin-security`}'s\n * `PermissionDeniedError` so `isPermissionDeniedError` matches whichever\n * class instance crosses the boundary, regardless of which package owns\n * the actual class identity at runtime. We do not add a hard dependency\n * on `plugin-security` here to keep the runtime usable in stack\n * compositions without security enforcement.\n */\nexport class PermissionDeniedError extends Error {\n readonly code = 'PERMISSION_DENIED';\n readonly statusCode = 403;\n readonly details?: Record<string, unknown>;\n constructor(message: string, details?: Record<string, unknown>) {\n super(message);\n this.name = 'PermissionDeniedError';\n this.details = details;\n }\n}\n\nexport function isPermissionDeniedError(e: unknown): e is PermissionDeniedError {\n if (!e || typeof e !== 'object') return false;\n const anyE = e as any;\n return (\n anyE.name === 'PermissionDeniedError' ||\n anyE.code === 'PERMISSION_DENIED' ||\n (typeof anyE.message === 'string' && anyE.message.startsWith('[Security] Access denied'))\n );\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Security response headers builder.\n *\n * Returns the conservative defaults every production API server should\n * send on every response. Designed to be merged with route-specific\n * headers by the dispatcher (`sendResult`) so all adapters (Hono,\n * Fastify, Express, Next.js, …) get them uniformly without each one\n * re-implementing helmet.\n *\n * What we DO opinionate:\n * - Content-Security-Policy (api-default: deny everything but self)\n * - Strict-Transport-Security (HSTS, prod-only — TLS is the caller's\n * responsibility; we just emit the header)\n * - X-Content-Type-Options: nosniff\n * - X-Frame-Options: DENY (anti clickjacking)\n * - Referrer-Policy: no-referrer\n * - Permissions-Policy: geolocation=(), camera=(), microphone=()\n * - Cross-Origin-Resource-Policy: same-origin\n *\n * What we DON'T opinionate:\n * - X-XSS-Protection (deprecated)\n * - CORS — that's an app concern, configure separately\n * - CSP for HTML pages — set a different CSP at the SPA host\n *\n * Every header can be overridden or disabled by config.\n */\n\nexport interface SecurityHeadersOptions {\n /**\n * Enable HSTS. Set to `true` in production behind TLS. When `false`\n * the Strict-Transport-Security header is omitted.\n * @default false\n */\n hsts?: boolean | {\n /** Max-age in seconds. @default 15552000 (180 days) */\n maxAge?: number;\n includeSubDomains?: boolean;\n preload?: boolean;\n };\n /**\n * Override the Content-Security-Policy header. Pass `false` to omit.\n * @default \"default-src 'none'; frame-ancestors 'none'\"\n */\n contentSecurityPolicy?: string | false;\n /**\n * Override X-Frame-Options. @default 'DENY'\n */\n frameOptions?: 'DENY' | 'SAMEORIGIN' | false;\n /**\n * Override Referrer-Policy. @default 'no-referrer'\n */\n referrerPolicy?: string | false;\n /**\n * Override Permissions-Policy. Pass `false` to omit.\n * @default 'geolocation=(), camera=(), microphone=(), payment=()'\n */\n permissionsPolicy?: string | false;\n /**\n * Override Cross-Origin-Resource-Policy. @default 'same-origin'\n */\n corp?: 'same-origin' | 'same-site' | 'cross-origin' | false;\n /**\n * Free-form extra headers merged last.\n */\n extra?: Record<string, string>;\n}\n\n/**\n * Build a header map ready to be `Object.assign`'d into a response.\n * Idempotent and synchronous — safe to call per-request.\n */\nexport function buildSecurityHeaders(opts: SecurityHeadersOptions = {}): Record<string, string> {\n const h: Record<string, string> = {};\n\n if (opts.contentSecurityPolicy !== false) {\n h['Content-Security-Policy'] =\n opts.contentSecurityPolicy ?? \"default-src 'none'; frame-ancestors 'none'\";\n }\n\n if (opts.hsts) {\n const cfg = typeof opts.hsts === 'object' ? opts.hsts : {};\n const maxAge = cfg.maxAge ?? 15_552_000;\n const parts = [`max-age=${maxAge}`];\n if (cfg.includeSubDomains ?? true) parts.push('includeSubDomains');\n if (cfg.preload) parts.push('preload');\n h['Strict-Transport-Security'] = parts.join('; ');\n }\n\n h['X-Content-Type-Options'] = 'nosniff';\n\n if (opts.frameOptions !== false) {\n h['X-Frame-Options'] = opts.frameOptions ?? 'DENY';\n }\n\n if (opts.referrerPolicy !== false) {\n h['Referrer-Policy'] = opts.referrerPolicy ?? 'no-referrer';\n }\n\n if (opts.permissionsPolicy !== false) {\n h['Permissions-Policy'] =\n opts.permissionsPolicy ?? 'geolocation=(), camera=(), microphone=(), payment=()';\n }\n\n if (opts.corp !== false) {\n h['Cross-Origin-Resource-Policy'] = opts.corp ?? 'same-origin';\n }\n\n if (opts.extra) {\n Object.assign(h, opts.extra);\n }\n\n return h;\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * In-memory token-bucket rate limiter.\n *\n * Designed to be adapter-agnostic — the dispatcher calls `consume(key)`\n * with a request fingerprint (IP, IP+route bucket, or user id) and\n * short-circuits with 429 if the bucket is empty.\n *\n * For production multi-instance deploys, swap the in-memory store via\n * `RateLimitStore`. The shape is intentionally narrow so a Redis-backed\n * implementation is straightforward.\n */\n\nexport interface RateLimitDecision {\n allowed: boolean;\n /** Remaining tokens in the bucket after this consume. */\n remaining: number;\n /** Wall-clock ms until next token is available (when not allowed). */\n retryAfterMs: number;\n /** UNIX ms when the limit window resets. */\n resetAt: number;\n}\n\nexport interface RateLimitBucketConfig {\n /** Max tokens (bucket capacity). */\n capacity: number;\n /** Tokens added per second. */\n refillPerSec: number;\n /** Optional cost override for the consume operation. @default 1 */\n defaultCost?: number;\n}\n\ninterface BucketState {\n tokens: number;\n /** Last refill timestamp (ms). */\n lastRefill: number;\n}\n\n/**\n * Storage interface — swap for Redis/Memcached in clustered deploys.\n * Implementations MUST be safe under concurrent access.\n */\nexport interface RateLimitStore {\n get(key: string): BucketState | undefined;\n set(key: string, state: BucketState): void;\n /** Cleanup hint — implementations may evict idle entries. */\n prune?(olderThanMs: number): void;\n}\n\nclass MemoryStore implements RateLimitStore {\n private buckets = new Map<string, BucketState>();\n private maxEntries: number;\n\n constructor(maxEntries = 100_000) {\n this.maxEntries = maxEntries;\n }\n\n get(key: string): BucketState | undefined {\n return this.buckets.get(key);\n }\n\n set(key: string, state: BucketState): void {\n // Crude LRU eviction — drop the oldest 10% when we hit the cap.\n // Good enough for an in-memory store; replace with Redis if you\n // need precision under load.\n if (this.buckets.size >= this.maxEntries) {\n const dropCount = Math.max(1, Math.floor(this.maxEntries / 10));\n const iter = this.buckets.keys();\n for (let i = 0; i < dropCount; i++) {\n const k = iter.next().value;\n if (!k) break;\n this.buckets.delete(k);\n }\n }\n this.buckets.set(key, state);\n }\n\n prune(olderThanMs: number): void {\n const cutoff = Date.now() - olderThanMs;\n for (const [k, v] of this.buckets) {\n if (v.lastRefill < cutoff) this.buckets.delete(k);\n }\n }\n}\n\nexport class RateLimiter {\n private config: RateLimitBucketConfig;\n private store: RateLimitStore;\n private now: () => number;\n\n constructor(config: RateLimitBucketConfig, opts: { store?: RateLimitStore; now?: () => number } = {}) {\n if (config.capacity <= 0) throw new Error('RateLimiter: capacity must be > 0');\n if (config.refillPerSec <= 0) throw new Error('RateLimiter: refillPerSec must be > 0');\n this.config = config;\n this.store = opts.store ?? new MemoryStore();\n // Injectable clock keeps tests deterministic.\n this.now = opts.now ?? Date.now;\n }\n\n /**\n * Attempt to consume `cost` tokens for `key`. Returns a decision\n * describing whether the request should proceed and, if not, how\n * long the caller should wait before retrying.\n */\n consume(key: string, cost = this.config.defaultCost ?? 1): RateLimitDecision {\n const now = this.now();\n const { capacity, refillPerSec } = this.config;\n\n let state = this.store.get(key);\n if (!state) {\n state = { tokens: capacity, lastRefill: now };\n } else {\n const elapsedSec = (now - state.lastRefill) / 1000;\n if (elapsedSec > 0) {\n state = {\n tokens: Math.min(capacity, state.tokens + elapsedSec * refillPerSec),\n lastRefill: now,\n };\n }\n }\n\n if (state.tokens >= cost) {\n state.tokens -= cost;\n this.store.set(key, state);\n return {\n allowed: true,\n remaining: Math.floor(state.tokens),\n retryAfterMs: 0,\n resetAt: now + Math.ceil(((capacity - state.tokens) / refillPerSec) * 1000),\n };\n }\n\n const tokensNeeded = cost - state.tokens;\n const retryAfterMs = Math.ceil((tokensNeeded / refillPerSec) * 1000);\n this.store.set(key, state);\n return {\n allowed: false,\n remaining: Math.floor(state.tokens),\n retryAfterMs,\n resetAt: now + retryAfterMs,\n };\n }\n\n /** Force-reset a key (e.g. after a successful auth flow). */\n reset(key: string): void {\n this.store.set(key, { tokens: this.config.capacity, lastRefill: this.now() });\n }\n}\n\n/**\n * Curated default buckets for the three traffic classes ObjectStack\n * dispatches. Conservative — tune via `DispatcherPluginConfig.rateLimit`\n * for your deployment.\n *\n * - auth: 10 req / minute / IP — guards /auth/* against credential\n * stuffing and password-spray.\n * - write: 60 req / minute / IP — POST/PUT/PATCH/DELETE.\n * - read: 600 req / minute / IP — GET, including discovery and\n * metadata.\n *\n * \"Per-IP\" is just the suggested key shape; the dispatcher constructs\n * the key from `${ip}:${bucket}` so a single noisy IP can saturate\n * one bucket without blocking the others.\n */\nexport interface RateLimitDefaults {\n auth: RateLimitBucketConfig;\n write: RateLimitBucketConfig;\n read: RateLimitBucketConfig;\n}\n\nexport const DEFAULT_RATE_LIMITS: RateLimitDefaults = {\n auth: { capacity: 10, refillPerSec: 10 / 60 },\n write: { capacity: 60, refillPerSec: 60 / 60 },\n read: { capacity: 600, refillPerSec: 600 / 60 },\n};\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Request correlation primitives.\n *\n * Two concerns:\n *\n * 1. **Request IDs.** Every request gets a stable id that is echoed back\n * via `X-Request-Id`, threaded into log records, and (where the host\n * asks for it) made available to handlers via `req.requestId`. The id\n * comes from the incoming `X-Request-Id` header when present and\n * well-formed, otherwise we mint a fresh one.\n *\n * 2. **W3C Trace Context.** When clients pass `traceparent` per\n * <https://www.w3.org/TR/trace-context/>, we surface the parsed\n * `traceId` / `spanId` / `sampled` triple so the host can attach it\n * to its OTel SDK / logger.\n *\n * Both helpers are pure functions — no I/O, no side effects, no\n * dependencies — so they are safe to call on the hot path and trivial to\n * test.\n */\n\nconst MAX_REQUEST_ID_LENGTH = 200;\n\n/**\n * Allowed characters in a request id: alphanumerics plus `-_.:`.\n * Rejects whitespace, control chars, anything that could interfere\n * with header serialization or log parsing.\n */\nconst REQUEST_ID_PATTERN = /^[A-Za-z0-9._:-]+$/;\n\n/**\n * Extract a request id from incoming headers, validating shape. If\n * the header is missing or malformed, returns `undefined` and the\n * caller should mint one via {@link generateRequestId}.\n *\n * Header lookup is case-insensitive — adapters normalize differently.\n */\nexport function extractRequestId(headers: unknown): string | undefined {\n if (!headers || typeof headers !== 'object') return undefined;\n for (const [k, v] of Object.entries(headers as Record<string, unknown>)) {\n if (k.toLowerCase() !== 'x-request-id') continue;\n const raw = Array.isArray(v) ? v[0] : v;\n if (typeof raw !== 'string') return undefined;\n const trimmed = raw.trim();\n if (!trimmed || trimmed.length > MAX_REQUEST_ID_LENGTH) return undefined;\n if (!REQUEST_ID_PATTERN.test(trimmed)) return undefined;\n return trimmed;\n }\n return undefined;\n}\n\n/**\n * Mint a fresh request id. Uses `crypto.randomUUID()` when available\n * (Node 16+, modern browsers, edge runtimes); falls back to a\n * timestamp+random suffix otherwise so the function is universally\n * callable.\n *\n * Format is `req_<hex>`; the prefix makes it obvious in logs that the\n * id was minted by this layer (vs. propagated from a client).\n */\nexport function generateRequestId(): string {\n const g: { randomUUID?: () => string } | undefined =\n (globalThis as unknown as { crypto?: { randomUUID?: () => string } }).crypto;\n if (g && typeof g.randomUUID === 'function') {\n return `req_${g.randomUUID().replace(/-/g, '')}`;\n }\n const t = Date.now().toString(36);\n const r = Math.random().toString(36).slice(2, 12);\n return `req_${t}${r}`;\n}\n\n/**\n * Return the incoming request id if valid, otherwise mint one.\n */\nexport function resolveRequestId(\n headers: unknown,\n generate: () => string = generateRequestId,\n): string {\n return extractRequestId(headers) ?? generate();\n}\n\n/**\n * Parsed W3C Trace Context. `sampled` reflects the lowest flag bit.\n */\nexport interface TraceContext {\n traceId: string;\n spanId: string;\n sampled: boolean;\n}\n\nconst TRACEPARENT_PATTERN = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;\n\n/**\n * Parse a `traceparent` header value into its W3C fields. Returns\n * `undefined` for malformed input, the all-zero trace/span ids\n * (spec-mandated invalid), or unknown versions.\n */\nexport function parseTraceparent(value: unknown): TraceContext | undefined {\n if (typeof value !== 'string') return undefined;\n const m = TRACEPARENT_PATTERN.exec(value.trim().toLowerCase());\n if (!m) return undefined;\n const [, version, traceId, spanId, flags] = m;\n if (version !== '00') return undefined;\n if (/^0+$/.test(traceId) || /^0+$/.test(spanId)) return undefined;\n const sampled = (parseInt(flags, 16) & 0x01) === 0x01;\n return { traceId, spanId, sampled };\n}\n\n/**\n * Build the response header equivalent so downstream services\n * continue the trace.\n */\nexport function formatTraceparent(ctx: TraceContext): string {\n const flag = ctx.sampled ? '01' : '00';\n return `00-${ctx.traceId}-${ctx.spanId}-${flag}`;\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Backwards-compat shim. The canonical home for `MetricsRegistry`,\n * `NoopMetricsRegistry`, `InMemoryMetricsRegistry`, `MetricSample`, and\n * the `RUNTIME_METRICS` constants moved to `@objectstack/observability`\n * so deployment-target-neutral code (cloud, self-hosted, ...) can\n * import them without pulling in the whole runtime.\n *\n * Existing imports from `@objectstack/runtime`-internal paths continue\n * to work transparently via this re-export.\n */\nexport {\n NoopMetricsRegistry,\n InMemoryMetricsRegistry,\n RUNTIME_METRICS,\n type MetricsRegistry,\n type MetricSample,\n} from '@objectstack/observability';\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Backwards-compat shim. See `metrics.ts` for the rationale — the\n * canonical home is `@objectstack/observability`.\n */\nexport {\n NoopErrorReporter,\n InMemoryErrorReporter,\n type ErrorReporter,\n type CapturedError,\n} from '@objectstack/observability';\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport {\n NoopMetricsRegistry,\n NoopErrorReporter,\n resolveRequestId,\n RUNTIME_METRICS,\n type MetricsRegistry,\n type ErrorReporter,\n} from './index.js';\n\n/**\n * Options for {@link instrumentRouteHandler}. All fields optional; the\n * defaults make the wrapper a no-op (zero overhead, no behavior change).\n *\n * Hosts plug their own implementations to bridge to Prometheus / OTel /\n * Sentry / Datadog without the framework taking a hard dependency on\n * any of them.\n */\nexport interface InstrumentOptions {\n metrics?: MetricsRegistry;\n errorReporter?: ErrorReporter;\n /** Override the default `req_<uuid>` generator. */\n generateRequestId?: () => string;\n /** Response header that echoes the request id (default `X-Request-Id`). */\n requestIdHeader?: string;\n /**\n * Wall clock for tests. Defaults to `Date.now`; only `now()` is\n * called, so any monotonic source works.\n */\n now?: () => number;\n}\n\n/**\n * Wrap an HTTP route handler with the runtime's standard observability\n * lifecycle:\n *\n * 1. Resolve a request id from incoming `X-Request-Id` (or mint one).\n * 2. Set the request id on `req.requestId` and response header.\n * 3. Time the handler.\n * 4. Emit `http_requests_total{method,route,status}` counter and\n * `http_request_duration_ms{method,route}` histogram.\n * 5. On thrown errors, emit `http_request_errors_total` and call\n * `errorReporter.captureException` for 5xx.\n * 6. When the handler catches its own error and calls\n * `errorResponseBase` (which leaves a side-channel\n * `res.__obsRecordedError`), still call the error reporter.\n *\n * The wrapper does not catch the error — it re-throws so the host\n * server still gets a chance to render its own 500 page if needed.\n */\nexport function instrumentRouteHandler(\n method: string,\n route: string,\n handler: (req: any, res: any) => unknown,\n opts: InstrumentOptions = {},\n): (req: any, res: any) => Promise<void> {\n const metrics = opts.metrics ?? new NoopMetricsRegistry();\n const errorReporter = opts.errorReporter ?? new NoopErrorReporter();\n const generateRequestId = opts.generateRequestId;\n const requestIdHeader = opts.requestIdHeader ?? 'X-Request-Id';\n const now = opts.now ?? Date.now;\n\n return async (req: any, res: any) => {\n const requestId = resolveRequestId(req?.headers, generateRequestId);\n try {\n (req as any).requestId = requestId;\n } catch {\n // frozen req object — fine, the header is the source of truth\n }\n if (typeof res?.header === 'function') {\n try {\n res.header(requestIdHeader, requestId);\n } catch {\n // adapter rejects header injection here — fine\n }\n }\n\n // Capture the final status. We start at 200 (the adapter default\n // when no status() is called) and override on status() calls via\n // a tiny proxy.\n let status = 200;\n const origStatus =\n typeof res?.status === 'function' ? res.status.bind(res) : undefined;\n if (origStatus) {\n res.status = (code: number) => {\n status = code;\n return origStatus(code);\n };\n }\n\n const startedAt = now();\n let threw = false;\n try {\n await handler(req, res);\n } catch (err: any) {\n threw = true;\n status = err?.statusCode ?? 500;\n metrics.counter(RUNTIME_METRICS.httpRequestErrorsTotal, { method, route });\n if (status >= 500) {\n safeReport(errorReporter, err, { requestId, method, route });\n }\n throw err;\n } finally {\n const elapsed = now() - startedAt;\n metrics.counter(RUNTIME_METRICS.httpRequestsTotal, {\n method,\n route,\n status: String(status),\n });\n metrics.histogram(\n RUNTIME_METRICS.httpRequestDurationMs,\n elapsed,\n { method, route },\n );\n // Side-channel: handler caught the error and called\n // errorResponseBase, which recorded the original error on\n // `res.__obsRecordedError`. Pick it up so 5xx still\n // reaches the reporter even though we did not see the throw.\n if (!threw && status >= 500) {\n const recorded = (res as any)?.__obsRecordedError;\n if (recorded !== undefined) {\n safeReport(errorReporter, recorded, { requestId, method, route });\n }\n }\n }\n };\n}\n\nfunction safeReport(\n reporter: ErrorReporter,\n err: unknown,\n ctx: Record<string, unknown>,\n): void {\n try {\n reporter.captureException(err, ctx);\n } catch {\n // never let reporter failures mask the original error\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Plugin, PluginContext } from '@objectstack/core';\nimport {\n OBSERVABILITY_METRICS_SERVICE,\n OBSERVABILITY_ERRORS_SERVICE,\n} from '@objectstack/observability';\nimport {\n NoopMetricsRegistry,\n NoopErrorReporter,\n type MetricsRegistry,\n type ErrorReporter,\n} from './index.js';\n\n/**\n * Canonical service names other plugins look up to find the host's\n * configured observability backends. Re-exported from\n * `@objectstack/observability` so callers can grab them alongside the\n * plugin without straddling two packages.\n */\nexport { OBSERVABILITY_METRICS_SERVICE, OBSERVABILITY_ERRORS_SERVICE };\n\n/**\n * Options for {@link ObservabilityServicePlugin}.\n *\n * Either or both backends can be omitted; the omitted one resolves to\n * the corresponding no-op exporter so consumers can always rely on the\n * service being present.\n */\nexport interface ObservabilityServicePluginOptions {\n /** Metrics backend (e.g. `ConsoleMetricsRegistry`, `OtlpHttpMetricsRegistry`). */\n metrics?: MetricsRegistry;\n /** Error reporter backend (e.g. Sentry adapter). */\n errors?: ErrorReporter;\n}\n\n/**\n * `ObservabilityServicePlugin` — registers the host's\n * {@link MetricsRegistry} and {@link ErrorReporter} in the kernel\n * service registry under the canonical names so any other plugin can\n * look them up without each host having to thread observability config\n * through every plugin constructor.\n *\n * Resolution chain other plugins should follow:\n *\n * 1. Explicit option on the plugin's own options object (escape\n * hatch for tests / explicit wiring).\n * 2. `ctx.getService(OBSERVABILITY_METRICS_SERVICE)`.\n * 3. `NoopMetricsRegistry()` — never null.\n *\n * Register this plugin **before** any plugin that wants to consume the\n * services (cache, storage, dispatcher), otherwise the consumer's\n * `init` will fall through to the no-op default.\n *\n * @example\n * ```ts\n * import { ObjectKernel } from '@objectstack/core';\n * import {\n * ObservabilityServicePlugin,\n * CacheServicePlugin,\n * } from '@objectstack/runtime';\n * import { ConsoleMetricsRegistry } from '@objectstack/observability';\n *\n * const kernel = new ObjectKernel();\n * kernel.use(new ObservabilityServicePlugin({\n * metrics: new ConsoleMetricsRegistry(),\n * }));\n * kernel.use(new CacheServicePlugin()); // picks metrics up automatically\n * ```\n */\nexport class ObservabilityServicePlugin implements Plugin {\n name = 'com.objectstack.observability.service';\n version = '1.0.0';\n type = 'standard';\n\n private readonly options: ObservabilityServicePluginOptions;\n\n constructor(options: ObservabilityServicePluginOptions = {}) {\n this.options = options;\n }\n\n async init(ctx: PluginContext): Promise<void> {\n const metrics = this.options.metrics ?? new NoopMetricsRegistry();\n const errors = this.options.errors ?? new NoopErrorReporter();\n ctx.registerService(OBSERVABILITY_METRICS_SERVICE, metrics);\n ctx.registerService(OBSERVABILITY_ERRORS_SERVICE, errors);\n ctx.logger.info(\n `ObservabilityServicePlugin: registered metrics=${(metrics as any).constructor?.name ?? 'unknown'} errors=${(errors as any).constructor?.name ?? 'unknown'}`,\n );\n }\n}\n\n/**\n * Helper used by consumer plugins to resolve a metrics backend with\n * the canonical fallback chain. Never throws; always returns a usable\n * `MetricsRegistry`.\n *\n * @param ctx the consuming plugin's `PluginContext`\n * @param override explicit option set on the consuming plugin (wins)\n */\nexport function resolveMetrics(\n ctx: PluginContext,\n override?: MetricsRegistry,\n): MetricsRegistry {\n if (override) return override;\n try {\n const m = ctx.getService<MetricsRegistry | undefined>(OBSERVABILITY_METRICS_SERVICE);\n if (m) return m;\n } catch {\n // Service not registered — fall through to the noop default.\n }\n return new NoopMetricsRegistry();\n}\n\n/**\n * Sibling of {@link resolveMetrics} for {@link ErrorReporter}.\n */\nexport function resolveErrorReporter(\n ctx: PluginContext,\n override?: ErrorReporter,\n): ErrorReporter {\n if (override) return override;\n try {\n const e = ctx.getService<ErrorReporter | undefined>(OBSERVABILITY_ERRORS_SERVICE);\n if (e) return e;\n } catch {\n // Service not registered — fall through to the noop default.\n }\n return new NoopErrorReporter();\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { Plugin, PluginContext, IHttpServer } from '@objectstack/core';\nimport { HttpDispatcher, HttpDispatcherResult } from './http-dispatcher.js';\nimport {\n buildSecurityHeaders,\n type SecurityHeadersOptions,\n} from './security/index.js';\nimport {\n NoopMetricsRegistry,\n NoopErrorReporter,\n instrumentRouteHandler,\n type MetricsRegistry,\n type ErrorReporter,\n} from './observability/index.js';\n\nexport interface DispatcherPluginConfig {\n /**\n * API path prefix for all endpoints.\n * @default '/api/v1'\n */\n prefix?: string;\n\n /**\n * Project-scoping configuration. Must match the REST API\n * `enableProjectScoping` / `projectResolution` fields so AI / automation\n * routes stay in lockstep with /data and /meta.\n *\n * When `enableProjectScoping` is true and `projectResolution` is:\n * - `required` — only `/environments/:environmentId/...` variants are registered.\n * - `optional` / `auto` — both unscoped and scoped variants are registered\n * (the scoped handler forwards `req.params.environmentId` into context).\n */\n scoping?: {\n enableProjectScoping?: boolean;\n projectResolution?: 'required' | 'optional' | 'auto';\n };\n\n /**\n * Enforce per-project membership (`sys_environment_member`) on scoped\n * data-plane routes. Returns 403 for non-members unless they are\n * staff (platform org) or the project is the well-known system\n * project.\n *\n * Defaults to `true` when `scoping.enableProjectScoping` is enabled;\n * explicitly set to `false` for tests and single-tenant deployments\n * where membership has not been seeded.\n */\n enforceProjectMembership?: boolean;\n\n /**\n * Security response headers. When provided, every response routed\n * through this plugin gets the headers merged in (route-specific\n * headers still win on conflict).\n *\n * Pass `false` to disable. Pass `true` (or omit) to enable with\n * conservative API-server defaults (CSP=deny-all, XCTO=nosniff,\n * X-Frame-Options=DENY, etc.). Pass an object to customize — see\n * {@link SecurityHeadersOptions}.\n *\n * @default true\n */\n securityHeaders?: boolean | SecurityHeadersOptions;\n\n /**\n * Observability wiring. All fields optional; defaults are noop\n * (zero overhead, no behavior change).\n *\n * - `metrics`: registry receiving `http_requests_total`,\n * `http_request_duration_ms`, `http_request_errors_total` for\n * every route this plugin mounts. Plug in `prom-client` /\n * `@opentelemetry/api-metrics` / your own adapter.\n *\n * - `errorReporter`: invoked on 5xx responses with the thrown\n * error and `{ requestId, method, route }`. Plug in Sentry /\n * Datadog / Rollbar.\n *\n * - `generateRequestId`: customize the format of minted request\n * ids (default: `req_<uuid>` via `crypto.randomUUID`). The\n * incoming `X-Request-Id` header is honored when present and\n * well-formed, regardless of this setting.\n *\n * - `requestIdHeader`: response header name to echo the id back\n * on. Defaults to `X-Request-Id`.\n */\n observability?: {\n metrics?: MetricsRegistry;\n errorReporter?: ErrorReporter;\n generateRequestId?: () => string;\n requestIdHeader?: string;\n };\n}\n\n/**\n * Route definition emitted by service plugins (e.g. AIServicePlugin) via hooks.\n * Minimal interface — matches the shape produced by `buildAIRoutes()`.\n */\ninterface RouteDefinition {\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE';\n path: string;\n description: string;\n handler: (req: any) => Promise<any>;\n}\n\n/**\n * Register a single RouteDefinition on the HTTP server.\n * Returns true if the route was successfully registered.\n */\nfunction mountRouteOnServer(\n route: RouteDefinition,\n server: IHttpServer,\n routePath: string,\n securityHeaders?: Record<string, string>,\n resolveUser?: (headers: Record<string, any>) => Promise<any | undefined>,\n): boolean {\n const handler = async (req: any, res: any) => {\n try {\n // Resolve the authenticated user from request headers (cookie /\n // bearer) so route handlers can attribute the request to an\n // actor — wires up `req.user` for AI routes, action endpoints,\n // anything that needs identity-aware execution.\n let user: any;\n if (resolveUser) {\n try {\n user = await resolveUser(req.headers ?? {});\n } catch {\n /* fall through anonymous — route's `auth: true` guard runs separately */\n }\n }\n\n const result = await route.handler({\n body: req.body,\n params: req.params,\n query: req.query,\n headers: req.headers,\n user,\n });\n\n if (result.stream && result.events) {\n // SSE streaming response\n res.status(result.status);\n\n if (securityHeaders) {\n for (const [k, v] of Object.entries(securityHeaders)) {\n res.header(k, v);\n }\n }\n\n // Apply headers from the route result if available\n if (result.headers) {\n for (const [k, v] of Object.entries(result.headers)) {\n res.header(k, String(v));\n }\n } else {\n res.header('Content-Type', 'text/event-stream');\n res.header('Cache-Control', 'no-cache');\n res.header('Connection', 'keep-alive');\n }\n\n // Write the stream — events are pre-encoded SSE strings\n if (typeof res.write === 'function' && typeof res.end === 'function') {\n for await (const event of result.events) {\n res.write(typeof event === 'string' ? event : `data: ${JSON.stringify(event)}\\n\\n`);\n }\n res.end();\n } else {\n // Fallback: collect events into array\n const events = [];\n for await (const event of result.events) {\n events.push(event);\n }\n res.json({ events });\n }\n } else {\n res.status(result.status);\n if (securityHeaders) {\n for (const [k, v] of Object.entries(securityHeaders)) {\n res.header(k, v);\n }\n }\n if (result.body !== undefined) {\n res.json(result.body);\n } else {\n res.end();\n }\n }\n } catch (err: any) {\n errorResponseBase(err, res, securityHeaders);\n }\n };\n\n const m = route.method.toLowerCase();\n if (m === 'get' && typeof server.get === 'function') {\n server.get(routePath, handler);\n return true;\n } else if (m === 'post' && typeof server.post === 'function') {\n server.post(routePath, handler);\n return true;\n } else if (m === 'delete' && typeof server.delete === 'function') {\n server.delete(routePath, handler);\n return true;\n } else if (m === 'patch' && typeof server.patch === 'function') {\n server.patch(routePath, handler);\n return true;\n }\n return false;\n}\n\n/**\n * Send an HttpDispatcherResult through IHttpResponse.\n * Differentiates between handled, unhandled (404), and special results.\n *\n * @param securityHeaders headers to merge into every response (under\n * the route-specific headers so the dispatcher can override on a\n * per-route basis when truly needed).\n */\nfunction sendResultBase(\n result: HttpDispatcherResult,\n res: any,\n securityHeaders?: Record<string, string>,\n): void {\n const applySecurityHeaders = () => {\n if (!securityHeaders) return;\n for (const [k, v] of Object.entries(securityHeaders)) {\n // Don't clobber route-set headers — `res.header` semantics\n // vary by adapter, so we set unconditionally and rely on the\n // call ordering (security headers first, route headers\n // overwrite below).\n res.header(k, v);\n }\n };\n\n if (result.handled) {\n if (result.response) {\n res.status(result.response.status);\n applySecurityHeaders();\n if (result.response.headers) {\n for (const [k, v] of Object.entries(result.response.headers)) {\n res.header(k, v);\n }\n }\n res.json(result.response.body);\n return;\n }\n if (result.result) {\n // Special results from the dispatcher's `result.result` channel.\n // Currently the only shape we handle here is the SSE/streaming\n // descriptor returned by AI routes:\n // { status, stream: true, events: AsyncIterable<string>,\n // headers?: Record<string, string>, contentType?: string }\n // Anything else falls through to JSON so older callers keep\n // working.\n const r = result.result as any;\n const isStream = r && typeof r === 'object' && (r.type === 'stream' || r.stream === true) && r.events;\n if (isStream && typeof res.write === 'function' && typeof res.end === 'function') {\n res.status(typeof r.status === 'number' ? r.status : 200);\n applySecurityHeaders();\n if (r.headers && typeof r.headers === 'object') {\n for (const [k, v] of Object.entries(r.headers)) {\n res.header(k, String(v));\n }\n } else {\n res.header('Content-Type', r.contentType || 'text/event-stream');\n res.header('Cache-Control', 'no-cache');\n res.header('Connection', 'keep-alive');\n }\n // Flip the adapter's `isStreaming` flag synchronously so the\n // outer handler can return before the AsyncIterable is fully\n // drained. Without this empty write, the Hono adapter would\n // see no streaming activity by the time the route handler\n // resolves and would close the body, truncating the SSE.\n res.write('');\n // Drain the events in the background; the adapter's\n // ReadableStream stays open until res.end() fires.\n (async () => {\n try {\n for await (const event of r.events as AsyncIterable<unknown>) {\n if (event == null) continue;\n res.write(typeof event === 'string' ? event : `data: ${JSON.stringify(event)}\\n\\n`);\n }\n } catch (streamErr) {\n try {\n res.write(`event: error\\ndata: ${JSON.stringify({ message: streamErr instanceof Error ? streamErr.message : String(streamErr) })}\\n\\n`);\n } catch { /* connection already gone */ }\n } finally {\n try { res.end(); } catch { /* idem */ }\n }\n })();\n return;\n }\n res.status(200);\n applySecurityHeaders();\n res.json(result.result);\n return;\n }\n }\n // Semantic 404: no route matched — include diagnostic info\n res.status(404);\n applySecurityHeaders();\n res.json({\n success: false,\n error: {\n message: 'Not Found',\n code: 404,\n type: 'ROUTE_NOT_FOUND',\n hint: 'No handler matched this request. Check the API discovery endpoint for available routes.',\n },\n });\n}\n\nfunction errorResponseBase(err: any, res: any, securityHeaders?: Record<string, string>): void {\n const code = err.statusCode || 500;\n res.status(code);\n if (securityHeaders) {\n for (const [k, v] of Object.entries(securityHeaders)) {\n res.header(k, v);\n }\n }\n // Side-channel: remember the original error so the observability\n // wrapper can hand it to errorReporter on 5xx. Handlers catch the\n // error and call us here instead of re-throwing, so this is the\n // only place we still have it.\n if (code >= 500) {\n try {\n (res as any).__obsRecordedError = err;\n } catch {\n // res is a frozen / proxy object — skip\n }\n }\n res.json({\n success: false,\n error: { message: err.message || 'Internal Server Error', code },\n });\n}\n\n/**\n * Dispatcher Plugin\n *\n * Bridges legacy HttpDispatcher handlers to the IHttpServer route-registration model.\n * Registers routes for domains NOT covered by @objectstack/rest:\n * - /.well-known/objectstack (discovery)\n * - /auth (authentication)\n * - /graphql (GraphQL)\n * - /analytics (BI queries)\n * - /packages (package management)\n * - /i18n (internationalization — locales, translations, field labels)\n * - /storage (file storage)\n * - /automation (CRUD + triggers + runs)\n *\n * Usage:\n * ```ts\n * import { createDispatcherPlugin } from '@objectstack/runtime';\n * runtime.use(createDispatcherPlugin({ prefix: '/api/v1' }));\n * ```\n */\nexport function createDispatcherPlugin(config: DispatcherPluginConfig = {}): Plugin {\n return {\n name: 'com.objectstack.runtime.dispatcher',\n version: '1.0.0',\n\n init: async (_ctx: PluginContext) => {\n // Consumer-only plugin — no services registered\n },\n\n start: async (ctx: PluginContext) => {\n let server: IHttpServer | undefined;\n try {\n server = ctx.getService<IHttpServer>('http.server');\n } catch {\n // No HTTP server available — skip silently\n return;\n }\n if (!server) return;\n\n const kernel = ctx.getKernel();\n // Default: enable membership enforcement iff environment-scoping is on.\n // Tests / single-tenant deploys can opt out via the explicit flag.\n const enforceMembership =\n config.enforceProjectMembership ?? (config.scoping?.enableProjectScoping ?? false);\n const dispatcher = new HttpDispatcher(kernel, undefined, {\n enforceProjectMembership: enforceMembership,\n });\n const prefix = config.prefix || '/api/v1';\n\n // ── Security: resolve once at startup; applied on every response.\n // Defaults to ON because every production API server should be\n // sending these headers. Opt out with `securityHeaders: false`\n // (only sensible for tests or when an upstream reverse proxy is\n // already setting them).\n const securityHeaders: Record<string, string> | undefined =\n config.securityHeaders === false\n ? undefined\n : buildSecurityHeaders(\n typeof config.securityHeaders === 'object'\n ? config.securityHeaders\n : {},\n );\n\n // Locally-shadowed wrappers — every `sendResult(...)` /\n // `errorResponse(...)` call below picks these up via lexical\n // scope, so the 50+ route handlers don't need to thread the\n // security headers through manually.\n const sendResult = (result: HttpDispatcherResult, res: any) =>\n sendResultBase(result, res, securityHeaders);\n const errorResponse = (err: any, res: any) =>\n errorResponseBase(err, res, securityHeaders);\n\n // ── Observability ──────────────────────────────────────────\n // Noop defaults; production hosts inject real adapters.\n const metrics: MetricsRegistry =\n config.observability?.metrics ?? new NoopMetricsRegistry();\n const errorReporter: ErrorReporter =\n config.observability?.errorReporter ?? new NoopErrorReporter();\n const generateRequestId = config.observability?.generateRequestId;\n const requestIdHeader =\n config.observability?.requestIdHeader ?? 'X-Request-Id';\n\n /**\n * Wrap the IHttpServer so every route registration is\n * automatically instrumented. We only override the three\n * verb methods the dispatcher uses; everything else passes\n * through unchanged.\n */\n const rawServer = server;\n server = new Proxy(rawServer, {\n get(target, prop, receiver) {\n if (prop === 'get' || prop === 'post' || prop === 'delete') {\n const method = String(prop).toUpperCase();\n const original = (target as any)[prop];\n if (typeof original !== 'function') return original;\n return (route: string, handler: any) => {\n return original.call(\n target,\n route,\n instrumentRouteHandler(method, route, handler, {\n metrics,\n errorReporter,\n generateRequestId,\n requestIdHeader,\n }),\n );\n };\n }\n return Reflect.get(target, prop, receiver);\n },\n }) as IHttpServer;\n\n // ── Discovery (.well-known) ─────────────────────────────────\n server.get('/.well-known/objectstack', async (_req: any, res: any) => {\n if (securityHeaders) {\n for (const [k, v] of Object.entries(securityHeaders)) {\n res.header(k, v);\n }\n }\n res.json({ data: await dispatcher.getDiscoveryInfo(prefix) });\n });\n\n // ── Discovery (versioned API path) ──────────────────────────\n server.get(`${prefix}/discovery`, async (_req: any, res: any) => {\n if (securityHeaders) {\n for (const [k, v] of Object.entries(securityHeaders)) {\n res.header(k, v);\n }\n }\n res.json({ data: await dispatcher.getDiscoveryInfo(prefix) });\n });\n\n // ── Health ──────────────────────────────────────────────────\n server.get(`${prefix}/health`, async (_req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', '/health', undefined, {}, { request: _req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ── Auth ────────────────────────────────────────────────────\n // NOTE: /auth/* wildcard is mounted by AuthProxyPlugin (cloud)\n // or AuthPlugin (single-tenant) directly on the raw Hono app —\n // those handlers can return native Web `Response` objects which\n // is what better-auth produces. The dispatcher cannot represent\n // a streaming Response cleanly through `IHttpServer.send`, so\n // we deliberately do NOT register a dispatcher wildcard here.\n //\n // Legacy explicit /auth/login retained for self-hosted clients\n // that still POST there; superseded by the wildcard above for\n // the better-auth surface (sign-up/email, sign-in/email, …).\n server.post(`${prefix}/auth/login`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handleAuth('login', 'POST', req.body, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ── GraphQL ─────────────────────────────────────────────────\n server.post(`${prefix}/graphql`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handleGraphQL(req.body, { request: req });\n if (securityHeaders) {\n for (const [k, v] of Object.entries(securityHeaders)) {\n res.header(k, v);\n }\n }\n res.json(result);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ── Analytics ───────────────────────────────────────────────\n // Route via dispatch() (not handleAnalytics directly) so the host\n // dispatcher's project-aware kernel swap runs first — the per-project\n // kernel owns the `analytics` service (registered by ObjectQLPlugin).\n server.post(`${prefix}/analytics/query`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', '/analytics/query', req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.get(`${prefix}/analytics/meta`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', '/analytics/meta', undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.post(`${prefix}/analytics/sql`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', '/analytics/sql', req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ── Packages ────────────────────────────────────────────────\n server.get(`${prefix}/packages`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages('', 'GET', {}, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.post(`${prefix}/packages`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages('', 'POST', req.body, {}, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.get(`${prefix}/packages/:id/export`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}/export`, 'GET', {}, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.get(`${prefix}/packages/:id`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}`, 'GET', {}, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.delete(`${prefix}/packages/:id`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}`, 'DELETE', {}, {}, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.patch(`${prefix}/packages/:id/enable`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}/enable`, 'PATCH', {}, {}, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.patch(`${prefix}/packages/:id/disable`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}/disable`, 'PATCH', {}, {}, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.post(`${prefix}/packages/:id/publish`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}/publish`, 'POST', req.body, {}, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.post(`${prefix}/packages/:id/revert`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}/revert`, 'POST', req.body, {}, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ── Storage ─────────────────────────────────────────────────\n server.post(`${prefix}/storage/upload`, async (req: any, res: any) => {\n try {\n // For file uploads the body *is* the file (parsed by adapter)\n const result = await dispatcher.handleStorage('upload', 'POST', req.body, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.get(`${prefix}/storage/file/:id`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handleStorage(`file/${req.params.id}`, 'GET', undefined, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ── i18n ────────────────────────────────────────────────────\n // Route via dispatch() (not handleI18n directly) so the host\n // dispatcher's project-aware kernel swap runs first. Without this,\n // i18n requests hit the host kernel's in-memory fallback (which\n // is always empty) instead of the per-project I18nServicePlugin\n // populated by ArtifactKernelFactory with the artifact's\n // translation bundles.\n server.get(`${prefix}/i18n/locales`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', '/i18n/locales', undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.get(`${prefix}/i18n/translations/:locale`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', `/i18n/translations/${req.params.locale}`, undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.get(`${prefix}/i18n/labels/:object/:locale`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', `/i18n/labels/${req.params.object}/${req.params.locale}`, undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ── Automation ──────────────────────────────────────────────\n // Registered at both `${prefix}/automation/...` and\n // `${prefix}/environments/:environmentId/automation/...` when project\n // scoping is enabled. Always dispatched through\n // `dispatcher.dispatch()` so the multi-kernel host can swap\n // to the per-project kernel before resolving the\n // `automation` service (which lives on the project kernel,\n // not the host kernel, in ObjectOS multi-tenant mode).\n const registerAutomationRoutes = (base: string) => {\n server!.get(`${base}/automation`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', '/automation', undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.post(`${base}/automation`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', '/automation', req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.get(`${base}/automation/:name`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', `/automation/${req.params.name}`, undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.put(`${base}/automation/:name`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('PUT', `/automation/${req.params.name}`, req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.delete(`${base}/automation/:name`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('DELETE', `/automation/${req.params.name}`, undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.post(`${base}/automation/trigger/:name`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', `/automation/trigger/${req.params.name}`, req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.post(`${base}/automation/:name/trigger`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', `/automation/${req.params.name}/trigger`, req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.post(`${base}/automation/:name/toggle`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', `/automation/${req.params.name}/toggle`, req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.get(`${base}/automation/:name/runs`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', `/automation/${req.params.name}/runs`, undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.get(`${base}/automation/:name/runs/:runId`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', `/automation/${req.params.name}/runs/${req.params.runId}`, undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // Screen-flow runtime (ADR-0019): resume a paused run with a\n // screen node's collected input, and re-fetch its pending screen.\n server!.post(`${base}/automation/:name/runs/:runId/resume`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', `/automation/${req.params.name}/runs/${req.params.runId}/resume`, req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.get(`${base}/automation/:name/runs/:runId/screen`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', `/automation/${req.params.name}/runs/${req.params.runId}/screen`, undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n };\n\n // ── AI / Assistants ─────────────────────────────────────────\n // The AI service plugin registers a large, dynamic surface\n // (chat, models, conversations, tools, agents, assistants)\n // whose exact routes are built at start() time from the\n // service's tool / agent registries. To support multi-tenant\n // hosts where the AI service lives on per-project kernels,\n // mount a method-wildcard catch-all that always dispatches\n // through `dispatcher.dispatch()` — that triggers the kernel\n // swap and then routes via `handleAI`, which looks up the\n // AI service on the current (project) kernel.\n const registerAIRoutes = (base: string) => {\n const wildcards: Array<['get'|'post'|'delete'|'put', string]> = [\n ['get', `${base}/ai/*`],\n ['post', `${base}/ai/*`],\n ['delete', `${base}/ai/*`],\n ['put', `${base}/ai/*`],\n ];\n for (const [method, pattern] of wildcards) {\n (server as any) => {\n try {\n // Reconstruct the AI subpath without the prefix\n // so dispatch() routes via the /ai branch.\n const fullPath: string = req.path ?? '';\n const idx = fullPath.lastIndexOf('/ai');\n const aiSubPath = idx >= 0 ? fullPath.slice(idx) : '/ai';\n const result = await dispatcher.dispatch(method.toUpperCase(), aiSubPath, req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n }\n };\n\n // ── Actions (server-registered handlers, e.g. CRM convertLead) ───\n // Bridges UI `script` / `modal` actions to ObjectQL handlers\n // registered via `engine.registerAction(object, action, fn)`.\n const registerActionRoutes = (base: string) => {\n server!.post(`${base}/actions/:object/:action`, async (req: any, res: any) => {\n try {\n const ctx: any = { request: req };\n if (req.params?.environmentId) ctx.environmentId = req.params.environmentId;\n const result = await dispatcher.handleActions(`/${req.params.object}/${req.params.action}`, 'POST', req.body, ctx);\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n server!.post(`${base}/actions/:object/:action/:recordId`, async (req: any, res: any) => {\n try {\n const ctx: any = { request: req };\n if (req.params?.environmentId) ctx.environmentId = req.params.environmentId;\n const result = await dispatcher.handleActions(`/${req.params.object}/${req.params.action}/${req.params.recordId}`, 'POST', req.body, ctx);\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n };\n\n const enableProjectScoping = config.scoping?.enableProjectScoping ?? false;\n const projectResolution = config.scoping?.projectResolution ?? 'auto';\n\n if (enableProjectScoping && projectResolution === 'required') {\n registerAutomationRoutes(`${prefix}/environments/:environmentId`);\n registerActionRoutes(`${prefix}/environments/:environmentId`);\n registerAIRoutes(`${prefix}/environments/:environmentId`);\n } else {\n registerAutomationRoutes(prefix);\n registerActionRoutes(prefix);\n registerAIRoutes(prefix);\n if (enableProjectScoping) {\n registerAutomationRoutes(`${prefix}/environments/:environmentId`);\n registerActionRoutes(`${prefix}/environments/:environmentId`);\n registerAIRoutes(`${prefix}/environments/:environmentId`);\n }\n }\n\n ctx.logger.info('Dispatcher bridge routes registered', { prefix, enableProjectScoping, projectResolution });\n\n // Resolve the authenticated user from a request's headers by\n // delegating to the AuthService's `getSession` API (better-auth\n // compatible). Returns a slim user shape that route handlers\n // can rely on without touching the underlying auth provider.\n //\n // Defensive: any failure → undefined (anonymous). The route's\n // `auth: true` guard still runs separately so unauthenticated\n // hits to protected routes are rejected upstream.\n const resolveRequestUser = async (headers: Record<string, any>): Promise<any | undefined> => {\n try {\n const authService: any = ctx.getService('auth');\n if (!authService) return undefined;\n let api: any = authService.api;\n if (!api && typeof authService.getApi === 'function') {\n api = await authService.getApi();\n }\n if (!api?.getSession) return undefined;\n const headersInstance = headers instanceof Headers\n ? headers\n : new Headers(headers as Record<string, string>);\n const sessionData = await api.getSession({ headers: headersInstance });\n const userId: string | undefined = sessionData?.user?.id ?? sessionData?.session?.userId;\n if (!userId) return undefined;\n return {\n userId,\n id: userId,\n displayName: sessionData?.user?.name ?? sessionData?.user?.email ?? userId,\n email: sessionData?.user?.email,\n roles: [],\n permissions: [],\n organizationId: sessionData?.session?.activeOrganizationId,\n };\n } catch {\n return undefined;\n }\n };\n\n // ── Dynamic service routes (AI, etc.) ───────────────────\n // Listen for route definitions emitted by service plugins.\n // The AIServicePlugin emits 'ai:routes' with RouteDefinition[].\n //\n // When environment-scoping is enabled, each AI route is mounted on\n // BOTH `${prefix}${path}` and `${prefix}/environments/:environmentId${path}`\n // (or only the scoped variant when `projectResolution === 'required'`).\n const toScopedPath = (routePath: string): string => {\n // routePath may already include /api/v1; splice /environments/:environmentId\n // after the `${prefix}` portion to produce the scoped variant.\n if (routePath.startsWith(prefix)) {\n const tail = routePath.slice(prefix.length);\n return `${prefix}/environments/:environmentId${tail}`;\n }\n return `/environments/:environmentId${routePath}`;\n };\n\n const mountAiRoute = (route: RouteDefinition) => {\n if (!server) return 0;\n const routePath = route.path.startsWith('/api/v1')\n ? route.path\n : `${prefix}${route.path}`;\n\n let count = 0;\n if (enableProjectScoping && projectResolution === 'required') {\n if (mountRouteOnServer(route, server, toScopedPath(routePath), securityHeaders, resolveRequestUser)) count++;\n } else {\n if (mountRouteOnServer(route, server, routePath, securityHeaders, resolveRequestUser)) count++;\n if (enableProjectScoping) {\n if (mountRouteOnServer(route, server, toScopedPath(routePath), securityHeaders, resolveRequestUser)) count++;\n }\n }\n return count;\n };\n\n ctx.hook('ai:routes', async (routes: RouteDefinition[]) => {\n if (!server) return;\n let total = 0;\n for (const route of routes) {\n total += mountAiRoute(route);\n }\n ctx.logger.info(`[Dispatcher] Registered ${total} AI route mount(s) from ${routes.length} definition(s)`);\n });\n\n // ── Fallback: recover routes cached before hook was registered ──\n // If AIServicePlugin.start() ran before DispatcherPlugin.start()\n // (possible when plugin start order differs from registration order),\n // the 'ai:routes' trigger fires with no listener. The AIServicePlugin\n // caches the routes on the kernel as __aiRoutes (see AIServicePlugin.start())\n // as an internal cross-plugin protocol so we can recover them here.\n // TODO: replace with a formal kernel.getCachedRoutes('ai') API in a future release.\n const cachedRoutes = (kernel as any).__aiRoutes as RouteDefinition[] | undefined;\n if (cachedRoutes && Array.isArray(cachedRoutes) && cachedRoutes.length > 0) {\n let registered = 0;\n for (const route of cachedRoutes) {\n registered += mountAiRoute(route);\n }\n if (registered > 0) {\n ctx.logger.info(`[Dispatcher] Recovered ${registered} cached AI route mount(s) (hook timing fallback)`);\n }\n }\n },\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { Plugin, PluginContext } from '@objectstack/core';\n\n/**\n * The well-known UUID for the built-in system project.\n * Kept in lockstep with `ProjectProvisioningService.provisionSystemEnvironment`.\n */\nexport const SYSTEM_ENVIRONMENT_ID = '00000000-0000-0000-0000-000000000001';\n\n/**\n * Minimal surface of `ProjectProvisioningService` consumed by the plugin.\n * Typed locally so the runtime package does not gain a hard dependency on\n * `@objectstack/service-tenant` — the service is discovered at runtime via\n * the kernel service registry.\n */\ninterface ProvisioningLike {\n provisionSystemEnvironment(): Promise<{\n project: { id: string; isSystem?: boolean };\n warnings?: string[];\n }>;\n}\n\nexport interface SystemEnvironmentPluginConfig {\n /**\n * Service name that resolves to a `ProjectProvisioningService`-shaped\n * object. Defaults to `tenant.provisioning` (convention used by\n * `@objectstack/service-tenant`).\n */\n serviceName?: string;\n\n /**\n * When true, plugin treats a missing provisioning service as an error.\n * Defaults to false — bootstrap is opt-in and must no-op gracefully when\n * the tenant package is not part of the stack.\n */\n strict?: boolean;\n}\n\n/**\n * System Project Bootstrap Plugin\n *\n * Ensures the built-in system project (well-known UUID\n * {@link SYSTEM_ENVIRONMENT_ID}) exists on the control plane the first time the\n * runtime starts. Calls are idempotent — `provisionSystemEnvironment()` returns\n * the existing row when the project has already been created.\n *\n * Register AFTER the tenant service is available so the provisioning service\n * can be resolved from the kernel.\n *\n * @example\n * ```ts\n * kernel.use(tenantPlugin);\n * kernel.use(createSystemEnvironmentPlugin());\n * ```\n */\nexport function createSystemEnvironmentPlugin(config: SystemEnvironmentPluginConfig = {}): Plugin {\n const serviceName = config.serviceName ?? 'tenant.provisioning';\n\n return {\n name: 'com.objectstack.runtime.system-environment',\n version: '1.0.0',\n\n init: async (_ctx: PluginContext) => {\n // Consumer-only plugin; nothing to register at init-time.\n },\n\n start: async (ctx: PluginContext) => {\n let service: ProvisioningLike | undefined;\n try {\n service = ctx.getService<ProvisioningLike>(serviceName);\n } catch {\n // Service registry throws when the key is not found.\n service = undefined;\n }\n\n if (!service || typeof service.provisionSystemEnvironment !== 'function') {\n if (config.strict) {\n throw new Error(\n `[SystemEnvironmentPlugin] Provisioning service '${serviceName}' not found — cannot bootstrap system project.`,\n );\n }\n ctx.logger.debug(\n `[SystemEnvironmentPlugin] Provisioning service '${serviceName}' unavailable — system project bootstrap skipped.`,\n );\n return;\n }\n\n try {\n const result = await service.provisionSystemEnvironment();\n const warnings = result.warnings ?? [];\n ctx.logger.info('[SystemEnvironmentPlugin] System project ready', {\n environmentId: result.project.id,\n isSystem: result.project.isSystem,\n warnings,\n });\n } catch (err: any) {\n if (config.strict) throw err;\n ctx.logger.warn('[SystemEnvironmentPlugin] Failed to provision system project', {\n error: err?.message ?? String(err),\n });\n }\n },\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { IHttpServer, RouteHandler, Middleware } from '@objectstack/core';\n\n/**\n * HttpServer - Unified HTTP Server Abstraction\n * \n * Provides a framework-agnostic HTTP server interface that wraps\n * underlying server implementations (Hono, Express, Fastify, etc.)\n * \n * This class serves as an adapter between the IHttpServer interface\n * and concrete server implementations, allowing plugins to register\n * routes and middleware without depending on specific frameworks.\n * \n * Features:\n * - Unified route registration API\n * - Middleware management with ordering\n * - Request/response lifecycle hooks\n * - Framework-agnostic abstractions\n */\nexport class HttpServer implements IHttpServer {\n protected server: IHttpServer;\n protected routes: Map<string, RouteHandler>;\n protected middlewares: Middleware[];\n \n /**\n * Create an HTTP server wrapper\n * @param server - The underlying server implementation (Hono, Express, etc.)\n */\n constructor(server: IHttpServer) {\n this.server = server;\n this.routes = new Map();\n this.middlewares = [];\n }\n \n /**\n * Register a GET route handler\n * @param path - Route path (e.g., '/api/users/:id')\n * @param handler - Route handler function\n */\n get(path: string, handler: RouteHandler): void {\n const key = `GET:${path}`;\n this.routes.set(key, handler);\n this.server.get(path, handler);\n }\n \n /**\n * Register a POST route handler\n * @param path - Route path\n * @param handler - Route handler function\n */\n post(path: string, handler: RouteHandler): void {\n const key = `POST:${path}`;\n this.routes.set(key, handler);\n this.server.post(path, handler);\n }\n \n /**\n * Register a PUT route handler\n * @param path - Route path\n * @param handler - Route handler function\n */\n put(path: string, handler: RouteHandler): void {\n const key = `PUT:${path}`;\n this.routes.set(key, handler);\n this.server.put(path, handler);\n }\n \n /**\n * Register a DELETE route handler\n * @param path - Route path\n * @param handler - Route handler function\n */\n delete(path: string, handler: RouteHandler): void {\n const key = `DELETE:${path}`;\n this.routes.set(key, handler);\n this.server.delete(path, handler);\n }\n \n /**\n * Register a PATCH route handler\n * @param path - Route path\n * @param handler - Route handler function\n */\n patch(path: string, handler: RouteHandler): void {\n const key = `PATCH:${path}`;\n this.routes.set(key, handler);\n this.server.patch(path, handler);\n }\n \n /**\n * Register middleware\n * @param path - Optional path to apply middleware to (if omitted, applies globally)\n * @param handler - Middleware function\n */\n use(path: string | Middleware, handler?: Middleware): void {\n if (typeof path === 'function') {\n // Global middleware\n this.middlewares.push(path);\n this.server.use(path);\n } else if (handler) {\n // Path-specific middleware\n this.middlewares.push(handler);\n this.server.use(path, handler);\n }\n }\n \n /**\n * Start the HTTP server\n * @param port - Port number to listen on\n * @returns Promise that resolves when server is ready\n */\n async listen(port: number): Promise<void> {\n await this.server.listen(port);\n }\n \n /**\n * Stop the HTTP server\n * @returns Promise that resolves when server is stopped\n */\n async close(): Promise<void> {\n if (this.server.close) {\n await this.server.close();\n }\n }\n \n /**\n * Get registered routes\n * @returns Map of route keys to handlers\n */\n getRoutes(): Map<string, RouteHandler> {\n return new Map(this.routes);\n }\n \n /**\n * Get registered middlewares\n * @returns Array of middleware functions\n */\n getMiddlewares(): Middleware[] {\n return [...this.middlewares];\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { Middleware, IHttpRequest, IHttpResponse } from '@objectstack/core';\nimport { MiddlewareConfig, MiddlewareType } from '@objectstack/spec/system';\n\n/**\n * Middleware Entry\n * Internal representation of registered middleware\n */\ninterface MiddlewareEntry {\n name: string;\n type: MiddlewareType;\n middleware: Middleware;\n order: number;\n enabled: boolean;\n paths?: {\n include?: string[];\n exclude?: string[];\n };\n}\n\n/**\n * MiddlewareManager\n * \n * Manages middleware registration, ordering, and execution.\n * Provides fine-grained control over middleware chains with:\n * - Execution order management\n * - Path-based filtering\n * - Enable/disable individual middleware\n * - Middleware categorization by type\n * \n * @example\n * const manager = new MiddlewareManager();\n * \n * // Register middleware with configuration\n * manager.register({\n * name: 'auth',\n * type: 'authentication',\n * order: 10,\n * paths: { exclude: ['/health', '/metrics'] }\n * }, authMiddleware);\n * \n * // Get sorted middleware chain\n * const chain = manager.getMiddlewareChain();\n * chain.forEach(mw => server.use(mw));\n */\nexport class MiddlewareManager {\n private middlewares: Map<string, MiddlewareEntry>;\n \n constructor() {\n this.middlewares = new Map();\n }\n \n /**\n * Register middleware with configuration\n * @param config - Middleware configuration\n * @param middleware - Middleware function\n */\n register(config: MiddlewareConfig, middleware: Middleware): void {\n const entry: MiddlewareEntry = {\n name: config.name,\n type: config.type,\n middleware,\n order: config.order ?? 100,\n enabled: config.enabled ?? true,\n paths: config.paths,\n };\n \n this.middlewares.set(config.name, entry);\n }\n \n /**\n * Unregister middleware by name\n * @param name - Middleware name\n */\n unregister(name: string): void {\n this.middlewares.delete(name);\n }\n \n /**\n * Enable middleware by name\n * @param name - Middleware name\n */\n enable(name: string): void {\n const entry = this.middlewares.get(name);\n if (entry) {\n entry.enabled = true;\n }\n }\n \n /**\n * Disable middleware by name\n * @param name - Middleware name\n */\n disable(name: string): void {\n const entry = this.middlewares.get(name);\n if (entry) {\n entry.enabled = false;\n }\n }\n \n /**\n * Get middleware entry by name\n * @param name - Middleware name\n */\n get(name: string): MiddlewareEntry | undefined {\n return this.middlewares.get(name);\n }\n \n /**\n * Get all middleware entries\n */\n getAll(): MiddlewareEntry[] {\n return Array.from(this.middlewares.values());\n }\n \n /**\n * Get middleware by type\n * @param type - Middleware type\n */\n getByType(type: MiddlewareType): MiddlewareEntry[] {\n return this.getAll().filter(entry => entry.type === type);\n }\n \n /**\n * Get middleware chain sorted by order\n * Returns only enabled middleware\n */\n getMiddlewareChain(): Middleware[] {\n return this.getAll()\n .filter(entry => entry.enabled)\n .sort((a, b) => a.order - b.order)\n .map(entry => entry.middleware);\n }\n \n /**\n * Get middleware chain with path filtering\n * @param path - Request path to match against\n */\n getMiddlewareChainForPath(path: string): Middleware[] {\n return this.getAll()\n .filter(entry => {\n if (!entry.enabled) return false;\n \n // Check path filters\n if (entry.paths) {\n // Check exclude patterns\n if (entry.paths.exclude) {\n const excluded = entry.paths.exclude.some(pattern => \n this.matchPath(path, pattern)\n );\n if (excluded) return false;\n }\n \n // Check include patterns (if specified)\n if (entry.paths.include) {\n const included = entry.paths.include.some(pattern => \n this.matchPath(path, pattern)\n );\n if (!included) return false;\n }\n }\n \n return true;\n })\n .sort((a, b) => a.order - b.order)\n .map(entry => entry.middleware);\n }\n \n /**\n * Match path against pattern (simple glob matching)\n * @param path - Request path\n * @param pattern - Pattern to match (supports * wildcard)\n */\n private matchPath(path: string, pattern: string): boolean {\n // Convert glob pattern to regex\n const regexPattern = pattern\n .replace(/\\*/g, '.*')\n .replace(/\\?/g, '.');\n \n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(path);\n }\n \n /**\n * Clear all middleware\n */\n clear(): void {\n this.middlewares.clear();\n }\n \n /**\n * Get middleware count\n */\n count(): number {\n return this.middlewares.size;\n }\n \n /**\n * Create a composite middleware from the chain\n * This can be used to apply all middleware at once\n */\n createCompositeMiddleware(): Middleware {\n const chain = this.getMiddlewareChain();\n \n return async (req: IHttpRequest, res: IHttpResponse, next: () => void | Promise<void>) => {\n let index = 0;\n \n const executeNext = async (): Promise<void> => {\n if (index >= chain.length) {\n await next();\n return;\n }\n \n const middleware = chain[index++];\n await middleware(req, res, executeNext);\n };\n \n await executeNext();\n };\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectKernel } from '@objectstack/core';\n\n/**\n * Factory contract for instantiating a per-project {@link ObjectKernel}.\n *\n * Given a `environmentId`, the factory is expected to:\n * 1. Read control-plane metadata (`sys_environment` + credentials + subscribed packages).\n * 2. Construct a fresh `ObjectKernel` with project-scoped driver + plugins + Apps.\n * 3. Return a **bootstrapped** kernel ready to serve requests.\n */\nexport interface EnvironmentKernelFactory {\n create(environmentId: string): Promise<ObjectKernel>;\n}\n\ninterface CachedEntry {\n kernel: ObjectKernel;\n createdAt: number;\n lastAccess: number;\n /**\n * Wall-clock ms of the most recent freshness probe (see\n * `freshnessProbe`). Throttles upstream probe rate to at most\n * `staleCheckIntervalMs` per env.\n */\n lastStaleCheckAt: number;\n}\n\nexport interface KernelManagerConfig {\n factory: EnvironmentKernelFactory;\n /** Maximum number of kernels to keep resident. Defaults to 32. */\n maxSize?: number;\n /**\n * Time-to-live (ms). Kernels idle longer than this are evicted on next\n * access. `0` disables TTL expiry. Defaults to 15 minutes.\n */\n ttlMs?: number;\n /**\n * Optional logger (duck-typed). Falls back to `console` when omitted.\n */\n logger?: { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n /**\n * Optional upstream-change detector. When set, every cache hit older\n * than `staleCheckIntervalMs` triggers this probe before returning the\n * cached kernel. Returning `true` evicts the kernel and forces a\n * rebuild, so changes to the control-plane state that don't reach\n * this process via push (marketplace installs, artifact republish,\n * etc.) become visible without waiting for the LRU TTL to expire.\n *\n * The probe should be cheap (single small GET). Errors thrown here\n * are caught and treated as \"still fresh\" so a brief upstream\n * outage doesn't churn every cached kernel — the worst case is\n * stale-by-`ttlMs`, which is what we had before adding the probe.\n *\n * `builtAtMs` is the kernel's `createdAt` time so the probe can\n * compare against an upstream \"last changed at\" timestamp.\n */\n freshnessProbe?: (environmentId: string, builtAtMs: number) => Promise<boolean>;\n /**\n * Minimum gap between successive freshness probes for the same env.\n * Defaults to 10 seconds — enough to avoid hammering the control\n * plane on tight render loops while still keeping the user's\n * post-install refresh perceived as immediate.\n */\n staleCheckIntervalMs?: number;\n}\n\n/**\n * LRU + TTL cache of per-project {@link ObjectKernel} instances.\n *\n * Implements ADR-0003 multi-kernel scheduling: each project gets an\n * isolated kernel (App/plugin/metadata namespaces) that is lazily built\n * on first request and evicted under memory / idle pressure. Concurrent\n * `getOrCreate()` calls for the same environmentId share a single in-flight\n * factory invocation (singleflight).\n */\nexport class KernelManager {\n private readonly factory: EnvironmentKernelFactory;\n private readonly maxSize: number;\n private readonly ttlMs: number;\n private readonly logger: NonNullable<KernelManagerConfig['logger']>;\n private readonly cache = new Map<string, CachedEntry>();\n private readonly pending = new Map<string, Promise<ObjectKernel>>();\n private readonly freshnessProbe?: KernelManagerConfig['freshnessProbe'];\n private readonly staleCheckIntervalMs: number;\n\n constructor(config: KernelManagerConfig) {\n this.factory = config.factory;\n this.maxSize = config.maxSize ?? 32;\n this.ttlMs = config.ttlMs ?? 15 * 60 * 1000;\n this.logger = config.logger ?? console;\n this.freshnessProbe = config.freshnessProbe;\n this.staleCheckIntervalMs = config.staleCheckIntervalMs ?? 10_000;\n }\n\n /** Returns the currently cached environmentIds (ordered by insertion). */\n keys(): string[] {\n return Array.from(this.cache.keys());\n }\n\n /** Cache size for diagnostics. */\n get size(): number {\n return this.cache.size;\n }\n\n /**\n * Resolve or construct the kernel for `environmentId`.\n *\n * - Cache hit (fresh): bumps `lastAccess` and returns immediately.\n * - Cache hit (TTL expired): evicts then falls through to factory.\n * - Cache miss: dedupes concurrent callers through `pending`.\n */\n async getOrCreate(environmentId: string): Promise<ObjectKernel> {\n const existing = this.cache.get(environmentId);\n if (existing) {\n if (this.ttlMs > 0 && Date.now() - existing.lastAccess > this.ttlMs) {\n await this.evict(environmentId);\n } else {\n // Throttled upstream freshness check. Probe errors are swallowed\n // so a brief control-plane outage doesn't churn the cache; the\n // worst case is stale-by-ttlMs, our prior behaviour.\n if (this.freshnessProbe) {\n const now = Date.now();\n if (now - existing.lastStaleCheckAt >= this.staleCheckIntervalMs) {\n existing.lastStaleCheckAt = now;\n let stale = false;\n try {\n stale = await this.freshnessProbe(environmentId, existing.createdAt);\n } catch (err) {\n this.logger.warn?.('[KernelManager] freshness probe failed', { environmentId, err });\n }\n if (stale) {\n this.logger.info?.('[KernelManager] kernel evicted by freshness probe', { environmentId });\n await this.evict(environmentId);\n // fall through to rebuild\n } else {\n existing.lastAccess = Date.now();\n return existing.kernel;\n }\n } else {\n existing.lastAccess = Date.now();\n return existing.kernel;\n }\n } else {\n existing.lastAccess = Date.now();\n return existing.kernel;\n }\n }\n }\n\n const inflight = this.pending.get(environmentId);\n if (inflight) return inflight;\n\n const promise = (async () => {\n const kernel = await this.factory.create(environmentId);\n const now = Date.now();\n this.cache.set(environmentId, { kernel, createdAt: now, lastAccess: now, lastStaleCheckAt: now });\n await this.enforceMaxSize();\n return kernel;\n })();\n\n this.pending.set(environmentId, promise);\n try {\n return await promise;\n } finally {\n this.pending.delete(environmentId);\n }\n }\n\n /**\n * Evict the kernel for `environmentId` and invoke `kernel.shutdown()`.\n * No-op when the entry is absent.\n */\n async evict(environmentId: string): Promise<void> {\n const entry = this.cache.get(environmentId);\n if (!entry) return;\n this.cache.delete(environmentId);\n try {\n await entry.kernel.shutdown();\n } catch (err) {\n this.logger.error?.('[KernelManager] shutdown failed', { environmentId, err });\n }\n }\n\n /** Evict all resident kernels. Used on runtime shutdown. */\n async evictAll(): Promise<void> {\n const ids = Array.from(this.cache.keys());\n await Promise.all(ids.map((id) => this.evict(id)));\n }\n\n private async enforceMaxSize(): Promise<void> {\n while (this.cache.size > this.maxSize) {\n // Find least-recently-accessed entry.\n let oldestKey: string | undefined;\n let oldestAccess = Infinity;\n for (const [key, entry] of this.cache) {\n if (entry.lastAccess < oldestAccess) {\n oldestAccess = entry.lastAccess;\n oldestKey = key;\n }\n }\n if (!oldestKey) return;\n await this.evict(oldestKey);\n }\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Artifact API client.\n *\n * HTTP client that talks to the ObjectStack control plane (e.g.\n * `apps/cloud`) to resolve hostnames to projects and to download a\n * project's compiled artifact.\n *\n * The control plane is expected to expose two endpoints:\n *\n * GET {controlPlaneUrl}/api/v1/cloud/resolve-hostname?host={hostname}\n * → { environmentId: string, organizationId?: string, runtime?: EnvironmentRuntimeConfig }\n *\n * GET {controlPlaneUrl}/api/v1/cloud/environments/:environmentId/artifact\n * → EnvironmentArtifactResponse (EnvironmentArtifact + optional `runtime` block)\n *\n * Both endpoints accept an optional `Authorization: Bearer <apiKey>`.\n *\n * Responses are cached in-memory with a TTL so each kernel-manager\n * miss does not produce an extra HTTP round trip. Concurrent callers\n * for the same key share a single in-flight promise (singleflight).\n */\n\nimport type { EnvironmentArtifact } from '@objectstack/spec/cloud';\n\n/**\n * Per-project runtime config injected by the control plane alongside\n * the artifact. Carries the physical database URL the runtime should\n * connect to (this is *not* part of the developer-authored compiled\n * artifact — the control plane mints it when serving the API).\n */\nexport interface EnvironmentRuntimeConfig {\n organizationId?: string;\n hostname?: string;\n /** Driver type — e.g. `sqlite`, `postgres`, `turso`, `memory`. */\n databaseDriver: string;\n /** Driver-specific connection URL. */\n databaseUrl: string;\n /** Optional auth token (e.g. for libSQL/Turso). */\n databaseAuthToken?: string;\n /**\n * Project-level metadata captured by the control plane at create time\n * (e.g. `ownerSeed`, `orgSeed`). Forwarded to the runtime so cold-boot\n * seed replay can mirror the cloud org + owner into the project DB\n * before the user's first SSO callback arrives.\n */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Hostname resolution response.\n */\nexport interface ResolvedHostname {\n environmentId: string;\n organizationId?: string;\n /** Optional runtime config — when present, callers can skip the artifact fetch's runtime block. */\n runtime?: EnvironmentRuntimeConfig;\n}\n\n/**\n * Artifact response wrapping the spec's `EnvironmentArtifact` envelope plus\n * an optional `runtime` block carrying the project's database\n * connection details.\n */\nexport interface EnvironmentArtifactResponse extends EnvironmentArtifact {\n runtime?: EnvironmentRuntimeConfig;\n}\n\nexport interface ArtifactApiClientConfig {\n /** Control-plane base URL (no trailing slash). */\n controlPlaneUrl: string;\n /** Optional bearer token. */\n apiKey?: string;\n /** Cache TTL in ms. Default: 5 min. */\n cacheTtlMs?: number;\n /** Timeout for control-plane HTTP calls in ms. Default: 10s. */\n requestTimeoutMs?: number;\n /** Optional fetch override (testing). */\n fetch?: typeof fetch;\n /** Optional logger. */\n logger?: { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n}\n\ninterface CacheEntry<T> {\n value: T;\n expiresAt: number;\n}\n\nexport class ArtifactApiClient {\n private readonly base: string;\n private readonly apiKey?: string;\n private readonly cacheTtlMs: number;\n private readonly requestTimeoutMs: number;\n private readonly fetchImpl: typeof fetch;\n private readonly logger: NonNullable<ArtifactApiClientConfig['logger']>;\n\n private readonly hostnameCache = new Map<string, CacheEntry<ResolvedHostname>>();\n private readonly artifactCache = new Map<string, CacheEntry<EnvironmentArtifactResponse>>();\n private readonly pendingHostname = new Map<string, Promise<ResolvedHostname | null>>();\n private readonly pendingArtifact = new Map<string, Promise<EnvironmentArtifactResponse | null>>();\n\n constructor(config: ArtifactApiClientConfig) {\n if (!config.controlPlaneUrl) {\n throw new Error('[ArtifactApiClient] controlPlaneUrl is required');\n }\n this.base = config.controlPlaneUrl.replace(/\\/+$/, '');\n this.apiKey = config.apiKey;\n this.cacheTtlMs = config.cacheTtlMs ?? 5 * 60 * 1000;\n this.requestTimeoutMs = config.requestTimeoutMs ?? 10_000;\n this.fetchImpl = config.fetch ?? globalThis.fetch;\n this.logger = config.logger ?? console;\n if (typeof this.fetchImpl !== 'function') {\n throw new Error('[ArtifactApiClient] global fetch is not available — provide config.fetch');\n }\n }\n\n /**\n * Resolve a hostname to its project. Returns `null` on 404 or\n * malformed responses. Errors (network / 5xx) are thrown so\n * upstream callers can retry.\n */\n async resolveHostname(host: string): Promise<ResolvedHostname | null> {\n const cached = this.hostnameCache.get(host);\n if (cached && cached.expiresAt > Date.now()) return cached.value;\n\n const inflight = this.pendingHostname.get(host);\n if (inflight) return inflight;\n\n const promise = (async () => {\n try {\n const url = `${this.base}/api/v1/cloud/resolve-hostname?host=${encodeURIComponent(host)}`;\n const res = await this.request(url);\n if (res === null) return null;\n const body = res.success === false ? null : (res.data ?? res);\n if (!body || typeof body.environmentId !== 'string' || !body.environmentId) return null;\n const value: ResolvedHostname = {\n environmentId: body.environmentId,\n organizationId: body.organizationId,\n runtime: body.runtime,\n };\n this.hostnameCache.set(host, { value, expiresAt: Date.now() + this.cacheTtlMs });\n return value;\n } finally {\n this.pendingHostname.delete(host);\n }\n })();\n this.pendingHostname.set(host, promise);\n return promise;\n }\n\n /**\n * Fetch the compiled artifact for a project.\n *\n * When `opts.commit` is set, requests that specific revision via the\n * existing `?commit=` query param. Different commits are cached\n * independently (the cache key includes the commit id) so the preview\n * runtime can hold multiple versions in memory simultaneously.\n */\n async fetchArtifact(environmentId: string, opts?: { commit?: string }): Promise<EnvironmentArtifactResponse | null> {\n const commit = opts?.commit?.trim() || '';\n const cacheKey = commit ? `${environmentId}@${commit}` : environmentId;\n const cached = this.artifactCache.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) return cached.value;\n\n const inflight = this.pendingArtifact.get(cacheKey);\n if (inflight) return inflight;\n\n const promise = (async () => {\n try {\n const qs = commit ? `?commit=${encodeURIComponent(commit)}` : '';\n const url = `${this.base}/api/v1/cloud/environments/${encodeURIComponent(environmentId)}/artifact${qs}`;\n const res = await this.request(url);\n if (res === null) return null;\n const body = res.success === false ? null : (res.data ?? res);\n if (!body || typeof body !== 'object') return null;\n if (!body.metadata) {\n this.logger.warn?.('[ArtifactApiClient] artifact response missing `metadata`', { environmentId, commit });\n return null;\n }\n const value = body as EnvironmentArtifactResponse;\n this.artifactCache.set(cacheKey, { value, expiresAt: Date.now() + this.cacheTtlMs });\n return value;\n } finally {\n this.pendingArtifact.delete(cacheKey);\n }\n })();\n this.pendingArtifact.set(cacheKey, promise);\n return promise;\n }\n\n /**\n * Resolve an 8-hex project short id (first 8 hex chars of the UUID,\n * dashes stripped) to the full environmentId. Used by the preview\n * runtime, which encodes project ids in subdomains.\n *\n * Returns `null` on 404 or ambiguity (the control plane returns 409\n * if the prefix matches more than one project).\n */\n async lookupProjectByShortId(shortId: string): Promise<{ environmentId: string; organizationId?: string } | null> {\n const short = String(shortId ?? '').trim().toLowerCase();\n if (!/^[0-9a-f]{8,}$/.test(short)) return null;\n const url = `${this.base}/api/v1/cloud/environments-by-short-id/${encodeURIComponent(short)}`;\n const res = await this.request(url);\n if (res === null) return null;\n const body = res.success === false ? null : (res.data ?? res);\n if (!body || typeof body.environmentId !== 'string' || !body.environmentId) return null;\n return { environmentId: body.environmentId, organizationId: body.organizationId };\n }\n\n /**\n * Fetch the head commit of a branch. Returns the commit id (and the\n * matching revision row's `published_at` for cache-validity checks).\n * Reuses the existing `GET /cloud/environments/:id/branches` endpoint.\n */\n async fetchBranchHead(\n environmentId: string,\n branchName: string,\n ): Promise<{ commitId: string; publishedAt?: string | null } | null> {\n const url = `${this.base}/api/v1/cloud/environments/${encodeURIComponent(environmentId)}/branches`;\n const res = await this.request(url);\n if (res === null) return null;\n const body = res.success === false ? null : (res.data ?? res);\n const branches = Array.isArray(body?.branches) ? body.branches : [];\n const target = String(branchName ?? '').trim().toLowerCase();\n const found = branches.find((b: any) => String(b?.branch ?? '').toLowerCase() === target);\n if (!found?.headCommitId) return null;\n return { commitId: String(found.headCommitId), publishedAt: found.headPublishedAt ?? null };\n }\n\n /**\n * Cheap freshness probe — returns the env's `last_published_at`\n * (and best-effort current commit) without rebuilding the artifact.\n * Used by `KernelManager` on cache hits to detect when a per-env\n * kernel has been invalidated by an upstream change (marketplace\n * install/uninstall, artifact publish) so it can be rebuilt\n * without waiting for the 15-minute LRU TTL to expire.\n *\n * Returns `null` on definitive 404 / unknown env. Errors propagate\n * (caller decides whether to treat unreachable cloud as fresh or\n * stale — typically fresh, so a brief outage doesn't churn every\n * cached kernel).\n */\n async getFreshness(environmentId: string): Promise<{\n environmentId: string;\n lastPublishedAt: string | null;\n commitId: string | null;\n } | null> {\n const url = `${this.base}/api/v1/cloud/environments/${encodeURIComponent(environmentId)}/freshness`;\n const res = await this.request(url);\n if (res === null) return null;\n const body = res.success === false ? null : (res.data ?? res);\n if (!body || typeof body !== 'object') return null;\n const envId = typeof body.environmentId === 'string' ? body.environmentId : environmentId;\n const lastPublishedAt = typeof body.lastPublishedAt === 'string' ? body.lastPublishedAt : null;\n const commitId = typeof body.commitId === 'string' ? body.commitId : null;\n return { environmentId: envId, lastPublishedAt, commitId };\n }\n\n /** Drop cached entries for a project (and any matching hostname). */\n invalidate(environmentId: string): void {\n // Cache keys are `${environmentId}` for HEAD or `${environmentId}@${commit}`\n // for pinned reads (preview runtime). Drop both shapes.\n this.artifactCache.delete(environmentId);\n const prefix = `${environmentId}@`;\n for (const key of Array.from(this.artifactCache.keys())) {\n if (key.startsWith(prefix)) this.artifactCache.delete(key);\n }\n for (const [host, entry] of this.hostnameCache) {\n if (entry.value.environmentId === environmentId) this.hostnameCache.delete(host);\n }\n }\n\n /** Drop everything. Used on shutdown / hot-reload. */\n clear(): void {\n this.hostnameCache.clear();\n this.artifactCache.clear();\n }\n\n private async request(url: string): Promise<any> {\n const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;\n const timer = controller ? setTimeout(() => controller.abort(), this.requestTimeoutMs) : null;\n try {\n const res = await this.fetchImpl(url, {\n method: 'GET',\n headers: this.buildHeaders(),\n signal: controller?.signal,\n });\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`[ArtifactApiClient] ${url} → HTTP ${res.status}`);\n }\n return await res.json();\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'accept': 'application/json',\n 'user-agent': 'objectos-runtime',\n };\n if (this.apiKey) headers['authorization'] = `Bearer ${this.apiKey}`;\n return headers;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * EnvironmentDriverRegistry implementation that talks to the control plane\n * over HTTP via {@link ArtifactApiClient}.\n *\n * Mirrors {@link DefaultEnvironmentDriverRegistry} from `environment-registry.ts`\n * but does **not** read from a local control-plane database. Hostname →\n * environmentId resolution and per-project runtime config (database URL /\n * driver) come from the control plane API.\n *\n * The cached `project` payload exposed by `peekById()` is shaped to look\n * like a `sys_environment` row so callers downstream (notably\n * `ArtifactKernelFactory`) can read `id`, `organization_id`,\n * `database_url` and `database_driver` without branching.\n */\n\nimport type * as Contracts from '@objectstack/spec/contracts';\nimport { resolve as resolvePathNode } from 'node:path';\nimport type { EnvironmentDriverRegistry } from './environment-registry.js';\nimport type { ArtifactApiClient, EnvironmentRuntimeConfig } from './artifact-api-client.js';\n\ntype IDataDriver = Contracts.IDataDriver;\n\ninterface CacheEntry {\n environmentId: string;\n driver: IDataDriver;\n project: any;\n expiresAt: number;\n}\n\nexport interface ArtifactEnvironmentRegistryConfig {\n client: ArtifactApiClient;\n /** Cache TTL for resolved drivers in ms. Default: 5 min. */\n cacheTtlMs?: number;\n /** Optional logger. */\n logger?: { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n}\n\nexport class ArtifactEnvironmentRegistry implements EnvironmentDriverRegistry {\n private readonly client: ArtifactApiClient;\n private readonly cacheTTL: number;\n private readonly logger: NonNullable<ArtifactEnvironmentRegistryConfig['logger']>;\n\n private readonly hostnameCache = new Map<string, CacheEntry>();\n private readonly idCache = new Map<string, CacheEntry>();\n private readonly pending = new Map<string, Promise<CacheEntry | null>>();\n\n constructor(config: ArtifactEnvironmentRegistryConfig) {\n this.client = config.client;\n this.cacheTTL = config.cacheTtlMs ?? 5 * 60 * 1000;\n this.logger = config.logger ?? console;\n }\n\n async resolveByHostname(host: string): Promise<{ environmentId: string; driver: IDataDriver } | null> {\n const cached = this.hostnameCache.get(host);\n if (cached && cached.expiresAt > Date.now()) {\n return { environmentId: cached.environmentId, driver: cached.driver };\n }\n const key = `host:${host}`;\n const inflight = this.pending.get(key);\n if (inflight) {\n const result = await inflight;\n return result ? { environmentId: result.environmentId, driver: result.driver } : null;\n }\n const promise = (async (): Promise<CacheEntry | null> => {\n try {\n const resolved = await this.client.resolveHostname(host);\n if (!resolved) return null;\n const entry = await this.buildCacheEntry(resolved.environmentId, resolved.runtime, resolved.organizationId, host);\n if (!entry) return null;\n this.hostnameCache.set(host, entry);\n this.idCache.set(entry.environmentId, entry);\n return entry;\n } catch (err: any) {\n this.logger.error?.('[ArtifactEnvironmentRegistry] resolveByHostname failed', {\n host,\n error: err?.message ?? err,\n });\n return null;\n } finally {\n this.pending.delete(key);\n }\n })();\n this.pending.set(key, promise);\n const entry = await promise;\n return entry ? { environmentId: entry.environmentId, driver: entry.driver } : null;\n }\n\n async resolveById(environmentId: string): Promise<IDataDriver | null> {\n const cached = this.idCache.get(environmentId);\n if (cached && cached.expiresAt > Date.now()) return cached.driver;\n\n const key = `id:${environmentId}`;\n const inflight = this.pending.get(key);\n if (inflight) {\n const result = await inflight;\n return result?.driver ?? null;\n }\n const promise = (async (): Promise<CacheEntry | null> => {\n try {\n const entry = await this.buildCacheEntry(environmentId, undefined, undefined, undefined);\n if (!entry) return null;\n this.idCache.set(environmentId, entry);\n if (entry.project?.hostname) this.hostnameCache.set(entry.project.hostname, entry);\n return entry;\n } catch (err: any) {\n this.logger.error?.('[ArtifactEnvironmentRegistry] resolveById failed', {\n environmentId,\n error: err?.message ?? err,\n });\n return null;\n } finally {\n this.pending.delete(key);\n }\n })();\n this.pending.set(key, promise);\n const entry = await promise;\n return entry?.driver ?? null;\n }\n\n peekById(environmentId: string): { environmentId: string; driver: IDataDriver; project: any } | null {\n const cached = this.idCache.get(environmentId);\n if (cached && cached.expiresAt > Date.now()) {\n return { environmentId: cached.environmentId, driver: cached.driver, project: cached.project };\n }\n return null;\n }\n\n invalidate(environmentId: string): void {\n this.idCache.delete(environmentId);\n for (const [host, entry] of this.hostnameCache) {\n if (entry.environmentId === environmentId) this.hostnameCache.delete(host);\n }\n this.client.invalidate(environmentId);\n }\n\n private async buildCacheEntry(\n environmentId: string,\n runtimeFromHostname: EnvironmentRuntimeConfig | undefined,\n orgIdFromHostname: string | undefined,\n hostname: string | undefined,\n ): Promise<CacheEntry | null> {\n let runtime = runtimeFromHostname;\n let organizationId = orgIdFromHostname;\n let host = hostname;\n let artifactProjectId = environmentId;\n\n if (!runtime || !organizationId) {\n const artifact = await this.client.fetchArtifact(environmentId);\n if (!artifact) {\n this.logger.warn?.('[ArtifactEnvironmentRegistry] artifact not found', { environmentId });\n return null;\n }\n artifactProjectId = artifact.environmentId ?? environmentId;\n if (!runtime) runtime = artifact.runtime ?? extractRuntimeFromMetadata(artifact.metadata);\n if (!organizationId) organizationId = artifact.runtime?.organizationId;\n if (!host) host = artifact.runtime?.hostname;\n }\n\n if (!runtime || !runtime.databaseUrl || !runtime.databaseDriver) {\n this.logger.warn?.('[ArtifactEnvironmentRegistry] no runtime config for project', { environmentId });\n return null;\n }\n\n const driver = await createDriver(runtime.databaseDriver, runtime.databaseUrl, runtime.databaseAuthToken ?? '');\n\n const projectRow = {\n id: artifactProjectId,\n organization_id: organizationId,\n hostname: host,\n database_url: runtime.databaseUrl,\n database_driver: runtime.databaseDriver,\n metadata: runtime.metadata,\n };\n\n return {\n environmentId: artifactProjectId,\n driver,\n project: projectRow,\n expiresAt: Date.now() + this.cacheTTL,\n };\n }\n}\n\n/**\n * Best-effort fallback: if the control plane did not return an explicit\n * `runtime` block, look for a default datasource in the compiled artifact\n * and reuse its connection config. Useful for self-published artifacts\n * where the developer encoded the connection inline (e.g. memory:// for\n * demos).\n */\nfunction extractRuntimeFromMetadata(metadata: any): EnvironmentRuntimeConfig | undefined {\n const datasources = metadata?.datasources;\n if (!Array.isArray(datasources) || datasources.length === 0) return undefined;\n const mapping: any[] | undefined = metadata?.datasourceMapping;\n let preferredName: string | undefined;\n if (mapping) {\n const def = mapping.find((m: any) => m?.default === true);\n if (def?.datasource) preferredName = def.datasource;\n }\n const ds = preferredName\n ? datasources.find((d: any) => d?.name === preferredName)\n : datasources[0];\n if (!ds || typeof ds !== 'object') return undefined;\n const config = (ds.config ?? {}) as Record<string, any>;\n const url = config.url ?? config.connectionString ?? config.connection ?? config.filename;\n const driver = ds.driver;\n if (typeof driver !== 'string' || typeof url !== 'string') return undefined;\n return {\n databaseDriver: driver,\n databaseUrl: url,\n databaseAuthToken: typeof config.authToken === 'string' ? config.authToken : undefined,\n };\n}\n\nasync function createDriver(driverType: string, databaseUrl: string, authToken: string): Promise<IDataDriver> {\n switch (driverType) {\n case 'libsql':\n case 'turso': {\n // The libsql/turso driver was extracted out of the framework\n // monorepo into `cloud/packages/driver-turso` (May 2026).\n // Package name is unchanged, so `await import(...)` resolves\n // it from the host app's node_modules (apps/objectos pins\n // `@objectstack/driver-turso: workspace:*` from the cloud\n // workspace, which surfaces in the Docker image's\n // node_modules layout). Self-host installs that need Turso\n // must `npm install @objectstack/driver-turso` from the cloud\n // package (or use the published version) before booting.\n // pnpm symlinks `@objectstack/runtime` into the host app's\n // node_modules but Node's ESM resolver follows the file's\n // realpath, which lives under framework/packages/runtime — from\n // there `@objectstack/driver-turso` (which lives in cloud/) is\n // invisible. We resolve explicitly from the host process cwd\n // (apps/objectos at runtime), which can see the cloud package\n // via its workspace:* dependency.\n let TursoDriver: any;\n try {\n ({ TursoDriver } = await import('@objectstack/driver-turso' as any));\n } catch (primaryErr: any) {\n try {\n const { createRequire } = await import('node:module');\n const path = await import('node:path');\n const url = await import('node:url');\n const hostRequire = createRequire(path.join(process.cwd(), 'noop.js'));\n const resolved = hostRequire.resolve('@objectstack/driver-turso');\n ({ TursoDriver } = await import(url.pathToFileURL(resolved).href));\n } catch (fallbackErr: any) {\n throw new Error(\n `[ArtifactEnvironmentRegistry] libsql/turso driver requested but @objectstack/driver-turso is not resolvable. ` +\n `Install it from the cloud monorepo (cloud/packages/driver-turso) or via npm. ` +\n `(primary: ${primaryErr?.message ?? primaryErr}; fallback: ${fallbackErr?.message ?? fallbackErr})`,\n );\n }\n }\n return new TursoDriver({ url: databaseUrl, authToken }) as unknown as IDataDriver;\n }\n case 'memory': {\n const { InMemoryDriver } = await import('@objectstack/driver-memory');\n const dbName = databaseUrl.replace(/^memory:\\/\\//, '').trim();\n // Resolve memory persistence files under the process cwd's\n // `.objectstack/data/projects/<name>.json` — keeps file-only dev\n // self-contained without depending on the cloud package's\n // serverless data-dir resolver.\n const filePath = dbName\n ? resolvePathNode(process.cwd(), '.objectstack/data/projects', `${dbName}.json`)\n : undefined;\n return new InMemoryDriver({\n persistence: filePath ? { type: 'file', path: filePath } : 'file',\n }) as unknown as IDataDriver;\n }\n case 'sqlite':\n case 'sql': {\n const filePath = databaseUrl.replace(/^file:/, '').replace(/^sql:\\/\\//, '');\n const { SqlDriver } = await import('@objectstack/driver-sql');\n return new SqlDriver({\n client: 'better-sqlite3',\n connection: { filename: filePath },\n useNullAsDefault: true,\n }) as unknown as IDataDriver;\n }\n case 'postgres':\n case 'postgresql':\n case 'pg': {\n const { SqlDriver } = await import('@objectstack/driver-sql');\n return new SqlDriver({\n client: 'pg',\n connection: databaseUrl,\n pool: { min: 0, max: 5 },\n }) as unknown as IDataDriver;\n }\n case 'mongodb':\n case 'mongo': {\n const { MongoDBDriver } = await import('@objectstack/driver-mongodb');\n return new MongoDBDriver({ url: databaseUrl }) as unknown as IDataDriver;\n }\n default:\n throw new Error(`[ArtifactEnvironmentRegistry] Unsupported driver type: ${driverType}`);\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * EnvironmentKernelFactory backed by the control plane's Artifact API.\n *\n * Differs from {@link DefaultEnvironmentKernelFactory} in two ways:\n *\n * 1. There is no local control-plane database to query — project rows\n * come from the {@link ArtifactEnvironmentRegistry} cache populated\n * via HTTP.\n * 2. There is no `ControlPlaneProxyDriver` mounted on the per-project\n * kernel. The runtime is intentionally isolated from the control\n * plane: each project kernel only knows about its own data driver.\n *\n * The kernel is bootstrapped with:\n * • DriverPlugin(driver) — project-scoped data driver, also aliased\n * as the `'cloud'` datasource so AuthPlugin's\n * identity manifest resolves locally.\n * • ObjectQLPlugin\n * • MetadataPlugin (registers `sys_metadata` + `sys_metadata_history` on\n * the project DB — required by ADR-0005: customization\n * overlays such as user-created views/dashboards are\n * persisted by ObjectStackProtocolImplementation on the\n * per-project engine, so the table must exist there).\n * • AuthPlugin — per-project, derives an HKDF secret from\n * `OS_AUTH_SECRET` + environmentId. Each project owns its\n * own `sys_user/sys_session/...` tables in its own\n * Turso DB. Cookies are scoped to the project's\n * hostname (no `.<root>`-wide cross-project leak).\n * • AppPlugin(artifact.metadata) — compiled developer code\n */\n\nimport { createHmac } from 'node:crypto';\nimport { ObjectKernel } from '@objectstack/core';\nimport { readEnvWithDeprecation } from '@objectstack/types';\nimport type * as Contracts from '@objectstack/spec/contracts';\nimport { DriverPlugin } from '../driver-plugin.js';\nimport { AppPlugin } from '../app-plugin.js';\nimport type { EnvironmentKernelFactory } from './kernel-manager.js';\nimport type { EnvironmentDriverRegistry } from './environment-registry.js';\nimport type { ArtifactApiClient } from './artifact-api-client.js';\nimport { loadCapabilities } from './capability-loader.js';\nimport {\n PLATFORM_SSO_PROVIDER_ID,\n derivePlatformSsoClientId,\n derivePlatformSsoClientSecret,\n} from './platform-sso.js';\n\ntype IDataDriver = Contracts.IDataDriver;\n\nexport interface ArtifactKernelFactoryConfig {\n client: ArtifactApiClient;\n envRegistry: EnvironmentDriverRegistry;\n /** Optional logger. */\n logger?: { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n /** Optional kernel constructor config. */\n kernelConfig?: ConstructorParameters<typeof ObjectKernel>[0];\n /**\n * Base secret used to derive per-project AuthPlugin secrets via\n * HKDF-style HMAC-SHA256(baseSecret, environmentId). Falls back to\n * `process.env.OS_AUTH_SECRET` / `AUTH_SECRET` at construction time.\n */\n authBaseSecret?: string;\n}\n\n/**\n * Derive a deterministic per-project auth secret. HMAC-SHA256 of the\n * environmentId keyed by the base secret yields a 64-char hex string that is:\n * - stable across container cold-starts (no DB lookup needed)\n * - independent per project (forging a token on project A does not\n * compromise project B)\n * - rotatable by changing the base secret (will invalidate all sessions)\n */\nfunction deriveProjectAuthSecret(baseSecret: string, environmentId: string): string {\n return createHmac('sha256', baseSecret).update(`project:${environmentId}`).digest('hex');\n}\n\nexport class ArtifactKernelFactory implements EnvironmentKernelFactory {\n private readonly client: ArtifactApiClient;\n private readonly envRegistry: EnvironmentDriverRegistry;\n private readonly logger: NonNullable<ArtifactKernelFactoryConfig['logger']>;\n private readonly kernelConfig?: ArtifactKernelFactoryConfig['kernelConfig'];\n private readonly authBaseSecret: string;\n\n constructor(config: ArtifactKernelFactoryConfig) {\n this.client = config.client;\n this.envRegistry = config.envRegistry;\n this.logger = config.logger ?? console;\n this.kernelConfig = config.kernelConfig;\n this.authBaseSecret = (\n config.authBaseSecret\n ?? readEnvWithDeprecation('OS_AUTH_SECRET', ['AUTH_SECRET', 'BETTER_AUTH_SECRET'])\n ?? ''\n ).trim();\n }\n\n async create(environmentId: string): Promise<ObjectKernel> {\n let cached = this.envRegistry.peekById(environmentId);\n if (!cached) {\n const driver = await this.envRegistry.resolveById(environmentId);\n if (!driver) {\n throw new Error(`[ArtifactKernelFactory] Could not resolve driver for project '${environmentId}'`);\n }\n cached = this.envRegistry.peekById(environmentId);\n if (!cached) {\n throw new Error(`[ArtifactKernelFactory] envRegistry returned a driver but no cached entry for '${environmentId}'`);\n }\n }\n\n const driver: IDataDriver = cached.driver;\n const project = cached.project as { id: string; organization_id?: string; hostname?: string };\n\n const artifact = await this.client.fetchArtifact(environmentId);\n if (!artifact) {\n throw new Error(`[ArtifactKernelFactory] Artifact not available for project '${environmentId}'`);\n }\n\n const { ObjectQLPlugin } = await import('@objectstack/objectql');\n const { MetadataPlugin } = await import('@objectstack/metadata');\n\n const kernel = new ObjectKernel(this.kernelConfig);\n\n // Register the project driver as both the unnamed default AND under\n // the `'cloud'` alias. AuthPlugin's manifest header historically\n // declares `defaultDatasource: 'cloud'`; aliasing here keeps that\n // path working without forcing every project's identity table\n // through a control-plane proxy.\n await kernel.use(new DriverPlugin(driver, { datasourceName: 'cloud' } as any));\n // Enable schema sync per-project so sys_user / sys_session / etc.\n // tables get created on the project's own DB. The host worker sets\n // `OS_SKIP_SCHEMA_SYNC=1` for the control-plane DB; that env var\n // must NOT bleed into project kernels because their auth tables\n // need provisioning. KernelManager caches kernels so this runs\n // at most once per cold-start per project.\n await kernel.use(new ObjectQLPlugin({ environmentId: environmentId, skipSchemaSync: false }));\n await kernel.use(new MetadataPlugin({\n watch: false,\n environmentId: environmentId,\n organizationId: project.organization_id,\n // ADR-0005: customization overlays (user-created views, dashboards,\n // edited objects, ...) are persisted by\n // ObjectStackProtocolImplementation.saveMetaItem on whichever\n // engine the protocol is attached to. For per-project kernels that\n // means the project's own DB, so the sys_metadata + history tables\n // MUST be provisioned here. The previous `false` setting caused\n // \"no such table: sys_metadata\" errors on any PUT /api/v1/meta/*\n // call (e.g. Studio \"Create View\") against a project deployment.\n registerSystemObjects: true,\n }));\n\n // Per-project AuthPlugin — only when an OS_AUTH_SECRET base is\n // configured. Without it we cannot derive a secret deterministically\n // and refuse to start auth (better silent-fail than insecure default).\n if (this.authBaseSecret) {\n try {\n const { AuthPlugin } = await import('@objectstack/plugin-auth');\n const projectSecret = deriveProjectAuthSecret(this.authBaseSecret, environmentId);\n const baseUrl = project.hostname\n ? (project.hostname.startsWith('http')\n ? project.hostname\n : (/(\\.|^)localhost(:\\d+)?$/i.test(project.hostname)\n ? (() => {\n const runtimePort = (process.env.OS_RUNTIME_PORT ?? '').trim();\n const hasPort = /:\\d+$/.test(project.hostname);\n const hostWithPort = hasPort || !runtimePort\n ? project.hostname\n : `${project.hostname}:${runtimePort}`;\n return `http://${hostWithPort}`;\n })()\n : `https://${project.hostname}`))\n : undefined;\n\n // Build the list of trusted origins for CSRF.\n // - Production: just the project's https baseUrl + any\n // platform-wide origins from OS_TRUSTED_ORIGINS (so\n // hostname renames don't require a kernel evict — the\n // parent worker already trusts `https://*.<rootdomain>`).\n // - Dev (*.localhost): also trust http variants on any port so\n // the local objectos dev server (PORT=4100 or any user-chosen\n // port) can complete sign-in from the browser. baseUrl alone\n // is `https://*.localhost` (no port, https) which the\n // browser's Origin (`http://*.localhost:4100`) does NOT\n // match — leading to better-auth \"Invalid origin\" 403.\n const trustedOriginsList: string[] = [];\n if (baseUrl) trustedOriginsList.push(baseUrl);\n // Inherit platform trusted-origin wildcards from the host\n // worker. Without this, renaming an environment leaves the\n // cached per-project kernel rejecting callbackURL=<new-host>\n // with INVALID_CALLBACK_URL until the next cold-start.\n const platformOrigins = (process.env.OS_TRUSTED_ORIGINS ?? '')\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n for (const o of platformOrigins) {\n if (!trustedOriginsList.includes(o)) trustedOriginsList.push(o);\n }\n // Convenience: when OS_ROOT_DOMAIN is set, trust the entire\n // platform subdomain space. Matches the host worker's CORS\n // posture so SSO survives any future tenant-domain rename.\n const rootDomain = (process.env.OS_ROOT_DOMAIN ?? '').trim().replace(/^https?:\\/\\//, '');\n if (rootDomain) {\n const wildcard = `https://*.${rootDomain}`;\n if (!trustedOriginsList.includes(wildcard)) trustedOriginsList.push(wildcard);\n }\n if (project.hostname) {\n const bareHost = project.hostname.replace(/^https?:\\/\\//, '');\n if (bareHost.endsWith('.localhost') || bareHost === 'localhost') {\n trustedOriginsList.push(`http://${bareHost}`);\n trustedOriginsList.push(`http://${bareHost}:*`);\n trustedOriginsList.push(`https://${bareHost}:*`);\n }\n }\n\n // Platform SSO (\"Airtable-style unified login\"): when the\n // cloud control-plane is reachable AND the master secret is\n // shared between the two containers, wire better-auth's\n // genericOAuth plugin so a builder who already signed in\n // on `cloud.<root>` is JIT-provisioned as a `sys_user` on\n // every per-project deployment without re-registering.\n //\n // Opt-out: set OS_PLATFORM_SSO=false to fall back to the\n // legacy \"every project owns its own login\" mode.\n const platformSsoEnabled = String(\n process.env.OS_PLATFORM_SSO ?? 'true',\n ).toLowerCase() !== 'false';\n const cloudBaseUrl = (process.env.OS_CLOUD_URL ?? '').trim().replace(/\\/+$/, '');\n const oidcProviders = platformSsoEnabled\n && cloudBaseUrl\n && /^https?:\\/\\//.test(cloudBaseUrl)\n ? [{\n providerId: PLATFORM_SSO_PROVIDER_ID,\n name: 'ObjectStack',\n discoveryUrl: `${cloudBaseUrl}/.well-known/openid-configuration`,\n clientId: derivePlatformSsoClientId(environmentId),\n clientSecret: derivePlatformSsoClientSecret(this.authBaseSecret, environmentId),\n scopes: ['openid', 'email', 'profile'],\n }]\n : undefined;\n\n await kernel.use(new AuthPlugin({\n secret: projectSecret,\n baseUrl,\n // Project kernel has no http-server (host owns it). The\n // dispatcher's handleAuth path resolves `auth` via\n // getService and invokes the handler directly — route\n // registration is unnecessary and would warn.\n registerRoutes: false,\n // Identity tables live in the project's own DB — keep\n // sys_user/sys_session local to this kernel.\n manifestDatasource: 'default',\n // Cookie scope: default to the project's own host. We\n // intentionally do NOT pass crossSubDomainCookies here\n // so cookies stay isolated per project subdomain.\n trustedOrigins: trustedOriginsList.length ? trustedOriginsList : undefined,\n ...(oidcProviders ? { oidcProviders } : {}),\n } as any));\n if (oidcProviders) {\n this.logger.info?.('[ArtifactKernelFactory] platform SSO wired', {\n environmentId,\n cloudBaseUrl,\n });\n }\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] AuthPlugin not registered', {\n environmentId,\n error: err?.message,\n });\n }\n } else {\n this.logger.warn?.('[ArtifactKernelFactory] OS_AUTH_SECRET not set — per-project AuthPlugin skipped (auth endpoints will return 404)', { environmentId });\n }\n\n // Per-project SecurityPlugin — provides RBAC + tenant_isolation RLS.\n // Multi-tenant deployments additionally register OrgScopingPlugin,\n // which provides organization_id auto-stamping, per-org seed\n // replay, and default-org bootstrap. SecurityPlugin probes the\n // `org-scoping` service at start time and strips the wildcard\n // `tenant_isolation` RLS when the scoping plugin is absent —\n // so OrgScopingPlugin MUST be registered before SecurityPlugin.\n try {\n const multiTenant = String(readEnvWithDeprecation('OS_MULTI_ORG_ENABLED', 'OS_MULTI_TENANT') ?? 'false').toLowerCase() !== 'false';\n if (multiTenant) {\n try {\n const { OrgScopingPlugin } = await import('@objectstack/plugin-org-scoping');\n await kernel.use(new OrgScopingPlugin() as any);\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] OrgScopingPlugin not registered (multi-tenant disabled)', {\n environmentId,\n error: err?.message,\n });\n }\n }\n const { SecurityPlugin } = await import('@objectstack/plugin-security');\n await kernel.use(new SecurityPlugin() as any);\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] SecurityPlugin not registered', {\n environmentId,\n error: err?.message,\n });\n }\n\n const projectName = project.hostname ?? environmentId;\n // Cloud Artifact API envelope shape (see\n // `service-cloud/src/routes/cloud.ts`):\n // { schemaVersion, environmentId, commitId, checksum,\n // metadata: { objects, views, apps, ... }, // category arrays only\n // functions, manifest, builtAt, runtime }\n // `manifest` is a TOP-LEVEL SIBLING of `metadata`, not nested\n // inside it. AppPlugin reads `bundle.manifest.id` for the plugin\n // name, so we must surface the sibling manifest onto the bundle\n // we hand it — otherwise it falls back to `'unnamed-app'` and a\n // package install (e.g. CRM Starter with declarative hooks)\n // crashes the env kernel at start, rolling back all plugins and\n // 500'ing every API.\n const artifactAny = artifact as any;\n const topLevelManifest = (artifactAny?.manifest && typeof artifactAny.manifest === 'object')\n ? artifactAny.manifest\n : null;\n const topLevelFunctions = Array.isArray(artifactAny?.functions) ? artifactAny.functions : [];\n const bundle: any = {\n ...(artifact.metadata ?? {}),\n ...(topLevelManifest ? { manifest: topLevelManifest } : {}),\n functions: topLevelFunctions,\n };\n const sys = bundle.manifest ?? bundle;\n const packageId = sys?.packageId ?? sys?.package_id ?? bundle?.packageId;\n\n // Per-project i18n: register I18nServicePlugin BEFORE AppPlugin so\n // AppPlugin.loadTranslations() finds an i18n service to populate.\n // Without this, the artifact's `translations` array is silently\n // dropped and the `/api/v1/i18n/*` endpoints return empty payloads.\n const i18nCfg = (bundle?.i18n ?? sys?.i18n ?? {}) as Record<string, any>;\n const trArr = Array.isArray(bundle?.translations) ? bundle.translations\n : Array.isArray(sys?.translations) ? sys.translations : [];\n // Always register — even with no inline translations the service\n // can serve labels/locales loaded by hosted apps. Cheap to register.\n try {\n const { I18nServicePlugin } = await import('@objectstack/service-i18n');\n await kernel.use(new I18nServicePlugin({\n defaultLocale: i18nCfg.defaultLocale,\n fallbackLocale: i18nCfg.fallbackLocale ?? i18nCfg.defaultLocale ?? 'en',\n // Routes are dispatched by HttpDispatcher.handleI18n via\n // kernel.getService('i18n'); the host worker owns the\n // HTTP server. Skip self-registration to avoid warnings.\n registerRoutes: false,\n } as any));\n console.warn(\n `[ArtifactKernelFactory] I18nServicePlugin registered (project=${environmentId}, translations=${trArr.length}, defaultLocale=${i18nCfg.defaultLocale ?? 'en'})`,\n );\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] I18nServicePlugin not registered', {\n environmentId,\n error: err?.message,\n });\n }\n\n // Tier-driven capability loading: install service plugins listed\n // in the artifact's `requires` array (e.g. ['ai','automation',\n // 'analytics']). Must be registered BEFORE AppPlugin so that\n // AppPlugin's start phase can hand off flows/agents/cubes to\n // services that are already initialised.\n const requiresRaw =\n (Array.isArray(bundle?.requires) ? bundle.requires : null) ??\n (Array.isArray(sys?.requires) ? sys.requires : null) ??\n [];\n const requires: string[] = (requiresRaw as unknown[])\n .filter((x): x is string => typeof x === 'string' && x.length > 0);\n\n if (requires.length > 0) {\n const installed = await loadCapabilities({\n kernel,\n requires,\n bundle: { ...(bundle ?? {}), ...(sys ?? {}) } as Record<string, unknown>,\n logger: this.logger,\n environmentId,\n });\n this.logger.info?.('[ArtifactKernelFactory] capabilities loaded', {\n environmentId,\n requires,\n installed,\n });\n }\n\n await kernel.use(new AppPlugin(bundle, {\n environmentId,\n organizationId: project.organization_id ?? '',\n projectName,\n packageId,\n source: packageId ? 'package' : 'user',\n } as any));\n\n await kernel.bootstrap();\n\n // Pre-seed the project owner. The cloud control-plane stashed the\n // creator's identity into `sys_environment.metadata.ownerSeed` at\n // project-create time; replay it AFTER `kernel.bootstrap()` so\n // ObjectQL/Security plugins have fully initialised and\n // `kernel.getService('objectql')` resolves. Pre-bootstrap, plugins\n // are only registered — services aren't wired yet.\n //\n // Order matters:\n // 1. Seed the OWNING cloud org into `sys_organization` so the\n // project's primary workspace matches the cloud team that\n // owns the project at the platform level.\n // 2. Seed the owner's `sys_user` row.\n // 3. Seed a `sys_member(owner)` row binding the user to the\n // cloud org so their first sign-in resolves an\n // activeOrganizationId without requiring an extra\n // \"create your first organization\" step.\n //\n // All three are idempotent — safe across cold-boots.\n try {\n const projMeta: any = typeof (project as any)?.metadata === 'string'\n ? JSON.parse((project as any).metadata)\n : ((project as any)?.metadata ?? {});\n const ownerSeed = projMeta?.ownerSeed;\n const orgSeed = projMeta?.orgSeed;\n\n if (orgSeed?.id && orgSeed?.name) {\n try {\n const { seedProjectOrganization } = await import('./environment-org-seed.js');\n await seedProjectOrganization(kernel, orgSeed, this.logger);\n } catch (e: any) {\n this.logger.warn?.('[ArtifactKernelFactory] orgSeed threw', {\n environmentId,\n error: e?.message,\n });\n }\n }\n\n if (ownerSeed?.userId && ownerSeed?.email) {\n try {\n const { seedProjectOwner } = await import('./environment-owner-seed.js');\n await seedProjectOwner(kernel, ownerSeed, this.logger);\n } catch (e: any) {\n this.logger.warn?.('[ArtifactKernelFactory] ownerSeed threw', {\n environmentId,\n error: e?.message,\n });\n }\n\n if (orgSeed?.id) {\n try {\n const { seedProjectMember } = await import('./environment-org-seed.js');\n await seedProjectMember(\n kernel,\n { userId: ownerSeed.userId, organizationId: orgSeed.id, role: 'owner' },\n this.logger,\n );\n } catch (e: any) {\n this.logger.warn?.('[ArtifactKernelFactory] memberSeed threw', {\n environmentId,\n error: e?.message,\n });\n }\n }\n }\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] owner/org seed skipped', {\n environmentId,\n error: err?.message,\n });\n }\n\n // Post-bootstrap seed replay. The SecurityPlugin's `sys_organization`\n // insert middleware only fires when a brand-new org row is inserted,\n // so packages installed AFTER the env's primary org already exists\n // would never get their `data` arrays applied. Run the seed-replayer\n // once per kernel cold-start so newly-installed marketplace packages\n // (e.g. CRM with \"Include sample data\" ticked) hydrate the primary\n // org on the next request after install.\n //\n // SeedLoader uses upsert semantics, so re-running across cold-starts\n // is idempotent — at worst we pay one batch upsert per kernel boot.\n try {\n const datasetsNow: any[] | undefined = (() => {\n try { return (kernel as any).getService?.('seed-datasets'); } catch { return undefined; }\n })();\n const replayer: any = (() => {\n try { return (kernel as any).getService?.('seed-replayer'); } catch { return undefined; }\n })();\n\n if (Array.isArray(datasetsNow) && datasetsNow.length > 0 && typeof replayer === 'function') {\n // Resolve the env's primary organization. Prefer the explicit\n // orgSeed metadata (set when env is created via the data API);\n // fall back to scanning sys_organization for the first row\n // (env created via the lifecycle endpoint that doesn't stash\n // orgSeed, or any env that has been used at least once).\n const projMetaRaw: any = (project as any)?.metadata;\n const projMeta: any = typeof projMetaRaw === 'string' ? (() => {\n try { return JSON.parse(projMetaRaw); } catch { return {}; }\n })() : (projMetaRaw ?? {});\n let primaryOrgId: string | undefined = projMeta?.orgSeed?.id;\n\n if (!primaryOrgId) {\n try {\n const ql: any = (kernel as any).getService?.('objectql');\n if (ql?.find) {\n const rows = await ql.find('sys_organization', { limit: 5, orderBy: [{ field: 'created_at', direction: 'asc' }] } as any);\n const list = Array.isArray(rows) ? rows : (rows?.value ?? rows?.records ?? []);\n if (Array.isArray(list) && list.length > 0 && list[0]?.id) {\n primaryOrgId = String(list[0].id);\n }\n }\n } catch { /* org table may not exist yet on a brand-new env */ }\n }\n\n if (primaryOrgId) {\n try {\n const summary = await replayer(primaryOrgId);\n const inserted = summary?.inserted ?? 0;\n const updated = summary?.updated ?? 0;\n const errs = summary?.errors?.length ?? 0;\n if (inserted > 0 || updated > 0 || errs > 0) {\n this.logger.info?.('[ArtifactKernelFactory] post-bootstrap seed replay', {\n environmentId,\n organizationId: primaryOrgId,\n datasets: datasetsNow.length,\n inserted,\n updated,\n errors: errs,\n });\n }\n } catch (e: any) {\n this.logger.warn?.('[ArtifactKernelFactory] post-bootstrap seed replay failed', {\n environmentId,\n organizationId: primaryOrgId,\n error: e?.message,\n });\n }\n }\n }\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] post-bootstrap seed step threw', {\n environmentId,\n error: err?.message,\n });\n }\n\n // Belt-and-braces: load translation bundles directly into the i18n\n // service after bootstrap. AppPlugin.loadTranslations should do this\n // during its `start` phase, but several conditions (missing objectql\n // service, runtime.onEnable throwing, bundle keys mismatch) can cause\n // it to bail before reaching the i18n step. Loading here guarantees\n // the bundles attached to the artifact metadata are always served via\n // `/api/v1/i18n/*`, regardless of AppPlugin's runtime path.\n let i18nSvc: any = null;\n try {\n i18nSvc = (kernel as any).getService?.('i18n');\n } catch {\n // getService throws when service isn't registered — leave null\n i18nSvc = null;\n }\n try {\n if (i18nSvc && typeof i18nSvc.loadTranslations === 'function') {\n if (i18nCfg.defaultLocale && typeof i18nSvc.setDefaultLocale === 'function') {\n i18nSvc.setDefaultLocale(i18nCfg.defaultLocale);\n }\n let loaded = 0;\n for (const tbundle of trArr) {\n if (!tbundle || typeof tbundle !== 'object') continue;\n for (const [locale, data] of Object.entries(tbundle)) {\n if (data && typeof data === 'object') {\n try {\n i18nSvc.loadTranslations(locale, data as Record<string, unknown>);\n loaded++;\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] i18n loadTranslations failed', {\n environmentId, locale, error: err?.message,\n });\n }\n }\n }\n }\n if (loaded > 0) {\n this.logger.info?.('[ArtifactKernelFactory] i18n direct-load complete', {\n environmentId, locales: loaded, bundles: trArr.length,\n });\n }\n }\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] i18n direct-load failed', {\n environmentId,\n error: err?.message,\n });\n }\n\n this.logger.info?.('[ArtifactKernelFactory] kernel ready', {\n environmentId,\n commitId: artifact.commitId,\n checksum: artifact.checksum,\n authEnabled: Boolean(this.authBaseSecret),\n });\n\n return kernel;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Capability loader — `bundle.requires` driven dispatch.\n *\n * Mirrors the CAPABILITY_PROVIDERS table in\n * `@objectstack/cli/src/commands/serve.ts` so that per-project kernels\n * built by {@link ArtifactKernelFactory} pick up the same service plugins\n * a developer would get when running `objectstack serve` locally.\n *\n * Design goals:\n * - Single source of truth: artifact's `requires` array. No hardcoded\n * plugin list per host.\n * - Lazy: each provider is dynamically imported only when requested,\n * keeping cold-start small for artifacts that don't need that\n * capability.\n * - Silent on missing deps: a host that doesn't ship the optional\n * package (e.g. service-queue) just logs a warn and continues.\n */\n\nimport type { ObjectKernel } from '@objectstack/core';\n\nexport interface CapabilitySpec {\n /** npm package name to import. */\n pkg: string;\n /** Named export — class constructor for the main plugin. */\n export: string;\n /**\n * Optional bundle key that, when present, is forwarded as constructor\n * argument (e.g. analytics needs `analyticsCubes`).\n */\n configKey?: string;\n /** Auxiliary plugins loaded alongside the main one. */\n extras?: Array<{ pkg: string; export: string }>;\n}\n\n/**\n * Registry of `requires` token → plugin provider.\n *\n * Keep keys in sync with the user-facing tokens accepted by\n * `defineStack({ requires: [...] })` and the CLI's CAPABILITY_PROVIDERS.\n *\n * Tier-gated capabilities (`auth`, `ui`, `i18n`) are intentionally NOT\n * listed here — they are wired explicitly by the kernel factory because\n * they need bespoke configuration (per-project HKDF secret, UI dist\n * paths, etc).\n */\nexport const CAPABILITY_PROVIDERS: Record<string, CapabilitySpec> = {\n automation: {\n // Self-contained: AutomationServicePlugin seeds all built-in node\n // executors itself (ADR-0018), so no companion node-pack plugins.\n pkg: '@objectstack/service-automation',\n export: 'AutomationServicePlugin',\n },\n ai: {\n pkg: '@objectstack/service-ai',\n export: 'AIServicePlugin',\n },\n analytics: {\n pkg: '@objectstack/service-analytics',\n export: 'AnalyticsServicePlugin',\n configKey: 'analyticsCubes',\n },\n audit: {\n pkg: '@objectstack/plugin-audit',\n export: 'AuditPlugin',\n },\n cache: {\n pkg: '@objectstack/service-cache',\n export: 'CacheServicePlugin',\n },\n storage: {\n pkg: '@objectstack/service-storage',\n export: 'StorageServicePlugin',\n },\n queue: {\n pkg: '@objectstack/service-queue',\n export: 'QueueServicePlugin',\n },\n job: {\n pkg: '@objectstack/service-job',\n export: 'JobServicePlugin',\n },\n messaging: {\n // Backs the `notify` flow node (ADR-0012): delivers to a user's\n // channels (inbox by default → `sys_inbox_message` rows).\n pkg: '@objectstack/service-messaging',\n export: 'MessagingServicePlugin',\n },\n triggers: {\n // Concrete flow triggers — record-change (ObjectQL hooks) + schedule\n // (cron/interval via the job service; pair `triggers` with `job`).\n pkg: '@objectstack/plugin-trigger-record-change',\n export: 'RecordChangeTriggerPlugin',\n extras: [{ pkg: '@objectstack/plugin-trigger-schedule', export: 'ScheduleTriggerPlugin' }],\n },\n realtime: {\n pkg: '@objectstack/service-realtime',\n export: 'RealtimeServicePlugin',\n },\n feed: {\n pkg: '@objectstack/service-feed',\n export: 'FeedServicePlugin',\n },\n settings: {\n pkg: '@objectstack/service-settings',\n export: 'SettingsServicePlugin',\n },\n};\n\ntype Logger = { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n\nexport interface LoadCapabilitiesOptions {\n kernel: ObjectKernel;\n /** Tokens from `bundle.requires` (e.g. `['ai','automation','analytics']`). */\n requires: readonly string[];\n /** Compiled artifact metadata. Used to pull `configKey`-driven args. */\n bundle: Record<string, unknown>;\n /** Optional logger. */\n logger?: Logger;\n /** environmentId for log breadcrumbs. */\n environmentId: string;\n}\n\n/**\n * Walk `requires` and install each known capability on the kernel.\n *\n * Returns the list of plugin exports actually installed for diagnostics.\n */\nexport async function loadCapabilities(opts: LoadCapabilitiesOptions): Promise<string[]> {\n const { kernel, requires, bundle, environmentId } = opts;\n const logger: Logger = opts.logger ?? console;\n const installed: string[] = [];\n\n // De-dupe, then ensure dependent capabilities are present. ADR-0030:\n // collaboration notifications (audit @mention/assignment) and the bell now\n // deliver through the messaging pipeline, so `messaging` must load whenever\n // `audit` does — otherwise those notifications silently no-op on cloud\n // per-project kernels (which, unlike `objectstack serve`, have no\n // always-on capability slate). Mirrors the CLI's foundational defaults.\n const resolved = [...new Set(requires)];\n if (resolved.includes('audit') && !resolved.includes('messaging')) {\n resolved.push('messaging');\n }\n\n for (const cap of resolved) {\n const spec = CAPABILITY_PROVIDERS[cap];\n if (!spec) {\n // Tier-gated capability (auth/ui/i18n) — wired elsewhere.\n continue;\n }\n\n try {\n const mod: any = await import(/* webpackIgnore: true */ spec.pkg);\n const Ctor = mod[spec.export];\n if (!Ctor) {\n logger.warn?.(\n `[CapabilityLoader] '${cap}': package '${spec.pkg}' did not export '${spec.export}'`,\n { environmentId },\n );\n continue;\n }\n\n let arg: unknown;\n if (spec.configKey) {\n const v = (bundle as Record<string, unknown>)[spec.configKey];\n if (spec.configKey === 'analyticsCubes') {\n arg = { cubes: Array.isArray(v) ? v : [] };\n } else if (v !== undefined) {\n arg = v;\n }\n }\n\n await kernel.use(arg !== undefined ? new Ctor(arg) : new Ctor());\n installed.push(spec.export);\n\n if (spec.extras) {\n for (const ex of spec.extras) {\n try {\n const exMod: any = await import(/* webpackIgnore: true */ ex.pkg);\n const ExCtor = exMod[ex.export];\n if (ExCtor) {\n await kernel.use(new ExCtor());\n installed.push(ex.export);\n }\n } catch {\n // Optional extra — silently skip.\n }\n }\n }\n\n logger.info?.(\n `[CapabilityLoader] '${cap}' installed (${spec.export}${spec.extras ? ' + ' + spec.extras.length + ' extras' : ''})`,\n { environmentId },\n );\n } catch (err: any) {\n const msg = err?.message ?? String(err);\n if (msg.includes('Cannot find module') || msg.includes('ERR_MODULE_NOT_FOUND')) {\n logger.warn?.(\n `[CapabilityLoader] '${cap}' requested but '${spec.pkg}' not installed in host — skipped`,\n { environmentId },\n );\n } else {\n logger.error?.(\n `[CapabilityLoader] '${cap}' load failed: ${msg}`,\n { environmentId },\n );\n }\n }\n }\n\n return installed;\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Platform SSO — shared between the cloud control-plane and the per-project\n * runtime kernels created by {@link ArtifactKernelFactory}.\n *\n * The architecture is \"Airtable-style unified login\": a builder signs in\n * once on `cloud.<root>` and is JIT-provisioned as a `sys_user` on every\n * per-project deployment (`<project>.<root>`) via the OAuth2 / OIDC\n * authorization-code flow.\n *\n * - cloud = OIDC Identity Provider (better-auth's `oauth-provider` plugin\n * — already wired in {@link AuthPlugin} when `oidcProvider:true`)\n * - project = OIDC Relying Party (better-auth's `genericOAuth` plugin —\n * opted in via the `oidcProviders` array on AuthPluginOptions)\n *\n * For the two sides to trust each other without runtime DB calls during\n * the SSO handshake, we use deterministic, derived client credentials:\n *\n * - `client_id` = `'project_' + environmentId`\n * - `client_secret` = HMAC-SHA256(baseSecret, 'oauth-client:' + environmentId)\n * - `redirect_uri` = `https://<hostname>/api/v1/auth/oauth2/callback/<PROVIDER_ID>`\n *\n * Both cloud and project containers share the same `OS_AUTH_SECRET` (or\n * `AUTH_SECRET`) — that's the only piece of state required for the\n * project-side runtime to derive the right secret without a control-plane\n * lookup. The cloud-side row in `sys_oauth_application` is a one-time\n * write per project and is upserted in two places:\n *\n * 1. {@link seedPlatformSsoClient} — called from the project-provisioning\n * flow in `http-dispatcher.ts` right after the `sys_environment` row is\n * inserted, so brand-new projects can SSO from the very first request.\n * 2. {@link backfillPlatformSsoClients} — registered as a boot-time\n * plugin in `control-plane-preset.ts` to retro-fit any pre-existing\n * projects that were created before this code shipped.\n */\n\nimport { createHmac, createHash } from 'node:crypto';\n\n/**\n * Provider id used in better-auth's `genericOAuth` and as part of the\n * callback URL: `/api/v1/auth/oauth2/callback/<PROVIDER_ID>`. Keep stable —\n * changing it invalidates every registered redirect_uri.\n */\nexport const PLATFORM_SSO_PROVIDER_ID = 'objectstack-cloud';\n\n/**\n * Derive the per-project OAuth client_id used in `sys_oauth_application`\n * (cloud side) and {@link genericOAuth} config (project side).\n */\nexport function derivePlatformSsoClientId(environmentId: string): string {\n return `project_${environmentId}`;\n}\n\n/**\n * Derive the per-project OAuth client_secret deterministically from the\n * shared master secret. HMAC-SHA256(baseSecret, 'oauth-client:' + environmentId)\n * yields a 64-char hex string that is:\n * - stable across container cold-starts (no DB lookup needed)\n * - independent per project (compromising one does not compromise others)\n * - rotatable via OS_AUTH_SECRET rotation (invalidates all SSO clients)\n *\n * This is the **plaintext** value the RP must present at the token endpoint.\n * The cloud-side `sys_oauth_application.client_secret` column instead stores\n * {@link hashPlatformSsoClientSecret}(plaintext) — better-auth's oauth-provider\n * defaults to `storeClientSecret: 'hashed'` (SHA-256 + base64url) when the JWT\n * plugin is enabled, and looks up the row by hashing the presented secret.\n */\nexport function derivePlatformSsoClientSecret(baseSecret: string, environmentId: string): string {\n return createHmac('sha256', baseSecret).update(`oauth-client:${environmentId}`).digest('hex');\n}\n\n/**\n * Hash the plaintext client_secret the same way `@better-auth/oauth-provider`'s\n * `defaultHasher` does it: SHA-256 → base64url (no padding). This MUST match\n * exactly or the token endpoint returns `invalid_client / invalid client_secret`\n * even though the row is present.\n *\n * Reference: `node_modules/@better-auth/oauth-provider/dist/utils-*.mjs` →\n * `const defaultHasher = async (value) => base64Url.encode(SHA-256(value))`\n */\nexport function hashPlatformSsoClientSecret(plaintext: string): string {\n return createHash('sha256').update(plaintext)\n .digest('base64')\n .replace(/=+$/, '')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_');\n}\n\n/**\n * Build the redirect_uri better-auth's `genericOAuth` plugin will use\n * when the project kernel mounts the provider with id\n * {@link PLATFORM_SSO_PROVIDER_ID}. MUST be one of the URIs registered\n * on the cloud-side oauth client or the authorization server will reject\n * the callback with `invalid_request`.\n */\nexport function buildPlatformSsoRedirectUri(hostname: string, basePath: string = '/api/v1/auth'): string {\n let host: string;\n if (hostname.startsWith('http://') || hostname.startsWith('https://')) {\n host = hostname;\n } else if (/(\\.|^)localhost(:\\d+)?$/i.test(hostname)) {\n // Local dev: localhost subdomains run on plain http with a custom\n // port. When the caller passes only a hostname (no scheme/port),\n // append the configured runtime port so the OAuth redirect_uri\n // matches what the browser can actually reach. We read\n // OS_RUNTIME_PORT (NOT PORT) because both the cloud control plane\n // and the runtime container call this function — only the runtime\n // port is meaningful for the callback.\n const port = (process.env.OS_RUNTIME_PORT ?? '').trim();\n const hostWithPort = /:\\d+$/.test(hostname) || !port ? hostname : `${hostname}:${port}`;\n host = `http://${hostWithPort}`;\n } else {\n host = `https://${hostname}`;\n }\n const trimmed = host.replace(/\\/+$/, '');\n const path = basePath.replace(/\\/+$/, '');\n return `${trimmed}${path}/oauth2/callback/${PLATFORM_SSO_PROVIDER_ID}`;\n}\n\nexport interface SeedPlatformSsoClientOptions {\n /**\n * Cloud control-plane ObjectQL engine. Must expose `find(object, query)`,\n * `insert(object, data)`, and `update(object, data, {where})`. Both the\n * `apps/cloud` boot kernel (via `kernel.getService('objectql')`) and the\n * dispatcher's local `ql` reference satisfy this shape.\n */\n ql: {\n find: (object: string, query: any, opts?: any) => Promise<any>;\n insert: (object: string, data: any, opts?: any) => Promise<any>;\n update: (object: string, data: any, where: any, opts?: any) => Promise<any>;\n };\n /** Project id (also used to derive client_id + client_secret). */\n environmentId: string;\n /**\n * Project hostname (e.g. `acme-crm.objectos.ai`). Optional — projects\n * may be created before a hostname is assigned, in which case no\n * redirect_uri is registered yet and the row is upserted with an\n * empty `redirect_uris` array. Calling this function again once the\n * hostname is known will merge the new URI in.\n */\n hostname?: string | null;\n /** Master secret shared between cloud and project containers. */\n baseSecret: string;\n /** Optional logger for diagnostics. */\n logger?: { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n /** When true, rethrow insert/update errors instead of swallowing them.\n * Backfill uses this to surface real failures via the admin endpoint. */\n throwOnError?: boolean;\n}\n\n/**\n * Idempotently upsert a `sys_oauth_application` row for the given project.\n * Re-running with the same `environmentId` is a no-op (the deterministic\n * `client_id` is uniquely indexed and the secret derivation is stable).\n * Re-running with a new `hostname` adds the new redirect_uri to the\n * existing row's JSON array.\n */\nexport async function seedPlatformSsoClient(opts: SeedPlatformSsoClientOptions): Promise<void> {\n const { ql, environmentId, hostname, baseSecret, logger, throwOnError } = opts;\n if (!baseSecret) {\n logger?.warn?.('[platform-sso] OS_AUTH_SECRET not set — skipping client seed', { environmentId });\n return;\n }\n const clientId = derivePlatformSsoClientId(environmentId);\n const clientSecretPlaintext = derivePlatformSsoClientSecret(baseSecret, environmentId);\n const clientSecretStored = hashPlatformSsoClientSecret(clientSecretPlaintext);\n const desiredRedirect = hostname ? buildPlatformSsoRedirectUri(hostname) : null;\n\n let existing: any = null;\n try {\n const rows = await ql.find('sys_oauth_application', {\n where: { client_id: clientId },\n limit: 1,\n }, { context: { isSystem: true } });\n const list = Array.isArray(rows) ? rows : Array.isArray((rows as any)?.records) ? (rows as any).records : [];\n existing = list[0] ?? null;\n } catch (err) {\n // Table may not exist yet (control-plane not yet migrated). Treat\n // as a no-op rather than crashing the project-create flow.\n logger?.warn?.('[platform-sso] sys_oauth_application read failed — skipping seed', {\n environmentId,\n error: (err as Error)?.message,\n });\n return;\n }\n\n const nowIso = new Date().toISOString();\n if (!existing) {\n const redirects = desiredRedirect ? [desiredRedirect] : [];\n try {\n await ql.insert('sys_oauth_application', {\n id: `oauthc_${environmentId}`,\n name: `Project ${environmentId}`,\n client_id: clientId,\n client_secret: clientSecretStored,\n type: 'web',\n redirect_uris: JSON.stringify(redirects),\n grant_types: JSON.stringify(['authorization_code', 'refresh_token']),\n response_types: JSON.stringify(['code']),\n scopes: JSON.stringify(['openid', 'email', 'profile']),\n token_endpoint_auth_method: 'client_secret_basic',\n require_pkce: false,\n skip_consent: true,\n disabled: false,\n subject_type: 'public',\n created_at: nowIso,\n updated_at: nowIso,\n }, { context: { isSystem: true } });\n logger?.info?.('[platform-sso] sys_oauth_application row created', { environmentId, clientId });\n } catch (err) {\n // Unique-index conflict implies a parallel writer raced us; treat\n // as success. Other errors are logged but non-fatal so they\n // don't poison the project-create response.\n logger?.warn?.('[platform-sso] sys_oauth_application create failed', {\n environmentId,\n error: (err as Error)?.message,\n });\n if (throwOnError) throw err;\n }\n return;\n }\n\n // Row exists — repair it. We always overwrite the canonical fields\n // (client_secret, grant_types, response_types, scopes, token_endpoint_auth_method,\n // require_pkce, skip_consent, subject_type, type, disabled) because older code\n // paths may have written rows with missing or wrong-shape values, and\n // re-running the seed should converge to the known-good shape.\n // For redirect_uris we MERGE — re-provisioning a project under an\n // additional hostname should add the new URI without dropping the old one.\n let currentRedirects: string[] = [];\n try {\n const raw = existing.redirect_uris;\n const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;\n if (Array.isArray(parsed)) currentRedirects = parsed.filter((s): s is string => typeof s === 'string');\n } catch { /* malformed JSON — treat as empty */ }\n const mergedRedirects = desiredRedirect && !currentRedirects.includes(desiredRedirect)\n ? [...currentRedirects, desiredRedirect]\n : currentRedirects;\n\n const repairPatch: Record<string, any> = {\n name: existing.name || `Project ${environmentId}`,\n client_secret: clientSecretStored,\n type: existing.type || 'web',\n redirect_uris: JSON.stringify(mergedRedirects),\n grant_types: JSON.stringify(['authorization_code', 'refresh_token']),\n response_types: JSON.stringify(['code']),\n scopes: JSON.stringify(['openid', 'email', 'profile']),\n token_endpoint_auth_method: 'client_secret_basic',\n require_pkce: false,\n skip_consent: true,\n disabled: false,\n subject_type: 'public',\n updated_at: nowIso,\n };\n try {\n await ql.update(\n 'sys_oauth_application',\n repairPatch,\n { where: { id: existing.id } },\n { context: { isSystem: true } },\n );\n logger?.info?.('[platform-sso] sys_oauth_application repaired', {\n environmentId,\n clientId,\n redirect_uris: mergedRedirects,\n });\n } catch (err) {\n logger?.warn?.('[platform-sso] sys_oauth_application repair failed', {\n environmentId,\n error: (err as Error)?.message,\n });\n if (throwOnError) throw err;\n }\n}\n\nexport interface BackfillPlatformSsoClientsOptions {\n ql: SeedPlatformSsoClientOptions['ql'];\n baseSecret: string;\n logger?: { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n /** Hard cap on rows scanned (default: 1000). */\n limit?: number;\n}\n\n/**\n * Scan `sys_environment` and ensure every active project has a corresponding\n * `sys_oauth_application` row. Intended to run once at cloud boot — the\n * happy path is dominated by the project-create hook\n * ({@link seedPlatformSsoClient}); the backfill exists so projects\n * created before this feature shipped also get SSO support without an\n * out-of-band migration.\n */\nexport async function backfillPlatformSsoClients(opts: BackfillPlatformSsoClientsOptions): Promise<{\n scanned: number;\n seeded: number;\n alreadyExisted: number;\n failures: Array<{ environmentId: string; error: string }>;\n}> {\n const { ql, baseSecret, logger, limit = 1000 } = opts;\n if (!baseSecret) {\n logger?.warn?.('[platform-sso] backfill skipped — OS_AUTH_SECRET not set');\n return { scanned: 0, seeded: 0, alreadyExisted: 0, failures: [] };\n }\n let projects: any[] = [];\n try {\n const rows = await ql.find('sys_environment', {\n limit,\n fields: ['id', 'hostname', 'status'],\n }, { context: { isSystem: true } });\n projects = Array.isArray(rows) ? rows : Array.isArray((rows as any)?.records) ? (rows as any).records : [];\n } catch (err) {\n logger?.warn?.('[platform-sso] backfill: sys_environment read failed', {\n error: (err as Error)?.message,\n });\n return { scanned: 0, seeded: 0, alreadyExisted: 0, failures: [{ environmentId: '<scan>', error: (err as Error)?.message ?? String(err) }] };\n }\n let seeded = 0;\n let alreadyExisted = 0;\n const failures: Array<{ environmentId: string; error: string }> = [];\n for (const p of projects) {\n if (!p?.id) continue;\n const before = await (async () => {\n try {\n const r = await ql.find('sys_oauth_application', {\n where: { client_id: derivePlatformSsoClientId(p.id) },\n limit: 1,\n }, { context: { isSystem: true } });\n const list = Array.isArray(r) ? r : Array.isArray((r as any)?.records) ? (r as any).records : [];\n return list[0] ?? null;\n } catch { return null; }\n })();\n try {\n await seedPlatformSsoClient({ ql, environmentId: p.id, hostname: p.hostname, baseSecret, logger, throwOnError: true });\n if (before) alreadyExisted++;\n else {\n // Verify the row is actually readable post-insert.\n const after = await (async () => {\n try {\n const r = await ql.find('sys_oauth_application', {\n where: { client_id: derivePlatformSsoClientId(p.id) },\n limit: 1,\n }, { context: { isSystem: true } });\n const list = Array.isArray(r) ? r : Array.isArray((r as any)?.records) ? (r as any).records : [];\n return list[0] ?? null;\n } catch (err) { return { _readErr: (err as Error)?.message }; }\n })();\n if (after && !(after as any)._readErr) seeded++;\n else failures.push({ environmentId: p.id, error: `post-insert read returned ${after ? JSON.stringify(after) : 'null'}` });\n }\n } catch (err: any) {\n failures.push({ environmentId: p.id, error: err?.message ?? String(err) });\n }\n }\n logger?.info?.('[platform-sso] backfill complete', { scanned: projects.length, seeded, alreadyExisted, failures: failures.length });\n return { scanned: projects.length, seeded, alreadyExisted, failures };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * AuthProxyPlugin\n *\n * Mounts a single `/api/v1/auth/*` wildcard route on the host's Hono server\n * that forwards every request to the per-project `AuthManager` registered\n * by `ArtifactKernelFactory`.\n *\n * Why a dedicated plugin: AuthPlugin (better-auth) registers its routes by\n * grabbing the host's `http-server` service from its own `PluginContext`.\n * In objectos runtime mode AuthPlugin lives on a per-project kernel — it\n * has no access to the host's HTTP server, so its `kernel:ready` route\n * registration is a no-op. The dispatcher plugin's wildcard registration\n * via `IHttpServer.post('/auth/*', …)` proved unreliable in practice,\n * so this plugin uses Hono's raw app directly (same path AuthPlugin took\n * historically) which is rock solid.\n *\n * Routing:\n * 1. Resolve the project from the request hostname via `env-registry`.\n * 2. Acquire the project's kernel via `kernel-manager`.\n * 3. Look up the `auth` service on that kernel — this is the better-auth\n * handler injected by `ArtifactKernelFactory`.\n * 4. Build a Web `Request` using the project's canonical baseUrl and\n * hand it to the better-auth handler.\n * 5. Stream the response back through Hono.\n */\n\nimport type { Plugin, PluginContext } from '@objectstack/core';\nimport { createHmac, randomUUID } from 'node:crypto';\nimport type { KernelManager } from './kernel-manager.js';\nimport type { EnvironmentDriverRegistry } from './environment-registry.js';\n\nconst AUTH_PREFIX = '/api/v1/auth';\n\n/**\n * HMAC-SHA256 + base64 + percent-encode the resulting `value.signature`\n * payload — replicates `serializeSignedCookie` from `better-call` so the\n * env's better-auth `getSignedCookie` validator accepts the cookie we\n * write here (without pulling better-call into runtime's deps).\n */\nfunction signSessionCookieValue(rawToken: string, secret: string): string {\n const signature = createHmac('sha256', secret).update(rawToken).digest('base64');\n return encodeURIComponent(`${rawToken}.${signature}`);\n}\n\n/**\n * Serialize a Set-Cookie header value matching better-auth's session-cookie\n * attributes. Attributes come from `authCookies.sessionToken.attributes`.\n */\nfunction buildSetCookieHeader(\n name: string,\n encodedValue: string,\n attrs: Record<string, any> | undefined,\n maxAgeSec: number,\n): string {\n const parts: string[] = [`${name}=${encodedValue}`];\n const a = attrs ?? {};\n if (a.path) parts.push(`Path=${a.path}`); else parts.push('Path=/');\n if (Number.isFinite(maxAgeSec) && maxAgeSec > 0) parts.push(`Max-Age=${Math.floor(maxAgeSec)}`);\n if (a.domain) parts.push(`Domain=${a.domain}`);\n if (a.sameSite) {\n const ss = String(a.sameSite);\n parts.push(`SameSite=${ss.charAt(0).toUpperCase() + ss.slice(1)}`);\n } else {\n parts.push('SameSite=Lax');\n }\n if (a.secure) parts.push('Secure');\n if (a.httpOnly !== false) parts.push('HttpOnly');\n if (a.partitioned) parts.push('Partitioned');\n return parts.join('; ');\n}\n\n// AuthCapableManager interface removed — unused (pickHandler uses duck typing on `any`).\n\nfunction pickHandler(svc: any): ((req: Request) => Promise<Response>) | undefined {\n if (!svc) return undefined;\n // AuthManager exposes handleRequest(req) — preferred entry point.\n if (typeof svc.handleRequest === 'function') return svc.handleRequest.bind(svc);\n if (typeof svc.handler === 'function') return svc.handler.bind(svc);\n if (svc.api && typeof svc.api.handler === 'function') return svc.api.handler.bind(svc.api);\n // AuthManager keeps the better-auth instance under `auth`.\n if (svc.auth && typeof svc.auth.handler === 'function') return svc.auth.handler.bind(svc.auth);\n return undefined;\n}\n\nasync function resolveAuthHandler(svc: any): Promise<((req: Request) => Promise<Response>) | undefined> {\n const direct = pickHandler(svc);\n if (direct) return direct;\n if (typeof svc?.getApi === 'function') {\n try {\n const api = await svc.getApi();\n return pickHandler(api) ?? pickHandler({ api });\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\nexport class AuthProxyPlugin implements Plugin {\n readonly name = 'com.objectstack.runtime.auth-proxy';\n readonly version = '1.0.0';\n\n init = async (_ctx: PluginContext): Promise<void> => {\n // No services registered — pure HTTP wiring during start().\n };\n\n start = async (ctx: PluginContext): Promise<void> => {\n // Mount routes on kernel:ready so HonoServerPlugin has finished\n // registering the http-server service. Doing this in start() can\n // race with HonoServerPlugin.init/start ordering.\n ctx.hook('kernel:ready', async () => {\n let httpServer: any;\n try {\n httpServer = ctx.getService('http-server');\n } catch {\n ctx.logger?.warn?.('[AuthProxyPlugin] http-server not available — auth routes not mounted');\n return;\n }\n if (!httpServer || typeof httpServer.getRawApp !== 'function') {\n ctx.logger?.warn?.('[AuthProxyPlugin] http-server missing getRawApp() — auth routes not mounted');\n return;\n }\n\n const rawApp = httpServer.getRawApp();\n const kernelManager = ctx.getService<KernelManager>('kernel-manager');\n const envRegistry = ctx.getService<EnvironmentDriverRegistry>('env-registry');\n\n const handler = async (c: any) => {\n try {\n const url = new URL(c.req.url);\n const host = url.hostname;\n let environmentId: string | undefined;\n try {\n const env = await envRegistry.resolveByHostname(host);\n environmentId = env?.environmentId;\n } catch {\n // ignore\n }\n if (!environmentId) {\n return c.json({ error: 'project_not_found', host }, 404);\n }\n\n const projectKernel = await kernelManager.getOrCreate(environmentId);\n let authSvc: any;\n try {\n authSvc = await (projectKernel as any).getServiceAsync?.('auth');\n } catch { authSvc = undefined; }\n if (!authSvc) {\n try { authSvc = (projectKernel as any).getService?.('auth'); } catch { /* ignore */ }\n }\n\n // Custom non-better-auth endpoints. better-auth has no\n // /config or /bootstrap-status route, so without these\n // short-circuits the request would fall through to the\n // better-auth handler and 404. The Account SPA needs\n // /config to render the \"Continue with ObjectStack\"\n // platform SSO button via SocialSignInButtons.\n const subPath = url.pathname.startsWith(AUTH_PREFIX + '/')\n ? url.pathname.substring(AUTH_PREFIX.length + 1)\n : '';\n if (c.req.method === 'GET' && (subPath === 'config' || subPath === 'bootstrap-status')) {\n if (subPath === 'config') {\n try {\n const config = typeof authSvc?.getPublicConfig === 'function'\n ? authSvc.getPublicConfig()\n : null;\n if (config) {\n return c.json({ success: true, data: config });\n }\n return c.json({ success: false, error: { code: 'auth_config_unavailable', message: 'AuthManager has no getPublicConfig()' } }, 503);\n } catch (e: any) {\n return c.json({ success: false, error: { code: 'auth_config_error', message: String(e?.message ?? e) } }, 500);\n }\n }\n // bootstrap-status\n try {\n // Report the real local owner state. Earlier the\n // proxy short-circuited to `hasOwner: true` as\n // soon as the `objectstack-cloud` SSO provider\n // was wired — the idea being \"identity lives in\n // cloud, JIT-create on first SSO callback\". That\n // forced every project to depend on cloud being\n // reachable for first-time setup AND made the\n // local /setup wizard unreachable. With SSO now\n // demoted to an *optional* federation button,\n // bootstrap status MUST reflect the project's\n // own `sys_user` table so /setup can run when\n // there is genuinely no local owner yet.\n const dataEngine = typeof authSvc?.getDataEngine === 'function'\n ? authSvc.getDataEngine()\n : null;\n if (!dataEngine || typeof dataEngine.count !== 'function') {\n return c.json({ hasOwner: true });\n }\n const count = await dataEngine.count('sys_user', {});\n return c.json({ hasOwner: (count ?? 0) > 0 });\n } catch {\n return c.json({ hasOwner: true });\n }\n }\n\n // ── sso-handoff-issue ─────────────────────────────\n // POST /api/v1/auth/sso-handoff-issue\n //\n // Called server-to-server by cloud's `sso_as_owner`\n // action. Cloud control plane (createCloudStack) has\n // no kernel-manager, so it cannot write into the env's\n // better-auth verification table itself — this endpoint\n // does it locally where the env kernel lives.\n //\n // Auth: `Authorization: Bearer <OS_CLOUD_API_KEY>` must\n // match `process.env.OS_CLOUD_API_KEY` on the env\n // runtime. The same secret is shared between cloud and\n // every env runtime (cloud uses it to verify env →\n // cloud calls; we reuse it for the reverse direction).\n //\n // Body: { email, name?, by?, envId? } — payload that\n // sso-exchange will JSON.parse from the verification\n // value. Returns { token, expiresAt, ttlSec }.\n if (c.req.method === 'POST' && subPath === 'sso-handoff-issue') {\n try {\n const expected = (process.env.OS_CLOUD_API_KEY ?? '').trim();\n if (!expected) {\n return c.json({ error: 'sso_handoff_disabled', reason: 'OS_CLOUD_API_KEY unset on env runtime' }, 503);\n }\n const authz = c.req.header('authorization') ?? '';\n const provided = authz.toLowerCase().startsWith('bearer ')\n ? authz.slice(7).trim()\n : '';\n if (!provided || provided !== expected) {\n return c.json({ error: 'unauthorized' }, 401);\n }\n\n if (typeof authSvc?.getAuthContext !== 'function') {\n return c.json({ error: 'auth_service_unavailable' }, 503);\n }\n const handoffAuthCtx: any = await authSvc.getAuthContext();\n const internal = handoffAuthCtx?.internalAdapter;\n if (!internal?.createVerificationValue) {\n return c.json({ error: 'verification_api_unavailable' }, 503);\n }\n\n let body: any = {};\n try { body = await c.req.json(); } catch { body = {}; }\n const email = String(body?.email ?? '').toLowerCase().trim();\n if (!email) return c.json({ error: 'email_required' }, 400);\n const name = body?.name == null ? null : String(body.name);\n const by = body?.by == null ? 'service' : String(body.by);\n const envIdInBody = body?.envId == null ? null : String(body.envId);\n\n const handoff = randomUUID().replace(/-/g, '')\n + randomUUID().replace(/-/g, '');\n const ttlSec = 60;\n const expiresAt = new Date(Date.now() + ttlSec * 1000);\n await internal.createVerificationValue({\n identifier: `sso-handoff:${handoff}`,\n value: JSON.stringify({ email, name, by, envId: envIdInBody ?? environmentId }),\n expiresAt,\n });\n return c.json({\n token: handoff,\n expiresAt: expiresAt.toISOString(),\n ttlSec,\n });\n } catch (err: any) {\n ctx.logger?.error?.('[AuthProxyPlugin] sso-handoff-issue failed', err instanceof Error ? err : new Error(String(err)));\n return c.json({ error: 'sso_handoff_issue_failed', message: String(err?.message ?? err) }, 500);\n }\n }\n\n // ── sso-exchange ───────────────────────────────────\n // GET /api/v1/auth/sso-exchange?token=<handoff>&next=/\n //\n // Consumes a single-use handoff token previously written\n // by the cloud `sso_as_owner` action (via the\n // sso-handoff-issue endpoint above), finds-or-creates\n // the user in the env by email, mints a fresh better-auth\n // session, sets the signed session cookie and 302s to\n // `next`. If the user has no credential account yet, we\n // redirect to /_console/system/profile?recovery_needed=true\n // so they can configure a disaster-recovery local password.\n if (c.req.method === 'GET' && subPath === 'sso-exchange') {\n try {\n const token = (url.searchParams.get('token') ?? '').trim();\n const nextRaw = url.searchParams.get('next') ?? '/';\n const next = nextRaw.startsWith('/') ? nextRaw : '/';\n if (!token) return c.text('missing token', 400);\n\n if (typeof authSvc?.getAuthContext !== 'function') {\n return c.text('auth service unavailable', 503);\n }\n const authCtx: any = await authSvc.getAuthContext();\n const internal = authCtx?.internalAdapter;\n if (!internal?.consumeVerificationValue) {\n return c.text('verification API unavailable', 503);\n }\n\n const consumed = await internal.consumeVerificationValue(`sso-handoff:${token}`);\n if (!consumed) return c.text('invalid or expired token', 401);\n const expiresAt = consumed?.expiresAt ? new Date(consumed.expiresAt).getTime() : 0;\n if (!expiresAt || expiresAt < Date.now()) return c.text('expired token', 401);\n\n let payload: { email?: string; name?: string | null } = {};\n try { payload = JSON.parse(String(consumed.value)); } catch { payload = { email: String(consumed.value) }; }\n const email = String(payload.email ?? '').toLowerCase().trim();\n if (!email) return c.text('handoff missing email', 400);\n\n const found = await internal.findUserByEmail(email, { includeAccounts: true });\n let userId: string | undefined = found?.user?.id;\n let hasCredentialAccount = (found?.accounts ?? []).some((a: any) => a.providerId === 'credential' && a.password);\n\n if (!userId) {\n const created = await internal.createUser({\n email,\n name: payload.name ?? email,\n emailVerified: true,\n });\n userId = created?.id;\n hasCredentialAccount = false;\n }\n if (!userId) return c.text('failed to provision user', 500);\n\n const session = await internal.createSession(userId, false);\n const rawToken: string | undefined = session?.token;\n const sessionExpiresAt = session?.expiresAt ? new Date(session.expiresAt) : new Date(Date.now() + 7 * 24 * 3600 * 1000);\n if (!rawToken) return c.text('failed to mint session', 500);\n\n const secret: string = authCtx?.secret ?? '';\n if (!secret) return c.text('auth secret unavailable', 503);\n const cookieName: string = authCtx?.authCookies?.sessionToken?.name ?? 'better-auth.session_token';\n const cookieAttrs = authCtx?.authCookies?.sessionToken?.attributes ?? {};\n const encoded = signSessionCookieValue(rawToken, secret);\n const maxAgeSec = Math.max(60, Math.floor((sessionExpiresAt.getTime() - Date.now()) / 1000));\n const setCookie = buildSetCookieHeader(cookieName, encoded, cookieAttrs, maxAgeSec);\n\n const finalNext = hasCredentialAccount\n ? next\n : `/_console/system/profile?recovery_needed=true&next=${encodeURIComponent(next)}`;\n const headers = new Headers();\n headers.set('Set-Cookie', setCookie);\n headers.set('Location', finalNext);\n headers.set('Cache-Control', 'no-store');\n return new Response(null, { status: 302, headers });\n } catch (err: any) {\n ctx.logger?.error?.('[AuthProxyPlugin] sso-exchange failed', err instanceof Error ? err : new Error(String(err)));\n return c.text(`sso-exchange failed: ${err?.message ?? String(err)}`, 500);\n }\n }\n\n const fn = await resolveAuthHandler(authSvc);\n if (!fn) {\n return c.json({ error: 'auth_service_unavailable', environmentId }, 503);\n }\n\n // Forward the original Web Request directly — better-auth\n // accepts a standard `Request` and returns a `Response`.\n const resp = await fn(c.req.raw);\n\n // ── Cookie-leak cleanup ─────────────────────────────────\n // Cloud previously set OS_COOKIE_DOMAIN=.objectos.ai,\n // which made cloud's better-auth session cookies leak\n // into every *.objectos.ai project subdomain and\n // collide with each project's own session_token.\n // The setting has been removed from cloud, but existing\n // browsers still carry the wide-scoped cookies. Append\n // delete instructions (Max-Age=0 + matching Domain) on\n // every per-project auth response so the leaked cookies\n // get drained on the next auth round-trip. Safe to keep\n // long-term: it only deletes cookies on a parent domain\n // that project containers never legitimately set.\n const rootDomain = process.env.OS_ROOT_DOMAIN || '';\n if (rootDomain) {\n const leakyDomain = rootDomain.startsWith('.') ? rootDomain : `.${rootDomain}`;\n const leakyNames = [\n '__Secure-better-auth.session_token',\n 'better-auth.session_token',\n '__Secure-better-auth.state',\n 'better-auth.state',\n '__Secure-better-auth.csrf_token',\n 'better-auth.csrf_token',\n ];\n try {\n for (const n of leakyNames) {\n const isSecure = n.startsWith('__Secure-');\n const attrs = `Max-Age=0; Path=/; Domain=${leakyDomain}; SameSite=Lax${isSecure ? '; Secure' : ''}`;\n (resp as any).headers?.append?.('Set-Cookie', `${n}=; ${attrs}`);\n }\n } catch { /* best-effort cleanup */ }\n }\n\n return resp;\n } catch (err: any) {\n (ctx.logger?.error as any)?.('[AuthProxyPlugin] auth dispatch failed', {\n error: err?.message,\n stack: err?.stack,\n });\n return c.json({\n error: 'auth_dispatch_failed',\n message: err?.message ?? String(err),\n }, 500);\n }\n };\n\n // Mount on every method via Hono's `all`. AuthPlugin previously\n // registered with `rawApp.all('/api/v1/auth/*', handler)` — same\n // shape here.\n if (typeof rawApp.all === 'function') {\n rawApp.all(`${AUTH_PREFIX}/*`, handler);\n } else {\n for (const m of ['get', 'post', 'put', 'delete', 'patch', 'options'] as const) {\n try { rawApp[m]?.(`${AUTH_PREFIX}/*`, handler); } catch { /* best effort */ }\n }\n }\n ctx.logger?.info?.(`[AuthProxyPlugin] auth proxy mounted at ${AUTH_PREFIX}/*`);\n });\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Shared marketplace / cloud control-plane defaults.\n *\n * Centralised so every plugin + the CLI auto-inject path agree on\n * \"what cloud URL do we mean when the user didn't set OS_CLOUD_URL?\".\n * Until we have a competing public hosted cloud, this points at the\n * ObjectStack-operated control plane so a vanilla `objectstack dev` can\n * browse the marketplace out of the box.\n */\nexport const DEFAULT_CLOUD_URL = 'https://cloud.objectos.ai';\n\n/**\n * Resolve the effective control-plane URL from an explicit constructor\n * value, the OS_CLOUD_URL env var, or the default. Returns an empty\n * string when the caller explicitly disabled cloud with\n * `OS_CLOUD_URL=off` / `local` — callers should treat that as\n * \"marketplace unavailable on this runtime\".\n */\nexport function resolveCloudUrl(explicit?: string | null): string {\n const raw = (explicit ?? process.env.OS_CLOUD_URL ?? '').trim();\n const lower = raw.toLowerCase();\n if (lower === 'off' || lower === 'none' || lower === 'local' || lower === 'disabled') {\n return '';\n }\n const picked = raw || DEFAULT_CLOUD_URL;\n return picked.replace(/\\/+$/, '');\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Marketplace public R2 base URL — when set, points at a Cloudflare R2\n * bucket (custom domain or `pub-*.r2.dev`) that serves pre-rendered\n * marketplace browse + install JSON snapshots. The snapshots are\n * written by ObjectStack Cloud (`packages/service-cloud/src/marketplace-snapshot.ts`).\n *\n * Architecture: cloud writes, tenants read directly from R2 → CDN.\n * Marketplace browse + install never touch the cloud control plane,\n * so Cloud cold-start (~12s) is bypassed entirely and the read path\n * scales to CF's edge capacity for free.\n *\n * Default: when OS_MARKETPLACE_PUBLIC_BASE_URL is unset we skip the\n * public fast-path and fall back to the legacy cloud proxy. Once the\n * R2 bucket public domain is wired up in operations, set\n * `OS_MARKETPLACE_PUBLIC_BASE_URL=https://marketplace.objectos.ai`\n * (or your own custom domain) to enable. Set to \"off\" / \"none\" to\n * explicitly disable even if a default is configured.\n *\n * Path layout under the base URL (matches the snapshot writer):\n * <base>/packages.json\n * <base>/packages/{id}.json\n * <base>/packages/{id}/versions/{versionId}/manifest.json\n * <base>/packages/{id}/versions/latest/manifest.json\n *\n * Each JSON file is already in the same `{ success: true, data: ... }`\n * shape as the corresponding cloud API endpoint, so callers can\n * substitute one for the other transparently.\n */\n\n/**\n * Resolve the effective public marketplace base URL. Returns an empty\n * string when the public fast-path is disabled — callers should fall\n * back to fetching via the cloud control plane.\n */\nexport function resolveMarketplacePublicBaseUrl(explicit?: string | null): string {\n const raw = (explicit ?? process.env.OS_MARKETPLACE_PUBLIC_BASE_URL ?? '').trim();\n const lower = raw.toLowerCase();\n if (!raw || lower === 'off' || lower === 'none' || lower === 'disabled' || lower === 'false') {\n return '';\n }\n return raw.replace(/\\/+$/, '');\n}\n\n/**\n * Map an incoming `/api/v1/marketplace/...` API path to a public R2\n * object key (relative — caller prepends the base URL).\n *\n * Returns `null` when the path is not snapshot-backed. Today three\n * paths are covered (list, detail, manifest); anything else (search\n * with non-trivial filters, install actions, etc.) routes via cloud.\n *\n * Query strings are NOT included in the returned key — R2 is static.\n * Callers that need filtering must fetch the full snapshot and filter\n * client-side.\n */\nexport function publicMarketplaceKeyForApiPath(pathname: string): string | null {\n const prefix = '/api/v1/marketplace/packages';\n if (pathname === prefix) return 'packages.json';\n if (!pathname.startsWith(`${prefix}/`)) return null;\n const tail = pathname.slice(prefix.length + 1);\n if (!tail) return null;\n const parts = tail.split('/');\n // /packages/{id}\n if (parts.length === 1) {\n const id = decodeURIComponent(parts[0] ?? '');\n if (!id) return null;\n return `packages/${encodeURIComponent(id)}.json`;\n }\n // /packages/{id}/versions/{versionId}/manifest\n if (parts.length === 4 && parts[1] === 'versions' && parts[3] === 'manifest') {\n const id = decodeURIComponent(parts[0] ?? '');\n const versionId = decodeURIComponent(parts[2] ?? '');\n if (!id || !versionId) return null;\n return `packages/${encodeURIComponent(id)}/versions/${encodeURIComponent(versionId)}/manifest.json`;\n }\n return null;\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * MarketplaceProxyPlugin\n *\n * Forwards `GET /api/v1/marketplace/*` from a tenant ObjectOS runtime to\n * the configured ObjectStack Cloud control-plane URL. The cloud endpoint\n * is unauthenticated and only exposes packages whose owner has opted in\n * to the public catalog (`sys_package.marketplace_listed = true`) — so the\n * proxy passes through without any credentials.\n *\n * Why proxy instead of direct browser → cloud:\n * - The Console SPA stays on the tenant origin, so no CORS configuration\n * is required on the cloud side.\n * - Local-dev `os serve` works regardless of whether the developer's\n * browser has cookies for cloud.objectos.ai.\n * - Adds a single, easily auditable network seam between tenant and\n * control plane.\n *\n * Install is NOT proxied here. Installing a package mutates control-plane\n * state and requires a cloud session + active organization context — the\n * Console SPA performs install by opening the cloud's install dialog in a\n * new tab so the user authenticates against cloud directly. A future\n * iteration may introduce a delegated install token; until then, browse\n * here and install on cloud.\n */\n\nimport type { Plugin, PluginContext } from '@objectstack/core';\nimport { resolveCloudUrl } from './cloud-url.js';\nimport {\n resolveMarketplacePublicBaseUrl,\n publicMarketplaceKeyForApiPath,\n} from './marketplace-public-url.js';\n\nconst MARKETPLACE_PREFIX = '/api/v1/marketplace';\n\n/**\n * In-memory cache for GET/HEAD marketplace responses.\n *\n * Marketplace data changes infrequently (new package versions are\n * audited & published in ~hours, not seconds), so we cache aggressively\n * with conditional revalidation:\n *\n * - listing/search → 30 min hard TTL\n * - package detail → 2 h\n * - version detail /\n * readme / assets → 24 h (versions are immutable once published)\n *\n * After TTL expiry the next request issues an `If-None-Match` /\n * `If-Modified-Since` and, on `304 Not Modified`, simply refreshes the\n * TTL without re-downloading the body.\n *\n * Bypass conditions (always re-fetch, no cache write):\n * - `OS_MARKETPLACE_CACHE=off`\n * - Request header `Cache-Control: no-cache` (the Console SPA's\n * \"Refresh\" button sets this)\n * - Non-2xx upstream responses (avoid pinning transient errors)\n *\n * Every response carries `X-Cache: HIT|REVALIDATED|MISS|BYPASS` to make\n * the layer observable in browser devtools.\n */\nconst DEFAULT_LRU_MAX = 200;\nconst LIST_TTL_MS = 30 * 60 * 1000; // 30 min\nconst PACKAGE_TTL_MS = 2 * 60 * 60 * 1000; // 2 h\nconst VERSION_TTL_MS = 24 * 60 * 60 * 1000; // 24 h\n\ninterface CacheEntry {\n status: number;\n body: ArrayBuffer;\n headers: Record<string, string>;\n etag?: string;\n lastModified?: string;\n expiresAt: number;\n ttlMs: number;\n}\n\nfunction ttlForPath(pathname: string): number {\n // `/api/v1/marketplace/packages/:id/versions/:v(.../...)?` → 24h\n if (/\\/packages\\/[^/]+\\/versions\\//.test(pathname)) return VERSION_TTL_MS;\n // `/api/v1/marketplace/packages/:id(/readme)?` → 2h\n if (/\\/packages\\/[^/]+/.test(pathname)) return PACKAGE_TTL_MS;\n // Listings, search, categories, anything else → 30 min\n return LIST_TTL_MS;\n}\n\nclass LruTtlCache {\n private readonly map = new Map<string, CacheEntry>();\n constructor(private readonly max: number) {}\n\n get(key: string): CacheEntry | undefined {\n const entry = this.map.get(key);\n if (!entry) return undefined;\n // LRU touch: re-insert to move to end.\n this.map.delete(key);\n this.map.set(key, entry);\n return entry;\n }\n\n set(key: string, entry: CacheEntry): void {\n if (this.map.has(key)) this.map.delete(key);\n this.map.set(key, entry);\n while (this.map.size > this.max) {\n const oldest = this.map.keys().next().value;\n if (oldest === undefined) break;\n this.map.delete(oldest);\n }\n }\n\n clear(): void {\n this.map.clear();\n }\n}\n\nexport interface MarketplaceProxyPluginConfig {\n /**\n * Control-plane base URL (e.g. https://cloud.objectos.ai). When the\n * caller passes nothing AND the runtime has no OS_CLOUD_URL set, the\n * plugin falls back to the public ObjectStack-operated cloud so that\n * `objectstack dev` can browse the marketplace out of the box. Set\n * OS_CLOUD_URL=off (or `local`) to opt out — the plugin then mounts\n * a stub that responds 503 and the SPA renders an empty-state\n * explaining marketplace is unavailable in this runtime.\n */\n controlPlaneUrl?: string;\n\n /**\n * Disable the in-memory response cache (testing / debugging).\n * Defaults to the value of `OS_MARKETPLACE_CACHE` (anything in\n * {\"off\",\"false\",\"0\",\"no\"} disables).\n */\n cacheDisabled?: boolean;\n\n /**\n * Override the LRU upper bound. Defaults to 200 entries.\n */\n cacheMaxEntries?: number;\n /**\n * Public R2 base URL for marketplace snapshots. When set, GETs for\n * snapshot-backed paths (`/packages`, `/packages/:id`,\n * `/packages/:id/versions/:vid/manifest`) are fetched directly from\n * R2 (CF edge) — bypassing the cloud control plane entirely.\n * Defaults to the value of OS_MARKETPLACE_PUBLIC_BASE_URL. Empty\n * string disables the public fast-path (legacy cloud-proxy only).\n */\n publicMarketplaceBaseUrl?: string;\n}\n\nexport class MarketplaceProxyPlugin implements Plugin {\n readonly name = 'com.objectstack.runtime.marketplace-proxy';\n readonly version = '1.1.0';\n\n private readonly cloudUrl: string;\n private readonly publicBaseUrl: string;\n private readonly cache: LruTtlCache | null;\n\n constructor(config: MarketplaceProxyPluginConfig = {}) {\n this.cloudUrl = resolveCloudUrl(config.controlPlaneUrl);\n this.publicBaseUrl = resolveMarketplacePublicBaseUrl(config.publicMarketplaceBaseUrl);\n\n const envFlag = (process.env.OS_MARKETPLACE_CACHE ?? '').trim().toLowerCase();\n const envDisabled = ['off', 'false', '0', 'no', 'disable', 'disabled'].includes(envFlag);\n const disabled = config.cacheDisabled ?? envDisabled;\n this.cache = disabled\n ? null\n : new LruTtlCache(Math.max(8, config.cacheMaxEntries ?? DEFAULT_LRU_MAX));\n }\n\n init = async (_ctx: PluginContext): Promise<void> => {\n // No services registered — pure HTTP wiring during start().\n };\n\n start = async (ctx: PluginContext): Promise<void> => {\n ctx.hook('kernel:ready', async () => {\n let httpServer: any;\n try {\n httpServer = ctx.getService('http-server');\n } catch {\n ctx.logger?.warn?.('[MarketplaceProxyPlugin] http-server not available — marketplace routes not mounted');\n return;\n }\n if (!httpServer || typeof httpServer.getRawApp !== 'function') {\n ctx.logger?.warn?.('[MarketplaceProxyPlugin] http-server missing getRawApp() — marketplace routes not mounted');\n return;\n }\n\n const rawApp = httpServer.getRawApp();\n const cloudUrl = this.cloudUrl;\n const publicBaseUrl = this.publicBaseUrl;\n const cache = this.cache;\n\n if (publicBaseUrl) {\n ctx.logger?.info?.(`[MarketplaceProxyPlugin] public R2 fast-path enabled → ${publicBaseUrl}`);\n }\n\n const handler = async (c: any, next: any) => {\n if (!cloudUrl) {\n return c.json({\n success: false,\n error: {\n code: 'marketplace_unavailable',\n message: 'No control-plane URL configured for this runtime (OS_CLOUD_URL).',\n },\n }, 503);\n }\n try {\n const incomingUrl = new URL(c.req.url);\n // Do NOT proxy install-local — those are owned by\n // MarketplaceInstallLocalPlugin and must hit this\n // runtime, never cloud. Pass through so Hono can match\n // the install-local route registered on the same app.\n if (incomingUrl.pathname.startsWith(`${MARKETPLACE_PREFIX}/install-local`)) {\n return next();\n }\n\n const method = String(c.req.method ?? 'GET').toUpperCase();\n\n // ── Public R2 fast-path ─────────────────────────\n // When OS_MARKETPLACE_PUBLIC_BASE_URL is configured,\n // GETs for snapshot-backed paths fetch directly from\n // R2 → CF edge cache. This skips the cloud control\n // plane entirely so marketplace browse + install\n // work even when cloud is asleep or completely down.\n if (publicBaseUrl && (method === 'GET' || method === 'HEAD')) {\n const r2Resp = await tryPublicMarketplaceFetch(\n publicBaseUrl, incomingUrl, method, c.req.header('accept'),\n ctx.logger,\n );\n if (r2Resp) return r2Resp;\n // Fall through on miss / error to the cloud path.\n }\n\n // Preserve the full /api/v1/marketplace/... path on cloud.\n const target = `${cloudUrl}${incomingUrl.pathname}${incomingUrl.search}`;\n\n // Forward only safe, idempotent methods. We intentionally\n // do NOT proxy POST / PUT / DELETE here — those would\n // need credentialled cloud auth which the tenant runtime\n // does not carry.\n if (method !== 'GET' && method !== 'HEAD') {\n return c.json({\n success: false,\n error: {\n code: 'marketplace_method_not_allowed',\n message: `Marketplace proxy only forwards GET/HEAD; install via cloud.`,\n },\n }, 405);\n }\n\n // Cache lookup. Key includes accept-language because\n // cloud may serve locale-specific copy in the future;\n // HEAD shares the cache slot with GET (we just elide the\n // body in the response).\n const accept = c.req.header('accept') ?? 'application/json';\n const acceptLang = c.req.header('accept-language') ?? '';\n const cacheKey = `${incomingUrl.pathname}${incomingUrl.search}|al=${acceptLang}|a=${accept}`;\n const reqCacheCtl = (c.req.header('cache-control') ?? '').toLowerCase();\n const bypass = !cache || reqCacheCtl.includes('no-cache') || reqCacheCtl.includes('no-store');\n const now = Date.now();\n\n if (cache && !bypass) {\n const hit = cache.get(cacheKey);\n if (hit && hit.expiresAt > now) {\n return buildCachedResponse(hit, method, 'HIT');\n }\n if (hit) {\n // TTL expired — try conditional revalidate so we\n // don't pay for the body when nothing changed.\n const revalHeaders: Record<string, string> = {\n 'Accept': accept,\n 'User-Agent': `objectos-marketplace-proxy/${MarketplaceProxyPlugin.prototype.version ?? '1.0.0'}`,\n };\n if (acceptLang) revalHeaders['Accept-Language'] = acceptLang;\n if (hit.etag) revalHeaders['If-None-Match'] = hit.etag;\n if (hit.lastModified) revalHeaders['If-Modified-Since'] = hit.lastModified;\n const revalResp = await fetch(target, { method: 'GET', headers: revalHeaders });\n if (revalResp.status === 304) {\n hit.expiresAt = now + hit.ttlMs;\n // Refresh ETag/Last-Modified if the upstream\n // re-issued them on the 304 (per RFC 7232 §4.1).\n const newEtag = revalResp.headers.get('etag');\n const newLm = revalResp.headers.get('last-modified');\n if (newEtag) hit.etag = newEtag;\n if (newLm) hit.lastModified = newLm;\n cache.set(cacheKey, hit);\n return buildCachedResponse(hit, method, 'REVALIDATED');\n }\n // 200 (or anything else): fall through to the\n // normal fetch+store path below, using the\n // revalidation response we already have in hand.\n return await consumeAndMaybeCache(revalResp, cacheKey, incomingUrl.pathname, method, cache);\n }\n }\n\n // MISS (or BYPASS): origin fetch.\n const reqHeaders: Record<string, string> = {\n // Strip the inbound Host header — fetch will set\n // it to the cloud host. Forward only the\n // identifying headers cloud might log.\n 'Accept': accept,\n 'User-Agent': `objectos-marketplace-proxy/${MarketplaceProxyPlugin.prototype.version ?? '1.0.0'}`,\n };\n if (acceptLang) reqHeaders['Accept-Language'] = acceptLang;\n const resp = await fetch(target, { method: 'GET', headers: reqHeaders });\n\n if (bypass || !cache) {\n // Don't write to cache; just stream back.\n return await passthroughResponse(resp, method, bypass ? 'BYPASS' : 'MISS');\n }\n return await consumeAndMaybeCache(resp, cacheKey, incomingUrl.pathname, method, cache);\n } catch (err: any) {\n const errObj = err instanceof Error ? err : new Error(err?.message ?? String(err));\n ctx.logger?.error?.('[MarketplaceProxyPlugin] proxy failed', errObj);\n return c.json({\n success: false,\n error: {\n code: 'marketplace_proxy_failed',\n message: err?.message ?? String(err),\n },\n }, 502);\n }\n };\n\n if (typeof rawApp.all === 'function') {\n rawApp.all(`${MARKETPLACE_PREFIX}/*`, handler);\n } else {\n for (const m of ['get', 'head'] as const) {\n try { rawApp[m]?.(`${MARKETPLACE_PREFIX}/*`, handler); } catch { /* best effort */ }\n }\n }\n\n ctx.logger?.info?.(`[MarketplaceProxyPlugin] mounted at ${MARKETPLACE_PREFIX}/* → ${cloudUrl || '(unconfigured)'} (cache=${this.cache ? 'on' : 'off'})`);\n });\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public R2 fast-path (module-private)\n// ---------------------------------------------------------------------------\n\n/**\n * Fetch a marketplace API path from the public R2 base URL and return\n * the response shaped exactly like the cloud API endpoint would. The\n * snapshots are already in `{ success: true, data: ... }` shape so for\n * direct lookups we stream bytes verbatim. The list endpoint applies\n * query-string filters (q / category / limit / offset) client-side\n * from the full snapshot.\n *\n * Returns `null` for any of:\n * - path is not snapshot-backed (e.g. featured / categories / etc.)\n * - R2 returned 404 (snapshot not yet generated for this id)\n * - network error fetching from R2\n *\n * On `null`, the caller falls back to the cloud proxy path.\n */\nasync function tryPublicMarketplaceFetch(\n publicBaseUrl: string,\n incomingUrl: URL,\n method: string,\n acceptHeader: string | undefined,\n logger: any,\n): Promise<Response | null> {\n const key = publicMarketplaceKeyForApiPath(incomingUrl.pathname);\n if (!key) return null;\n\n const target = `${publicBaseUrl}/${key}`;\n let resp: Response;\n try {\n resp = await fetch(target, {\n method: 'GET',\n headers: {\n 'Accept': acceptHeader || 'application/json',\n 'User-Agent': `objectos-marketplace-proxy/public-r2`,\n },\n });\n } catch (err: any) {\n logger?.warn?.(`[MarketplaceProxyPlugin] public R2 fetch failed (${target}): ${err?.message ?? err}`);\n return null;\n }\n if (resp.status === 404) return null;\n if (!resp.ok) {\n logger?.warn?.(`[MarketplaceProxyPlugin] public R2 ${target} returned ${resp.status} — falling back to cloud`);\n return null;\n }\n\n // List endpoint: apply optional q/category/limit/offset filters on\n // the full snapshot. Detail + manifest snapshots stream verbatim.\n const isList = key === 'packages.json';\n const hasFilters = isList && (\n incomingUrl.searchParams.has('q') ||\n incomingUrl.searchParams.has('category') ||\n incomingUrl.searchParams.has('limit') ||\n incomingUrl.searchParams.has('offset')\n );\n\n if (!hasFilters) {\n // Verbatim passthrough — preserve cache headers from R2 / CF.\n const headers = new Headers();\n const ct = resp.headers.get('content-type') ?? 'application/json; charset=utf-8';\n headers.set('content-type', ct);\n const cc = resp.headers.get('cache-control');\n if (cc) headers.set('cache-control', cc);\n const etag = resp.headers.get('etag');\n if (etag) headers.set('etag', etag);\n headers.set('x-cache', 'PUBLIC-R2');\n const body = method === 'HEAD' ? null : resp.body;\n return new Response(body, { status: 200, headers });\n }\n\n // Filtered list — parse, filter, re-serialize.\n let snapshot: any;\n try { snapshot = await resp.json(); }\n catch (err: any) {\n logger?.warn?.(`[MarketplaceProxyPlugin] public R2 list snapshot parse failed: ${err?.message ?? err}`);\n return null;\n }\n const items: any[] = Array.isArray(snapshot?.data?.items) ? snapshot.data.items : [];\n\n const q = (incomingUrl.searchParams.get('q') ?? '').trim().toLowerCase();\n const category = (incomingUrl.searchParams.get('category') ?? '').trim();\n const limit = Math.min(Math.max(Number(incomingUrl.searchParams.get('limit') ?? 50), 1), 100);\n const offset = Math.max(Number(incomingUrl.searchParams.get('offset') ?? 0), 0);\n\n let filtered = items;\n if (q) {\n filtered = filtered.filter((r) => {\n const dn = String(r?.display_name ?? '').toLowerCase();\n const mid = String(r?.manifest_id ?? '').toLowerCase();\n return dn.includes(q) || mid.includes(q);\n });\n }\n if (category) {\n filtered = filtered.filter((r) => String(r?.category ?? '') === category);\n }\n const total = filtered.length;\n const page = filtered.slice(offset, offset + limit);\n const body = JSON.stringify({ success: true, data: { items: page, total, limit, offset } });\n\n const headers = new Headers({\n 'content-type': 'application/json; charset=utf-8',\n 'cache-control': 'public, max-age=30',\n 'x-cache': 'PUBLIC-R2-FILTERED',\n });\n return new Response(method === 'HEAD' ? null : body, { status: 200, headers });\n}\n\n// ---------------------------------------------------------------------------\n// Cache helpers (module-private)\n// ---------------------------------------------------------------------------\n\nconst PASSTHROUGH_HEADERS = ['content-type', 'cache-control', 'etag', 'last-modified', 'vary'] as const;\n\nfunction collectHeaders(src: Response): Record<string, string> {\n const out: Record<string, string> = {};\n for (const h of PASSTHROUGH_HEADERS) {\n const v = src.headers.get(h);\n if (v) out[h] = v;\n }\n return out;\n}\n\nfunction buildCachedResponse(entry: CacheEntry, method: string, xCache: 'HIT' | 'REVALIDATED'): Response {\n const headers = new Headers(entry.headers);\n headers.set('X-Cache', xCache);\n // Surface remaining freshness so downstream HTTP caches / devtools\n // can reason about it (clamped at 0).\n const ageSec = Math.max(0, Math.floor((entry.expiresAt - entry.ttlMs - Date.now()) / -1000));\n headers.set('Age', String(Math.max(0, ageSec)));\n const body = method === 'HEAD' ? null : entry.body;\n return new Response(body, { status: entry.status, headers });\n}\n\nasync function passthroughResponse(resp: Response, method: string, xCache: 'MISS' | 'BYPASS'): Promise<Response> {\n const headers = new Headers(collectHeaders(resp));\n headers.set('X-Cache', xCache);\n if (method === 'HEAD') {\n // Drain to release the connection.\n try { await resp.arrayBuffer(); } catch { /* ignore */ }\n return new Response(null, { status: resp.status, headers });\n }\n const body = await resp.arrayBuffer();\n return new Response(body, { status: resp.status, headers });\n}\n\nasync function consumeAndMaybeCache(\n resp: Response,\n key: string,\n pathname: string,\n method: string,\n cache: LruTtlCache,\n): Promise<Response> {\n const body = await resp.arrayBuffer();\n const headers = collectHeaders(resp);\n // Only cache success responses — pinning a 404 / 5xx would just\n // amplify a transient failure.\n if (resp.status >= 200 && resp.status < 300) {\n const ttlMs = ttlForPath(pathname);\n const entry: CacheEntry = {\n status: resp.status,\n body,\n headers,\n etag: resp.headers.get('etag') ?? undefined,\n lastModified: resp.headers.get('last-modified') ?? undefined,\n expiresAt: Date.now() + ttlMs,\n ttlMs,\n };\n cache.set(key, entry);\n }\n const respHeaders = new Headers(headers);\n respHeaders.set('X-Cache', 'MISS');\n const outBody = method === 'HEAD' ? null : body;\n return new Response(outBody, { status: resp.status, headers: respHeaders });\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * RuntimeConfigPlugin\n *\n * Serves `GET /api/v1/runtime/config` (and the legacy alias\n * `GET /api/v1/studio/runtime-config`) from a tenant ObjectOS runtime so\n * the Console / Studio SPA can learn the upstream cloud URL and capability\n * flags **at boot time**, instead of sniffing `window.location.hostname`\n * or reading Vite-time env vars.\n *\n * Response shape (mirrors cloud's `createStudioRuntimeConfigPlugin`):\n *\n * {\n * cloudUrl: string, // base URL of the upstream cloud\n * singleEnvironment: false, // multi-tenant runtime\n * features: {\n * installLocal: boolean, // false here — install-local is owned\n * // by CLI `serve` (single-tenant), not\n * // by createObjectOSStack\n * marketplace: boolean, // true — MarketplaceProxyPlugin mounts\n * // /api/v1/marketplace/*\n * }\n * }\n *\n * Registers its routes on the Hono raw app, parallel to MarketplaceProxy /\n * AuthProxy / MarketplaceInstallLocal plugins.\n */\n\nimport type { Plugin, PluginContext } from '@objectstack/core';\nimport { resolveCloudUrl } from './cloud-url.js';\n\nexport interface RuntimeConfigPluginConfig {\n /**\n * Upstream cloud base URL. Falls back to `resolveCloudUrl()` (reads\n * `OS_CLOUD_URL` / built-in default) when omitted. Pass an explicit\n * empty string to declare \"this runtime IS the cloud\" (same-origin\n * for marketplace + install).\n */\n controlPlaneUrl?: string;\n /** Override the `features.installLocal` flag. Default: false. */\n installLocal?: boolean;\n /**\n * Report this runtime as a single-environment deployment (CLI\n * `objectstack dev` / `os serve`). Defaults to `false` for\n * multi-tenant ObjectOS.\n */\n singleEnvironment?: boolean;\n /**\n * Product name shown in browser title, splash screen, and other\n * client chrome. Operators can override per-deployment (white-label,\n * regional rebrands). Falls back to `OS_PRODUCT_NAME` env var, then\n * to the default `'ObjectOS'`.\n */\n productName?: string;\n /** Short product name (PWA shortName, compact spots). Defaults to productName. */\n productShortName?: string;\n}\n\nexport class RuntimeConfigPlugin implements Plugin {\n readonly name = 'com.objectstack.runtime.runtime-config';\n readonly version = '1.0.0';\n\n private readonly cloudUrl: string;\n private readonly installLocal: boolean;\n private readonly singleEnvironment: boolean;\n private readonly productName: string;\n private readonly productShortName: string;\n\n constructor(config: RuntimeConfigPluginConfig = {}) {\n // An explicit empty string means \"stay on this origin\" — bypass the\n // resolver which would otherwise fall back to the default cloud URL.\n this.cloudUrl = config.controlPlaneUrl === ''\n ? ''\n : (resolveCloudUrl(config.controlPlaneUrl) ?? '');\n this.installLocal = !!config.installLocal;\n this.singleEnvironment = !!config.singleEnvironment;\n const envName = (typeof process !== 'undefined' ? process.env?.OS_PRODUCT_NAME : undefined)?.trim();\n const envShort = (typeof process !== 'undefined' ? process.env?.OS_PRODUCT_SHORT_NAME : undefined)?.trim();\n this.productName = (config.productName ?? envName ?? 'ObjectOS').trim() || 'ObjectOS';\n this.productShortName = (config.productShortName ?? envShort ?? this.productName).trim() || this.productName;\n }\n\n init = async (_ctx: PluginContext): Promise<void> => {};\n\n start = async (ctx: PluginContext): Promise<void> => {\n ctx.hook('kernel:ready', async () => {\n let httpServer: any;\n try {\n httpServer = ctx.getService('http-server');\n } catch {\n ctx.logger?.warn?.('[RuntimeConfigPlugin] http-server not available — runtime/config not mounted');\n return;\n }\n if (!httpServer || typeof httpServer.getRawApp !== 'function') {\n ctx.logger?.warn?.('[RuntimeConfigPlugin] http-server missing getRawApp() — runtime/config not mounted');\n return;\n }\n const rawApp = httpServer.getRawApp();\n\n // The tenant runtime is multi-tenant: one process serves many\n // subdomains, each mapped to one sys_environment row. Telling the\n // SPA *which* environment it is attached to (per-request) lets\n // the App Marketplace skip the env-picker dialog and install\n // directly into \"this\" env — the operator's domain already\n // identifies it.\n //\n // Hostname → env is resolved by the same registry the per-env\n // kernel router uses (env-registry). Falls back to the static\n // payload when the host doesn't map to any env (e.g. a\n // marketing root, a CLI-served single-env runtime, or\n // cloud.objectos.ai which mounts its own static handler).\n const features = {\n installLocal: this.installLocal,\n marketplace: true,\n };\n let envRegistry: any = null;\n try { envRegistry = ctx.getService('env-registry'); } catch { /* not mounted (file/CLI mode) */ }\n\n const handler = async (c: any) => {\n const rawHost = c.req.header('host') ?? '';\n const host = rawHost.split(':')[0].toLowerCase().trim();\n let defaultEnvironmentId: string | undefined;\n let defaultOrgId: string | undefined;\n let resolvedSingleEnv = this.singleEnvironment;\n // EnvironmentDriverRegistry exposes `resolveByHostname()`;\n // older code paths used `resolveHostname()` on the client.\n // Accept either so production runtimes (which register the\n // ArtifactEnvironmentRegistry implementing `resolveByHostname`)\n // don't silently no-op and leave the SPA showing the env\n // picker on per-subdomain pages.\n const resolveFn: ((h: string) => Promise<any>) | null =\n typeof envRegistry?.resolveByHostname === 'function'\n ? envRegistry.resolveByHostname.bind(envRegistry)\n : typeof envRegistry?.resolveHostname === 'function'\n ? envRegistry.resolveHostname.bind(envRegistry)\n : null;\n if (resolveFn && host) {\n try {\n const resolved = await resolveFn(host);\n if (resolved?.environmentId) {\n defaultEnvironmentId = String(resolved.environmentId);\n const orgId = resolved.organizationId ?? resolved.organization_id;\n if (orgId) defaultOrgId = String(orgId);\n // Each subdomain is one environment from the\n // operator's POV: surface as single-environment\n // so the SPA hides multi-env affordances.\n resolvedSingleEnv = true;\n }\n } catch {\n // Resolver failures are non-fatal — fall through\n // to the static payload so /runtime/config never\n // 500s. Worst case the SPA shows its env picker.\n }\n }\n return c.json({\n cloudUrl: this.cloudUrl,\n singleEnvironment: resolvedSingleEnv,\n defaultOrgId,\n defaultEnvironmentId,\n features,\n branding: {\n productName: this.productName,\n productShortName: this.productShortName,\n },\n });\n };\n rawApp.get('/api/v1/runtime/config', handler);\n // Legacy alias for older Studio bundles.\n rawApp.get('/api/v1/studio/runtime-config', handler);\n ctx.logger?.info?.('[RuntimeConfigPlugin] mounted /api/v1/runtime/config', {\n cloudUrl: this.cloudUrl || '(empty)',\n installLocal: this.installLocal,\n perHostEnvResolution: !!envRegistry,\n });\n });\n };\n\n destroy = async (): Promise<void> => {};\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * File-backed ArtifactApiClient.\n *\n * A drop-in replacement for {@link ArtifactApiClient} that reads a\n * single project's compiled artifact from a local JSON file instead of\n * an HTTP control plane. Intended for:\n *\n * - `pnpm dev` workflows where standing up a full `apps/cloud`\n * instance to host one artifact is overkill.\n * - Smoke tests / CI that need a hermetic objectos boot.\n * - Single-tenant self-hosted deployments that ship one artifact\n * baked into the container image.\n *\n * Hostname resolution is the identity function: every host resolves\n * to the same `environmentId`. The runtime config (database URL +\n * driver) is synthesised from the artifact's default datasource,\n * matching what the cloud API would mint for a project whose\n * developer declared an inline datasource in `defineStack()`.\n *\n * Public API mirrors {@link ArtifactApiClient} so callers can swap\n * implementations transparently.\n */\n\nimport { readFile, stat } from 'node:fs/promises';\nimport { resolve as resolvePath } from 'node:path';\nimport type {\n EnvironmentArtifactResponse,\n EnvironmentRuntimeConfig,\n ResolvedHostname,\n} from './artifact-api-client.js';\n\nexport interface FileArtifactApiClientConfig {\n /**\n * Path to a compiled artifact JSON file (`dist/objectstack.json`).\n * Resolved against `process.cwd()` when relative. Defaults to\n * `<cwd>/dist/objectstack.json`.\n */\n artifactPath?: string;\n /**\n * Project id every hostname maps to. Defaults to\n * `process.env.OS_ENVIRONMENT_ID` or `'proj_local'`.\n */\n environmentId?: string;\n /**\n * Organization id surfaced alongside the project. Defaults to\n * `process.env.OS_ORGANIZATION_ID` or `'org_local'`.\n */\n organizationId?: string;\n /**\n * Override runtime config. When unset, the client tries to derive\n * one from the artifact's `datasources` array; if that fails it\n * falls back to a local-file SQLite DB at\n * `<cwd>/.objectstack/data/<environmentId>.db`.\n */\n runtime?: EnvironmentRuntimeConfig;\n /**\n * Reload the artifact on every fetch instead of caching the first\n * read. Useful when iterating on a project's metadata without\n * restarting objectos. Defaults to `true` for dev ergonomics.\n */\n watch?: boolean;\n /** Optional logger. */\n logger?: { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n}\n\nexport class FileArtifactApiClient {\n private readonly artifactPath: string;\n private readonly environmentId: string;\n private readonly organizationId: string;\n private readonly overrideRuntime?: EnvironmentRuntimeConfig;\n private readonly watch: boolean;\n private readonly logger: NonNullable<FileArtifactApiClientConfig['logger']>;\n\n private cached?: { mtimeMs: number; response: EnvironmentArtifactResponse };\n\n constructor(config: FileArtifactApiClientConfig = {}) {\n const cwd = process.cwd();\n this.artifactPath = resolvePath(\n cwd,\n config.artifactPath\n ?? process.env.OS_ARTIFACT_PATH\n ?? 'dist/objectstack.json',\n );\n this.environmentId = config.environmentId\n ?? process.env.OS_ENVIRONMENT_ID\n ?? 'proj_local';\n this.organizationId = config.organizationId\n ?? process.env.OS_ORGANIZATION_ID\n ?? 'org_local';\n this.overrideRuntime = config.runtime;\n this.watch = config.watch ?? true;\n this.logger = config.logger ?? console;\n }\n\n async resolveHostname(_host: string): Promise<ResolvedHostname | null> {\n // Single-project mode: every host maps to the one configured project.\n const runtime = this.overrideRuntime ?? (await this.readRuntimeFromArtifact());\n return {\n environmentId: this.environmentId,\n organizationId: this.organizationId,\n ...(runtime ? { runtime } : {}),\n };\n }\n\n async fetchArtifact(_environmentId: string, _opts?: { commit?: string }): Promise<EnvironmentArtifactResponse | null> {\n return this.loadArtifact();\n }\n\n async lookupProjectByShortId(_shortId: string): Promise<{ environmentId: string; organizationId?: string } | null> {\n return { environmentId: this.environmentId, organizationId: this.organizationId };\n }\n\n async fetchBranchHead(\n _environmentId: string,\n _branchName: string,\n ): Promise<{ commitId: string; publishedAt?: string | null } | null> {\n const artifact = await this.loadArtifact();\n return artifact\n ? { commitId: artifact.commitId ?? 'local', publishedAt: null }\n : null;\n }\n\n invalidate(_environmentId: string): void {\n this.cached = undefined;\n }\n\n clear(): void {\n this.cached = undefined;\n }\n\n private async loadArtifact(): Promise<EnvironmentArtifactResponse | null> {\n try {\n const stats = await stat(this.artifactPath);\n const mtimeMs = stats.mtimeMs;\n if (!this.watch && this.cached) return this.cached.response;\n if (this.cached && this.cached.mtimeMs === mtimeMs) return this.cached.response;\n\n const raw = await readFile(this.artifactPath, 'utf8');\n const parsed = JSON.parse(raw);\n // The compiled JSON may already be a `EnvironmentArtifact` envelope\n // (with a `metadata` block) or a bare bundle. Wrap when needed.\n const isEnvelope = parsed && typeof parsed === 'object'\n && typeof parsed.metadata === 'object'\n && parsed.metadata !== null;\n const metadata = isEnvelope ? parsed.metadata : parsed;\n const runtime = this.overrideRuntime\n ?? (isEnvelope ? parsed.runtime : undefined)\n ?? this.deriveRuntimeFromMetadata(metadata)\n ?? this.defaultLocalSqliteRuntime();\n const response: EnvironmentArtifactResponse = {\n schemaVersion: parsed.schemaVersion ?? '1',\n environmentId: parsed.environmentId ?? this.environmentId,\n commitId: parsed.commitId ?? 'local',\n checksum: parsed.checksum ?? '',\n publishedAt: parsed.publishedAt ?? new Date().toISOString(),\n metadata,\n functions: parsed.functions,\n manifest: parsed.manifest,\n runtime: {\n organizationId: this.organizationId,\n ...runtime,\n },\n } as EnvironmentArtifactResponse;\n this.cached = { mtimeMs, response };\n return response;\n } catch (err: any) {\n this.logger.error?.('[FileArtifactApiClient] failed to load artifact', {\n artifactPath: this.artifactPath,\n error: err?.message ?? err,\n });\n return null;\n }\n }\n\n private async readRuntimeFromArtifact(): Promise<EnvironmentRuntimeConfig | undefined> {\n const artifact = await this.loadArtifact();\n return artifact?.runtime;\n }\n\n private deriveRuntimeFromMetadata(metadata: any): EnvironmentRuntimeConfig | undefined {\n const datasources = metadata?.datasources;\n if (!Array.isArray(datasources) || datasources.length === 0) return undefined;\n const mapping: any[] | undefined = metadata?.datasourceMapping;\n let preferredName: string | undefined;\n if (mapping) {\n const def = mapping.find((m: any) => m?.default === true);\n if (def?.datasource) preferredName = def.datasource;\n }\n const ds = preferredName\n ? datasources.find((d: any) => d?.name === preferredName) ?? datasources[0]\n : datasources[0];\n if (!ds || typeof ds !== 'object') return undefined;\n const config = (ds.config ?? {}) as Record<string, any>;\n const url = config.url ?? config.connectionString ?? config.connection ?? config.filename;\n const driver = ds.driver;\n if (typeof driver !== 'string' || typeof url !== 'string') return undefined;\n return {\n databaseDriver: driver,\n databaseUrl: url,\n databaseAuthToken: typeof config.authToken === 'string' ? config.authToken : undefined,\n };\n }\n\n private defaultLocalSqliteRuntime(): EnvironmentRuntimeConfig {\n const cwd = process.cwd();\n const dbPath = resolvePath(cwd, '.objectstack/data', `${this.environmentId}.db`);\n return {\n databaseDriver: 'sqlite',\n databaseUrl: `file:${dbPath}`,\n };\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * createObjectOSStack\n *\n * ObjectOS pure-runtime stack — no control-plane database, no auth /\n * security / audit / tenant plugins. The host kernel registers:\n *\n * - A minimal engine triplet (ObjectQL + in-memory DriverPlugin +\n * MetadataPlugin) so CLI auto-injected plugins (Setup, Studio,\n * Dispatcher, REST) and the runtime can boot. The host kernel itself\n * never reads or writes business data — every record query is routed\n * to a per-project kernel built from a remote artifact.\n * - The `env-registry` and `kernel-manager` services, so the runtime's\n * HTTP dispatcher can resolve hostnames and dispatch every request\n * to the matching project kernel.\n *\n * Invoked by `createRuntimeStack()` whenever `OS_CLOUD_URL`\n * (or `config.controlPlaneUrl`) is set. The same plugin shape is returned\n * as `createCloudStack()` so host configs can swap stacks transparently.\n */\n\nimport { Plugin, PluginContext } from '@objectstack/core';\nimport type { EnvironmentDriverRegistry } from './environment-registry.js';\nimport { KernelManager } from './kernel-manager.js';\nimport { ArtifactApiClient } from './artifact-api-client.js';\nimport { ArtifactEnvironmentRegistry } from './artifact-environment-registry.js';\nimport { ArtifactKernelFactory } from './artifact-kernel-factory.js';\nimport { AuthProxyPlugin } from './auth-proxy-plugin.js';\nimport { MarketplaceProxyPlugin } from './marketplace-proxy-plugin.js';\nimport { RuntimeConfigPlugin } from './runtime-config-plugin.js';\nimport { FileArtifactApiClient, type FileArtifactApiClientConfig } from './file-artifact-api-client.js';\n\nexport interface ObjectOSStackConfig {\n /**\n * Control-plane base URL (HTTP) or a sentinel of `'file'` for the\n * local file-backed dev mode. Required unless `client` is supplied.\n *\n * - `http(s)://…` — talk to a real ObjectStack Cloud control plane\n * over HTTP and resolve hostnames via its `/cloud/*` API.\n * - `'file'` — load a single project from a local\n * `dist/objectstack.json` (or `fileConfig.artifactPath`). Every\n * request, regardless of hostname, resolves to the same project.\n * Intended for `pnpm dev` / smoke tests where standing up a\n * separate control plane is overkill.\n */\n controlPlaneUrl?: string;\n /** Optional bearer token for the control-plane API. */\n controlPlaneApiKey?: string;\n /**\n * Override the artifact client entirely. When supplied,\n * `controlPlaneUrl` is ignored — useful for tests or custom transports.\n */\n client?: ArtifactApiClient | FileArtifactApiClient;\n /** Config for the file-backed mode (used when `controlPlaneUrl === 'file'`). */\n fileConfig?: FileArtifactApiClientConfig;\n /** KernelManager LRU size. Default: 32. */\n kernelCacheSize?: number;\n /** KernelManager idle TTL (ms). Default: 15 min. */\n kernelTtlMs?: number;\n /** EnvironmentDriverRegistry cache TTL (ms). Default: 5 min. */\n envCacheTtlMs?: number;\n /** Artifact / hostname response cache TTL (ms). Default: 5 min. */\n artifactCacheTtlMs?: number;\n /** API prefix (carried for parity with cloud-stack). Default: /api/v1. */\n apiPrefix?: string;\n}\n\nexport interface ObjectOSStackResult {\n plugins: any[];\n api: { enableProjectScoping: true; projectResolution: 'auto'; requireAuth: true };\n}\n\n/**\n * Lazy-loaded host engine plugins. Mirrors the head of\n * `createControlPlanePlugins()` — ObjectQL + InMemory Driver + Metadata.\n *\n * The host kernel in objectos is a pure routing shell. Per-tenant auth +\n * business data live in per-project kernels (each backed by the project's\n * own Turso/Postgres DB), so there is nothing to persist on the host.\n *\n * AuthPlugin is intentionally NOT injected on the host (CLI's\n * `serve.ts` auto-injection guard skips it when `OS_CLOUD_URL` is set).\n * Identity is owned by `ArtifactKernelFactory` per project so that:\n * - users persist in the project's DB across container cold-starts\n * - cookies are scoped to the project's hostname (no `.<root>`-wide leak)\n * - tokens are signed with a per-project HKDF-derived secret\n */\nasync function createHostEnginePlugins(): Promise<Plugin[]> {\n const { ObjectQLPlugin } = await import('@objectstack/objectql');\n const { DriverPlugin } = await import('../driver-plugin.js');\n const { MetadataPlugin } = await import('@objectstack/metadata');\n const { InMemoryDriver } = await import('@objectstack/driver-memory');\n\n const driver = new InMemoryDriver();\n const driverName = 'memory';\n\n const oqlRef: { ql: any } = { ql: null };\n const objectql: Plugin = {\n name: 'com.objectstack.engine.objectql',\n version: '0.0.0',\n async init(ctx: PluginContext) {\n const plugin = new ObjectQLPlugin();\n (this as any)._inner = plugin;\n if ((plugin as any).init) await (plugin as any).init(ctx);\n // Capture the engine instance AFTER init() — ObjectQLPlugin\n // creates its `ql` lazily inside init(), so reading `plugin.ql`\n // before that returns undefined and breaks the\n // datasource-mapping wiring below.\n oqlRef.ql = (plugin as any).ql ?? plugin;\n },\n async start(ctx: PluginContext) {\n const plugin = (this as any)._inner;\n // Forward start() so ObjectQLPlugin can discover `driver.*`\n // services (registered by DriverPlugin.init) and wire them\n // into the engine via `ql.registerDriver(...)`. Without this\n // the engine has zero drivers at request time, causing\n // `[ObjectQL] No driver available for object '...'` errors.\n if (plugin?.start) await plugin.start(ctx);\n },\n async destroy() {\n const plugin = (this as any)._inner;\n if (plugin?.destroy) await plugin.destroy();\n else if (plugin?.stop) await plugin.stop();\n },\n };\n\n const datasourceMapping: Plugin = {\n name: 'objectos-host-datasource-mapping',\n version: '0.0.0',\n dependencies: ['com.objectstack.engine.objectql'],\n async init() {\n const ql = oqlRef.ql;\n if (ql?.setDatasourceMapping) {\n ql.setDatasourceMapping([\n { default: true, datasource: `com.objectstack.driver.${driverName}` },\n ]);\n }\n },\n };\n\n const driverPlugin = new DriverPlugin(driver as any, driverName);\n\n const metadata = new MetadataPlugin({\n watch: false,\n // The host kernel is a routing shell. It doesn't own metadata —\n // every per-project kernel registers its own.\n registerSystemObjects: false,\n });\n\n return [objectql, datasourceMapping, driverPlugin as unknown as Plugin, metadata as unknown as Plugin];\n}\n\n/**\n * Single host plugin that owns the artifact API client, the env registry,\n * and the kernel manager. Registered as services on the host kernel so\n * downstream plugins (the dispatcher, the REST API plugin) pick them up\n * automatically.\n */\nclass ObjectOSEnvironmentPlugin implements Plugin {\n readonly name = 'com.objectstack.runtime.objectos-environment';\n readonly version = '1.0.0';\n\n private readonly config: ObjectOSStackConfig;\n private kernelManager?: KernelManager;\n private client?: ArtifactApiClient;\n\n constructor(config: ObjectOSStackConfig) {\n this.config = config;\n }\n\n init = async (ctx: PluginContext): Promise<void> => {\n const client: ArtifactApiClient | FileArtifactApiClient = this.config.client\n ?? (this.config.controlPlaneUrl === 'file'\n ? new FileArtifactApiClient({\n ...(this.config.fileConfig ?? {}),\n logger: ctx.logger as any,\n })\n : new ArtifactApiClient({\n controlPlaneUrl: this.config.controlPlaneUrl!,\n apiKey: this.config.controlPlaneApiKey,\n cacheTtlMs: this.config.artifactCacheTtlMs,\n logger: ctx.logger,\n }));\n this.client = client as ArtifactApiClient;\n\n const envRegistry: EnvironmentDriverRegistry = new ArtifactEnvironmentRegistry({\n client: client as ArtifactApiClient,\n cacheTtlMs: this.config.envCacheTtlMs,\n logger: ctx.logger,\n });\n\n const factory = new ArtifactKernelFactory({\n client: client as ArtifactApiClient,\n envRegistry,\n logger: ctx.logger,\n });\n\n const kernelManager = new KernelManager({\n factory,\n maxSize: this.config.kernelCacheSize,\n ttlMs: this.config.kernelTtlMs,\n logger: ctx.logger,\n // Only the HTTP client exposes /freshness; file-mode (CLI dev)\n // has no upstream to probe.\n freshnessProbe: this.config.controlPlaneUrl === 'file'\n ? undefined\n : async (envId, builtAtMs) => {\n const fresh = await (client as ArtifactApiClient).getFreshness(envId);\n if (!fresh) return false; // unknown / unreachable → treat as fresh\n const t = fresh.lastPublishedAt ? Date.parse(fresh.lastPublishedAt) : NaN;\n if (!Number.isFinite(t)) return false;\n if (t <= builtAtMs) return false;\n // Upstream changed since this kernel was built. Drop\n // the artifact cache too so the rebuild sees the new\n // bundle (otherwise we'd happily rebuild from the\n // same 5-minute-cached artifact JSON).\n try { (client as ArtifactApiClient).invalidate(envId); } catch { /* best effort */ }\n return true;\n },\n });\n this.kernelManager = kernelManager;\n\n ctx.registerService('env-registry', envRegistry);\n ctx.registerService('kernel-manager', kernelManager);\n ctx.registerService('artifact-api-client', client);\n\n ctx.logger.info?.('ObjectOSEnvironmentPlugin: registered env-registry + kernel-manager', {\n mode: this.config.controlPlaneUrl === 'file' ? 'file' : 'http',\n controlPlaneUrl: this.config.controlPlaneUrl,\n });\n };\n\n destroy = async (): Promise<void> => {\n try { await this.kernelManager?.evictAll(); } catch { /* best effort */ }\n try { this.client?.clear(); } catch { /* best effort */ }\n };\n}\n\nexport async function createObjectOSStack(config: ObjectOSStackConfig): Promise<ObjectOSStackResult> {\n if (!config.controlPlaneUrl && !config.client) {\n throw new Error('[createObjectOSStack] either controlPlaneUrl or client is required');\n }\n const merged: ObjectOSStackConfig = {\n ...config,\n kernelCacheSize: Number(process.env.OS_KERNEL_CACHE_SIZE ?? config.kernelCacheSize ?? 32),\n kernelTtlMs: Number(process.env.OS_KERNEL_TTL_MS ?? config.kernelTtlMs ?? 15 * 60 * 1000),\n envCacheTtlMs: Number(process.env.OS_ENV_CACHE_TTL_MS ?? config.envCacheTtlMs ?? 5 * 60 * 1000),\n artifactCacheTtlMs: Number(process.env.OS_ARTIFACT_CACHE_TTL_MS ?? config.artifactCacheTtlMs ?? 5 * 60 * 1000),\n };\n\n const enginePlugins = await createHostEnginePlugins();\n\n return {\n plugins: [...enginePlugins, new ObjectOSEnvironmentPlugin(merged), new AuthProxyPlugin(), new MarketplaceProxyPlugin({ controlPlaneUrl: merged.controlPlaneUrl === 'file' ? undefined : merged.controlPlaneUrl }), new RuntimeConfigPlugin({ controlPlaneUrl: merged.controlPlaneUrl === 'file' ? undefined : merged.controlPlaneUrl, installLocal: false })],\n api: {\n enableProjectScoping: true,\n projectResolution: 'auto',\n // ObjectOS is multi-tenant: anonymous /api/v1/data/* must never\n // leak per-project data across organisations. AuthProxyPlugin\n // verifies upstream tokens and populates ctx.userId; requireAuth\n // turns missing userId into 401 at the REST layer before the\n // request reaches the per-project kernel.\n requireAuth: true,\n },\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * MarketplaceInstallLocalPlugin\n *\n * Installs marketplace packages into THIS runtime's kernel as opposed to a\n * remote cloud environment. Conceptually different from cloud install in\n * three important ways:\n *\n * 1. Single target — the local kernel is the only install target; there\n * is no `sys_environment` picker.\n * 2. Manifests are cached on disk — once installed, the package is\n * runnable offline. Cloud is only needed during the install action\n * itself (to fetch the manifest snapshot).\n * 3. Coexists with user-authored apps — the local runtime usually has\n * its own `objectstack.config.ts` declared apps. Install refuses to\n * overwrite a manifest_id that's already registered to avoid silently\n * replacing user code.\n *\n * Endpoints (mounted by `start()` on the `kernel:ready` hook):\n *\n * POST /api/v1/marketplace/install-local\n * body: { packageId: string, versionId?: string } (default: \"latest\")\n * → fetches manifest from cloud, caches to disk, registers via\n * the kernel's `manifest` service. Returns the installed entry.\n *\n * GET /api/v1/marketplace/install-local\n * → lists currently installed marketplace packages\n *\n * DELETE /api/v1/marketplace/install-local/:manifestId\n * → removes the cached manifest. Kernel must be restarted to fully\n * unload — `engine.registerApp` is additive only. We document\n * this in the response message.\n *\n * Persistence layout:\n * <cwd>/.objectstack/installed-packages/<safe-manifest-id>.json\n * Each file: { packageId, versionId, manifestId, version, manifest, installedAt, installedBy }\n *\n * On `kernel:ready`, the plugin scans the directory and re-registers each\n * cached manifest so installs survive process restarts without further\n * cloud round-trips.\n */\n\nimport { existsSync, mkdirSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport type { Plugin, PluginContext } from '@objectstack/core';\nimport { readEnvWithDeprecation } from '@objectstack/types';\nimport { resolveCloudUrl } from './cloud-url.js';\nimport { resolveMarketplacePublicBaseUrl } from './marketplace-public-url.js';\n\nconst ROUTE_BASE = '/api/v1/marketplace/install-local';\nconst DEFAULT_DIR = '.objectstack/installed-packages';\n\nexport interface MarketplaceInstallLocalPluginConfig {\n /** Cloud control-plane base URL. When unset, falls back to OS_CLOUD_URL\n * and then to the public ObjectStack cloud so a fresh `objectstack dev`\n * can install from the marketplace without configuration. Set\n * OS_CLOUD_URL=off to disable (the install endpoint then returns 503). */\n controlPlaneUrl?: string;\n /** Override the on-disk cache directory. Defaults to\n * `<cwd>/.objectstack/installed-packages`. */\n storageDir?: string;\n}\n\ninterface InstalledEntry {\n packageId: string;\n versionId: string;\n manifestId: string;\n version: string;\n manifest: any;\n installedAt: string;\n installedBy: string | null;\n /** Whether the bundled seed datasets have been loaded into the kernel\n * database. True after install (seedNow=true) or an explicit reseed;\n * false after a purge. Persisted so the UI can show \"Add\" vs \"Re-seed\". */\n withSampleData?: boolean;\n}\n\nfunction safeFilename(manifestId: string): string {\n return manifestId.replace(/[^a-zA-Z0-9._-]/g, '_') + '.json';\n}\n\nexport class MarketplaceInstallLocalPlugin implements Plugin {\n readonly name = 'com.objectstack.runtime.marketplace-install-local';\n readonly version = '1.0.0';\n\n private readonly cloudUrl: string;\n private readonly storageDir: string;\n\n constructor(config: MarketplaceInstallLocalPluginConfig = {}) {\n this.cloudUrl = resolveCloudUrl(config.controlPlaneUrl);\n this.storageDir = config.storageDir\n ? resolve(config.storageDir)\n : resolve(process.cwd(), DEFAULT_DIR);\n }\n\n init = async (_ctx: PluginContext): Promise<void> => {\n // No services registered — pure HTTP wiring during start().\n };\n\n start = async (ctx: PluginContext): Promise<void> => {\n ctx.hook('kernel:ready', async () => {\n // 1. Rehydrate previously installed packages so they survive restart.\n await this.rehydrate(ctx);\n\n // 2. Mount HTTP endpoints.\n let httpServer: any;\n try {\n httpServer = ctx.getService('http-server');\n } catch {\n ctx.logger?.warn?.('[MarketplaceInstallLocal] http-server not available — install endpoints not mounted');\n return;\n }\n if (!httpServer || typeof httpServer.getRawApp !== 'function') {\n ctx.logger?.warn?.('[MarketplaceInstallLocal] http-server missing getRawApp() — install endpoints not mounted');\n return;\n }\n const rawApp = httpServer.getRawApp();\n\n const postHandler = async (c: any) => this.handleInstall(c, ctx);\n const getHandler = async (c: any) => this.handleList(c);\n const deleteHandler = async (c: any) => this.handleUninstall(c, ctx);\n\n const reseedHandler = async (c: any) => this.handleReseed(c, ctx);\n const purgeHandler = async (c: any) => this.handlePurge(c, ctx);\n\n if (typeof rawApp.post === 'function') rawApp.post(ROUTE_BASE, postHandler);\n if (typeof rawApp.get === 'function') rawApp.get(ROUTE_BASE, getHandler);\n if (typeof rawApp.delete === 'function') rawApp.delete(`${ROUTE_BASE}/:manifestId`, deleteHandler);\n if (typeof rawApp.post === 'function') {\n rawApp.post(`${ROUTE_BASE}/:manifestId/reseed-sample-data`, reseedHandler);\n rawApp.post(`${ROUTE_BASE}/:manifestId/purge-sample-data`, purgeHandler);\n }\n\n ctx.logger?.info?.(`[MarketplaceInstallLocal] mounted at ${ROUTE_BASE} (storage: ${this.storageDir})`);\n });\n };\n\n /**\n * Re-register every cached manifest with the kernel's manifest service.\n * Safe to call on a kernel that already has the same manifest_id (the\n * underlying ObjectQL registry overwrites by id, but we still warn so\n * a developer can spot the dev-time clash between their config.ts and\n * a marketplace package).\n */\n private rehydrate = async (ctx: PluginContext): Promise<void> => {\n const entries = this.readAll();\n if (entries.length === 0) return;\n\n let manifestService: { register(m: any): void } | null = null;\n try {\n manifestService = ctx.getService('manifest') as any;\n } catch {\n ctx.logger?.warn?.('[MarketplaceInstallLocal] no `manifest` service — rehydrate skipped');\n return;\n }\n\n for (const entry of entries) {\n try {\n manifestService!.register(entry.manifest);\n // Sync schemas so the driver creates tables for the newly-\n // registered objects (idempotent — already-synced tables\n // are no-ops).\n try {\n const ql: any = ctx.getService('objectql');\n if (ql && typeof ql.syncSchemas === 'function') await ql.syncSchemas();\n } catch { /* non-fatal */ }\n // Replay translations + register seed datasets, but don't\n // re-run seeding — existing rows are already in the DB from\n // the original install, and multi-tenant orgs will replay\n // via the security middleware on next sys_organization insert.\n await this.applySideEffects(ctx, entry.manifest, { seedNow: false });\n ctx.logger?.info?.(`[MarketplaceInstallLocal] rehydrated ${entry.manifestId}@${entry.version}`);\n } catch (err: any) {\n ctx.logger?.error?.(`[MarketplaceInstallLocal] rehydrate failed for ${entry.manifestId}`, err instanceof Error ? err : new Error(String(err)));\n }\n }\n };\n\n private handleInstall = async (c: any, ctx: PluginContext): Promise<Response> => {\n const userId = await this.requireAuthenticatedUser(c, ctx);\n if (!userId) {\n return c.json({ success: false, error: { code: 'unauthorized', message: 'Authentication required to install packages.' } }, 401);\n }\n\n let body: any = {};\n try { body = await c.req.json(); } catch { /* empty body */ }\n\n // ── Offline path: an inline manifest was supplied (file import). ──\n // Bypass the cloud-fetch entirely; no OS_CLOUD_URL required.\n const inlineManifest = body?.manifest && typeof body.manifest === 'object' ? body.manifest : null;\n\n let manifest: any;\n let resolvedVersionId: string;\n let version: string;\n let packageId: string;\n\n if (inlineManifest) {\n manifest = inlineManifest;\n packageId = String(manifest.id ?? manifest.name ?? '').trim();\n version = String(manifest.version ?? 'unknown');\n resolvedVersionId = String(body?.versionId ?? version);\n if (!packageId) {\n return c.json({ success: false, error: { code: 'invalid_manifest', message: 'Inline manifest must have an \"id\" or \"name\".' } }, 400);\n }\n } else {\n if (!this.cloudUrl) {\n return c.json({ success: false, error: { code: 'marketplace_unavailable', message: 'OS_CLOUD_URL not configured.' } }, 503);\n }\n packageId = String(body?.packageId ?? '').trim();\n const versionId = String(body?.versionId ?? 'latest').trim() || 'latest';\n if (!packageId) {\n return c.json({ success: false, error: { code: 'bad_request', message: 'packageId is required.' } }, 400);\n }\n\n // 1. Fetch manifest snapshot — prefer public R2 fast-path so\n // install works even when cloud is asleep or down. Fall back\n // to cloud on miss/error.\n let payload: any;\n const publicBase = resolveMarketplacePublicBaseUrl();\n const fetchAttempts: { label: string; url: string }[] = [];\n if (publicBase) {\n fetchAttempts.push({\n label: 'public-r2',\n url: `${publicBase}/packages/${encodeURIComponent(packageId)}/versions/${encodeURIComponent(versionId)}/manifest.json`,\n });\n }\n fetchAttempts.push({\n label: 'cloud',\n url: `${this.cloudUrl}/api/v1/marketplace/packages/${encodeURIComponent(packageId)}/versions/${encodeURIComponent(versionId)}/manifest`,\n });\n\n let lastErrStatus = 0;\n let lastErrText = '';\n for (const attempt of fetchAttempts) {\n try {\n const resp = await fetch(attempt.url, { headers: { 'Accept': 'application/json' } });\n if (!resp.ok) {\n lastErrStatus = resp.status;\n lastErrText = (await resp.text().catch(() => '')).slice(0, 200);\n // 404 from public R2 is not fatal — fall through to cloud.\n if (attempt.label === 'public-r2' && resp.status === 404) {\n ctx.logger?.info?.(`[MarketplaceInstallLocal] public-r2 miss for ${packageId}@${versionId}, falling back to cloud`);\n continue;\n }\n if (attempt.label === 'public-r2' && resp.status >= 500) {\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] public-r2 ${resp.status}, falling back to cloud`);\n continue;\n }\n break; // cloud non-ok → surface error\n }\n payload = await resp.json();\n lastErrStatus = 0;\n break;\n } catch (err: any) {\n if (attempt.label === 'public-r2') {\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] public-r2 fetch error: ${err?.message ?? err}, falling back to cloud`);\n continue;\n }\n return c.json({\n success: false,\n error: { code: 'cloud_fetch_failed', message: err?.message ?? String(err) },\n }, 502);\n }\n }\n if (!payload) {\n return c.json({\n success: false,\n error: { code: 'cloud_fetch_failed', message: `Cloud returned ${lastErrStatus}: ${lastErrText}` },\n }, lastErrStatus === 404 ? 404 : 502);\n }\n\n const data = payload?.data ?? payload;\n manifest = data?.manifest;\n resolvedVersionId = String(data?.version_id ?? versionId);\n version = String(data?.version ?? 'unknown');\n }\n\n const manifestId = String(manifest?.id ?? manifest?.name ?? '');\n if (!manifest || !manifestId) {\n return c.json({ success: false, error: { code: 'invalid_manifest', message: 'Invalid manifest payload.' } }, inlineManifest ? 400 : 502);\n }\n\n // 2. Conflict check — refuse to overwrite user-authored apps\n const conflict = this.findConflict(ctx, manifestId);\n if (conflict === 'user-code') {\n return c.json({\n success: false,\n error: {\n code: 'manifest_conflict',\n message: `manifest_id \"${manifestId}\" is already defined by this runtime's local code. Refusing to overwrite. Uninstall the local definition first.`,\n },\n }, 409);\n }\n\n // 3. Hot-register FIRST so a malformed inline manifest fails the\n // install loudly rather than persisting a broken record that\n // would also fail on every subsequent rehydrate.\n try {\n const manifestService = ctx.getService('manifest') as any;\n manifestService.register(manifest);\n } catch (err: any) {\n // For offline file imports we treat a register failure as a hard\n // failure (don't persist). Cloud installs historically tolerated\n // this (the on-disk record survives a restart), so keep that path\n // lenient for backwards compatibility.\n if (inlineManifest) {\n return c.json({\n success: false,\n error: { code: 'register_failed', message: `Failed to register imported manifest: ${err?.message ?? err}` },\n }, 422);\n }\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] hot-register failed for ${manifestId} (will load on next restart): ${err?.message ?? err}`);\n }\n\n // 4. Persist on disk\n const entry: InstalledEntry = {\n packageId,\n versionId: resolvedVersionId,\n manifestId,\n version,\n manifest,\n installedAt: new Date().toISOString(),\n installedBy: userId,\n withSampleData: false,\n };\n try {\n mkdirSync(this.storageDir, { recursive: true });\n writeFileSync(join(this.storageDir, safeFilename(manifestId)), JSON.stringify(entry, null, 2), 'utf8');\n } catch (err: any) {\n return c.json({\n success: false,\n error: { code: 'storage_failed', message: `Failed to persist manifest: ${err?.message ?? err}` },\n }, 500);\n }\n\n // 4b. Sync schemas to physical tables — registerApp only adds the\n // object definitions to the in-memory registry; the driver\n // must be asked to materialize tables/columns before any seed\n // insert (or user write) succeeds.\n try {\n const ql: any = ctx.getService('objectql');\n if (ql && typeof ql.syncSchemas === 'function') {\n await ql.syncSchemas();\n ctx.logger?.info?.(`[MarketplaceInstallLocal] syncSchemas() ran after registering ${manifestId}`);\n }\n } catch (err: any) {\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] syncSchemas failed for ${manifestId}: ${err?.message ?? err}`);\n }\n\n // 5. Replicate the AppPlugin start-time side-effects that the\n // `manifest` service does NOT do on its own:\n // • load translation bundles into the i18n service\n // • stash seed datasets on the kernel + run them now so the\n // installed app has demo data on first paint.\n const seededSummary = await this.applySideEffects(ctx, manifest, { seedNow: true, c });\n if (seededSummary.seeded.mode === 'inline' && (seededSummary.seeded.inserted ?? 0) + (seededSummary.seeded.updated ?? 0) > 0) {\n entry.withSampleData = true;\n try {\n writeFileSync(join(this.storageDir, safeFilename(manifestId)), JSON.stringify(entry, null, 2), 'utf8');\n } catch { /* non-fatal — entry already on disk */ }\n }\n\n return c.json({\n success: true,\n data: {\n manifestId,\n version,\n versionId: resolvedVersionId,\n installedAt: entry.installedAt,\n hotLoaded: true,\n upgradedFrom: conflict === 'marketplace' ? 'previous-marketplace-version' : null,\n translationsLoaded: seededSummary.translationsLoaded,\n seeded: seededSummary.seeded,\n note: 'App is now available in this runtime. Refresh the console to see it in the app switcher.',\n },\n }, 200);\n };\n\n private handleList = async (c: any): Promise<Response> => {\n const entries = this.readAll();\n return c.json({\n success: true,\n data: {\n items: entries.map(e => ({\n packageId: e.packageId,\n versionId: e.versionId,\n manifestId: e.manifestId,\n version: e.version,\n installedAt: e.installedAt,\n installedBy: e.installedBy,\n withSampleData: e.withSampleData ?? false,\n })),\n total: entries.length,\n storageDir: this.storageDir,\n },\n }, 200);\n };\n\n private handleUninstall = async (c: any, ctx: PluginContext): Promise<Response> => {\n const userId = await this.requireAuthenticatedUser(c, ctx);\n if (!userId) {\n return c.json({ success: false, error: { code: 'unauthorized', message: 'Authentication required.' } }, 401);\n }\n const manifestId = String(c.req.param?.('manifestId') ?? c.req.params?.manifestId ?? '').trim();\n if (!manifestId) {\n return c.json({ success: false, error: { code: 'bad_request', message: 'manifestId path param required.' } }, 400);\n }\n const file = join(this.storageDir, safeFilename(manifestId));\n if (!existsSync(file)) {\n return c.json({ success: false, error: { code: 'not_found', message: `No marketplace install for ${manifestId}.` } }, 404);\n }\n try {\n unlinkSync(file);\n } catch (err: any) {\n return c.json({ success: false, error: { code: 'storage_failed', message: err?.message ?? String(err) } }, 500);\n }\n ctx.logger?.info?.(`[MarketplaceInstallLocal] uninstalled ${manifestId} (cached manifest removed; restart runtime to unload from running kernel)`);\n return c.json({\n success: true,\n data: {\n manifestId,\n note: 'Cached manifest removed. The app remains loaded in the running kernel until the next restart (the kernel API does not support unregistering apps in-place).',\n },\n }, 200);\n };\n\n /**\n * Detect whether `manifestId` is already known to the kernel and classify\n * the source so we can refuse vs upgrade gracefully.\n *\n * 'none' — fresh install\n * 'marketplace' — previously installed by this plugin (allow upgrade)\n * 'user-code' — defined by AppPlugin from objectstack.config.ts\n * (refuse to avoid silently overwriting authored code)\n */\n private findConflict = (ctx: PluginContext, manifestId: string): 'none' | 'marketplace' | 'user-code' => {\n // First check: do we already have a marketplace install file?\n if (existsSync(join(this.storageDir, safeFilename(manifestId)))) {\n return 'marketplace';\n }\n // Then check: is the manifest_id already in the engine's registry?\n try {\n const ql: any = ctx.getService('objectql');\n const packages: any[] = ql?.registry?.getAllPackages?.() ?? [];\n const hit = packages.find((p: any) =>\n (p?.manifest?.id ?? p?.id ?? p?.manifest?.name) === manifestId,\n );\n if (hit) return 'user-code';\n } catch { /* objectql not registered yet — treat as fresh */ }\n return 'none';\n };\n\n /**\n * Pull a userId out of the request's better-auth session, if any.\n * Returns null when there is no signed-in user. v1 does not check\n * admin role — UI gating + the auth requirement is sufficient for\n * dev / single-tenant runtimes. Stricter checks can be layered on\n * via a middleware in cloud-hosted multi-tenant deployments.\n */\n /**\n * POST /api/v1/marketplace/install-local/:manifestId/reseed-sample-data\n *\n * Re-runs SeedLoaderService against the cached manifest's `data` arrays.\n * Idempotent (upsert by id). Useful when:\n * • The user installed an app and skipped sample data\n * • A purge was undone\n * • The user wants a clean baseline back after editing demo rows\n *\n * Multi-tenant: requires an active organization on the session (same\n * rule as install seed path).\n */\n private handleReseed = async (c: any, ctx: PluginContext): Promise<Response> => {\n const userId = await this.requireAuthenticatedUser(c, ctx);\n if (!userId) {\n return c.json({ success: false, error: { code: 'unauthorized', message: 'Authentication required.' } }, 401);\n }\n const manifestId = String(c.req.param?.('manifestId') ?? c.req.params?.manifestId ?? '').trim();\n if (!manifestId) {\n return c.json({ success: false, error: { code: 'bad_request', message: 'manifestId path param required.' } }, 400);\n }\n const file = join(this.storageDir, safeFilename(manifestId));\n if (!existsSync(file)) {\n return c.json({ success: false, error: { code: 'not_found', message: `No marketplace install for ${manifestId}.` } }, 404);\n }\n\n let entry: InstalledEntry;\n try {\n entry = JSON.parse(readFileSync(file, 'utf8'));\n } catch (err: any) {\n return c.json({ success: false, error: { code: 'storage_failed', message: `Failed to read manifest cache: ${err?.message ?? err}` } }, 500);\n }\n\n const summary = await this.applySideEffects(ctx, entry.manifest, { seedNow: true, c });\n if (summary.seeded.mode === 'skipped') {\n return c.json({\n success: false,\n error: {\n code: 'reseed_skipped',\n message: `Reseed did not run: ${summary.seeded.reason ?? 'unknown reason'}`,\n },\n }, 400);\n }\n\n // Persist flag flip\n try {\n entry.withSampleData = true;\n writeFileSync(file, JSON.stringify(entry, null, 2), 'utf8');\n } catch { /* non-fatal */ }\n\n return c.json({\n success: true,\n data: {\n manifestId,\n inserted: summary.seeded.inserted ?? 0,\n updated: summary.seeded.updated ?? 0,\n errors: summary.seeded.errors ?? 0,\n withSampleData: true,\n },\n }, 200);\n };\n\n /**\n * POST /api/v1/marketplace/install-local/:manifestId/purge-sample-data\n *\n * Deletes every record whose id is declared in the cached manifest's\n * seed datasets. Uses the `driver` service directly to bypass ACL /\n * lifecycle hooks (same pattern as cloud purge). User-created records\n * are never touched — only ids declared in the package's bundled\n * datasets are removed. Already-deleted rows count as `skipped`.\n */\n private handlePurge = async (c: any, ctx: PluginContext): Promise<Response> => {\n const userId = await this.requireAuthenticatedUser(c, ctx);\n if (!userId) {\n return c.json({ success: false, error: { code: 'unauthorized', message: 'Authentication required.' } }, 401);\n }\n const manifestId = String(c.req.param?.('manifestId') ?? c.req.params?.manifestId ?? '').trim();\n if (!manifestId) {\n return c.json({ success: false, error: { code: 'bad_request', message: 'manifestId path param required.' } }, 400);\n }\n const file = join(this.storageDir, safeFilename(manifestId));\n if (!existsSync(file)) {\n return c.json({ success: false, error: { code: 'not_found', message: `No marketplace install for ${manifestId}.` } }, 404);\n }\n\n let entry: InstalledEntry;\n try {\n entry = JSON.parse(readFileSync(file, 'utf8'));\n } catch (err: any) {\n return c.json({ success: false, error: { code: 'storage_failed', message: `Failed to read manifest cache: ${err?.message ?? err}` } }, 500);\n }\n\n const datasets = Array.isArray(entry.manifest?.data)\n ? entry.manifest.data.filter((d: any) => d && d.object && Array.isArray(d.records))\n : [];\n\n if (datasets.length === 0) {\n return c.json({\n success: false,\n error: { code: 'nothing_to_purge', message: 'This package declares no seed datasets.' },\n }, 400);\n }\n\n let driver: any;\n try { driver = ctx.getService('driver'); } catch { /* none */ }\n if (!driver || typeof driver.delete !== 'function') {\n return c.json({\n success: false,\n error: { code: 'driver_missing', message: 'driver service unavailable — cannot purge.' },\n }, 500);\n }\n\n let deleted = 0;\n let skipped = 0;\n let errors = 0;\n for (const ds of datasets) {\n const object = String(ds.object);\n for (const rec of ds.records as any[]) {\n const id = rec?.id;\n if (id === undefined || id === null || id === '') { skipped++; continue; }\n try {\n const r = await driver.delete(object, id);\n if (r === false || r === 0 || r?.deleted === 0) skipped++;\n else deleted++;\n } catch (err: any) {\n // Treat \"not found\" as skipped; anything else as error.\n const msg = String(err?.message ?? err);\n if (/not.?found|no row/i.test(msg)) skipped++;\n else { errors++; ctx.logger?.warn?.(`[MarketplaceInstallLocal] purge ${object}#${id}: ${msg}`); }\n }\n }\n }\n\n // Flip flag so UI reflects the empty baseline\n try {\n entry.withSampleData = false;\n writeFileSync(file, JSON.stringify(entry, null, 2), 'utf8');\n } catch { /* non-fatal */ }\n\n ctx.logger?.info?.(`[MarketplaceInstallLocal] purged ${manifestId}: deleted=${deleted} skipped=${skipped} errors=${errors}`);\n return c.json({\n success: true,\n data: { manifestId, deleted, skipped, errors, withSampleData: false },\n }, 200);\n };\n\n /**\n * Replicate the start-time side-effects that AppPlugin runs for\n * statically-declared apps but the `manifest` service does NOT:\n *\n * 1. Load `manifest.translations` (array of `Record<locale, data>`)\n * into the i18n service — auto-creating an in-memory fallback if\n * none is registered, matching AppPlugin's behaviour.\n *\n * 2. Merge `manifest.data` (an array of seed datasets) into the\n * kernel's `seed-datasets` service so SecurityPlugin's per-org\n * replay middleware picks them up on every future\n * sys_organization insert.\n *\n * 3. When `seedNow=true`, also run the seed immediately so the user\n * sees demo data without having to create a new org:\n * • single-tenant: run SeedLoaderService inline (mirrors\n * AppPlugin single-tenant branch)\n * • multi-tenant: invoke `seed-replayer` for the caller's\n * active org (resolved from the request session)\n *\n * Errors are logged but never thrown — install succeeds even if\n * post-register side-effects partially fail (the manifest itself is\n * already registered + cached). Returns a small summary for the\n * response envelope.\n */\n private applySideEffects = async (\n ctx: PluginContext,\n manifest: any,\n opts: { seedNow: boolean; c?: any },\n ): Promise<{ translationsLoaded: number; seeded: { mode: 'inline' | 'replayer' | 'skipped'; inserted?: number; updated?: number; errors?: number; reason?: string } }> => {\n const appId = String(manifest?.id ?? 'unknown');\n let translationsLoaded = 0;\n let seedSummary: any = { mode: 'skipped', reason: 'no-datasets' };\n\n // ── 1. i18n bundles ─────────────────────────────────────────────\n try {\n const bundles: Array<Record<string, unknown>> = [];\n if (Array.isArray(manifest?.translations)) bundles.push(...manifest.translations);\n if (Array.isArray(manifest?.i18n)) bundles.push(...manifest.i18n);\n\n if (bundles.length > 0) {\n let i18nService: any;\n try { i18nService = ctx.getService('i18n'); } catch { /* not registered */ }\n if (!i18nService) {\n try {\n const mod = await import('@objectstack/core');\n const createMemoryI18n = (mod as any).createMemoryI18n;\n if (typeof createMemoryI18n === 'function') {\n i18nService = createMemoryI18n();\n (ctx as any).registerService?.('i18n', i18nService);\n ctx.logger?.info?.(`[MarketplaceInstallLocal] auto-registered in-memory i18n fallback for \"${appId}\"`);\n }\n } catch { /* fallback unavailable */ }\n }\n if (i18nService?.loadTranslations) {\n for (const bundle of bundles) {\n for (const [locale, data] of Object.entries(bundle)) {\n if (data && typeof data === 'object') {\n try {\n i18nService.loadTranslations(locale, data as Record<string, unknown>);\n translationsLoaded++;\n } catch (err: any) {\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] failed to load ${appId} translations for ${locale}: ${err?.message ?? err}`);\n }\n }\n }\n }\n ctx.logger?.info?.(`[MarketplaceInstallLocal] loaded ${translationsLoaded} locale bundle(s) for ${appId}`);\n }\n }\n } catch (err: any) {\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] i18n side-effect failed for ${appId}: ${err?.message ?? err}`);\n }\n\n // ── 2. Seed datasets — merge into kernel service ─────────────────\n const datasets = Array.isArray(manifest?.data)\n ? manifest.data.filter((d: any) => d && d.object && Array.isArray(d.records))\n : [];\n\n if (datasets.length > 0) {\n try {\n const kernel: any = (ctx as any).kernel;\n let existing: any[] = [];\n try {\n const v = kernel?.getService?.('seed-datasets');\n if (Array.isArray(v)) existing = v;\n } catch { /* unset */ }\n const merged = [...existing, ...datasets];\n if (kernel?.registerService) kernel.registerService('seed-datasets', merged);\n else (ctx as any).registerService?.('seed-datasets', merged);\n ctx.logger?.info?.(`[MarketplaceInstallLocal] merged ${datasets.length} seed dataset(s) into kernel (total: ${merged.length})`);\n } catch (err: any) {\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] failed to merge seed-datasets: ${err?.message ?? err}`);\n }\n }\n\n // ── 3. Optional immediate seed ───────────────────────────────────\n // Always seed inline via SeedLoaderService — don't rely on the\n // `seed-replayer` registered by AppPlugin since (a) it isn't\n // registered when the host runtime has no AppPlugin app with\n // seed data, and (b) its closure may use stale datasets. In\n // multi-tenant mode we pass `organizationId` so the loader\n // writes tenant-scoped rows the same way AppPlugin's\n // single-tenant branch + SecurityPlugin's per-org replay do.\n if (opts.seedNow && datasets.length > 0) {\n const multiTenant = String(readEnvWithDeprecation('OS_MULTI_ORG_ENABLED', 'OS_MULTI_TENANT') ?? 'false').toLowerCase() !== 'false';\n try {\n const ql: any = ctx.getService('objectql');\n let metadata: any;\n try { metadata = ctx.getService('metadata'); } catch { /* none */ }\n if (!ql || !metadata) {\n seedSummary = { mode: 'skipped', reason: 'objectql-or-metadata-missing' };\n } else {\n let organizationId: string | undefined;\n if (multiTenant) {\n const resolved = await this.resolveActiveOrgId(opts.c, ctx);\n if (resolved) organizationId = resolved;\n else {\n seedSummary = { mode: 'skipped', reason: 'multi-tenant-no-active-org' };\n ctx.logger?.warn?.('[MarketplaceInstallLocal] multi-tenant: no active org on request — data not seeded');\n }\n }\n if (!multiTenant || organizationId) {\n const [{ SeedLoaderService }, { SeedLoaderRequestSchema }] = await Promise.all([\n import('../seed-loader.js'),\n import('@objectstack/spec/data'),\n ]);\n const seedLoader = new (SeedLoaderService as any)(ql, metadata, ctx.logger);\n const request = (SeedLoaderRequestSchema as any).parse({\n datasets,\n config: {\n defaultMode: 'upsert',\n multiPass: true,\n ...(organizationId ? { organizationId } : {}),\n },\n });\n const result = await seedLoader.load(request);\n seedSummary = {\n mode: 'inline',\n inserted: result.summary.totalInserted,\n updated: result.summary.totalUpdated,\n errors: result.errors.length,\n };\n ctx.logger?.info?.(`[MarketplaceInstallLocal] inline seed for ${appId}${organizationId ? ` (org=${organizationId})` : ''}: inserted=${seedSummary.inserted} updated=${seedSummary.updated} errors=${seedSummary.errors}`);\n }\n }\n } catch (err: any) {\n seedSummary = { mode: 'skipped', reason: `seed-error: ${err?.message ?? err}` };\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] seed run failed for ${appId}: ${err?.message ?? err}`);\n }\n }\n\n return { translationsLoaded, seeded: seedSummary };\n };\n\n /**\n * Best-effort active-org resolution. Reads the better-auth session\n * (same path as requireAuthenticatedUser) and returns\n * `session.activeOrganizationId`, falling back to the user's first\n * org membership.\n */\n private resolveActiveOrgId = async (c: any, ctx: PluginContext): Promise<string | null> => {\n if (!c?.req?.raw?.headers) return null;\n try {\n const authService: any = ctx.getService('auth');\n let api: any = authService?.api;\n if (!api && typeof authService?.getApi === 'function') api = await authService.getApi();\n if (!api?.getSession) return null;\n const session = await api.getSession({ headers: c.req.raw.headers });\n const direct = session?.session?.activeOrganizationId ?? session?.activeOrganizationId ?? null;\n if (direct) return String(direct);\n // Fall back to the user's first membership row.\n const userId = session?.user?.id;\n if (!userId) return null;\n try {\n const ql: any = ctx.getService('objectql');\n if (ql?.find) {\n const rows = await ql.find('sys_organization_member', { where: { user_id: userId }, limit: 1, context: { isSystem: true } } as any);\n const row = Array.isArray(rows) ? rows[0] : (rows?.items?.[0] ?? null);\n return row?.organization_id ? String(row.organization_id) : null;\n }\n } catch { /* ignore */ }\n } catch { /* ignore */ }\n return null;\n };\n\n private requireAuthenticatedUser = async (c: any, ctx: PluginContext): Promise<string | null> => {\n try {\n // Mirror `hono-plugin.ts` resolveCtx: pull the better-auth `api`\n // off the auth service and call `getSession({ headers })`. The\n // earlier guess `c.get('auth').session` is wrong — AuthPlugin\n // does not pre-populate the Hono context.\n const authService: any = ctx.getService('auth');\n let api: any = authService?.api;\n if (!api && typeof authService?.getApi === 'function') {\n api = await authService.getApi();\n }\n if (api?.getSession && c?.req?.raw?.headers) {\n const session = await api.getSession({ headers: c.req.raw.headers });\n const userId = session?.user?.id ?? null;\n if (userId) return String(userId);\n }\n } catch { /* ignore — fall through */ }\n // Header fallback for cases where auth is disabled (e.g. test stubs)\n const xUserId = c?.req?.header?.('x-user-id');\n if (xUserId) return String(xUserId);\n return null;\n };\n\n private readAll = (): InstalledEntry[] => {\n if (!existsSync(this.storageDir)) return [];\n const out: InstalledEntry[] = [];\n for (const name of readdirSync(this.storageDir)) {\n if (!name.endsWith('.json')) continue;\n try {\n const raw = readFileSync(join(this.storageDir, name), 'utf8');\n out.push(JSON.parse(raw));\n } catch { /* skip corrupt files */ }\n }\n return out;\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * # Hook & Action Body Sandbox\n *\n * Pluggable execution engine for L2 `ScriptBody` payloads coming from\n * `@objectstack/spec/data` `HookBodySchema`.\n *\n * ## Engine choice — quickjs-emscripten\n *\n * Two candidates were evaluated:\n *\n * | Property | isolated-vm | quickjs-emscripten |\n * |-------------------------|----------------------------|---------------------------|\n * | True isolation | ✅ V8 isolate | ✅ separate JS heap |\n * | Memory limit enforced | ✅ hard cap | ⚠️ soft (engine-level) |\n * | CPU timeout enforced | ✅ hard kill | ✅ interrupt handler |\n * | Native dependency | ❌ requires N-API build | ✅ pure WASM |\n * | Edge runtime support | ❌ Cloudflare/Vercel ban | ✅ runs on every JS host |\n * | Cold-start cost | ~50ms (native init) | ~100ms (WASM init) |\n * | Per-invocation overhead | very low | low–medium |\n *\n * **Decision:** `quickjs-emscripten`.\n *\n * The single biggest constraint for ObjectStack is that `objectos` ships as a\n * pure-JS runtime so it can run on serverless edges, Cloudflare Workers,\n * Vercel Edge, Deno Deploy, plus traditional Node servers. `isolated-vm`\n * disqualifies us from every edge target because of its N-API dependency.\n * The performance penalty of QuickJS for short hook/action bodies (typically\n * <1 ms of script logic) is dominated by `ctx.api` round-trips anyway, so the\n * trade is favorable.\n *\n * The engine sits behind the `ScriptRunner` interface — if a host environment\n * can guarantee node-only deployment we can plug `isolated-vm` later without\n * touching call sites.\n */\n\nimport type { HookBody, ScriptBody, ExpressionBody } from '@objectstack/spec/data';\n\n/**\n * Identity / origin information used by the sandbox for diagnostics, capability\n * gating, and audit logs.\n */\nexport interface ScriptOrigin {\n /** Whether the body is attached to a Hook or an Action. */\n kind: 'hook' | 'action';\n /** Object the hook/action targets, when applicable. */\n object?: string;\n /** Hook/Action name, used in error messages and traces. */\n name: string;\n}\n\n/**\n * Context object exposed to the script. The shape mirrors `HookContext` /\n * `ActionContext` from `@objectstack/spec`. The sandbox copies a subset of\n * these into the isolated heap; capability checks gate which methods are\n * actually wired up.\n */\nexport interface ScriptContext {\n input: unknown;\n previous?: unknown;\n user?: unknown;\n session?: unknown;\n /**\n * The lifecycle event name the hook is firing for (e.g. `beforeInsert`,\n * `afterUpdate`). Required for hooks that subscribe to multiple events\n * and dispatch on event name.\n */\n event?: string;\n /** The object the hook/action targets — surfaces from `HookContext.object`. */\n object?: string;\n /**\n * Action only: the record id passed in the action invocation URL\n * (`POST /api/v1/actions/:object/:action/:recordId`). Hooks always have\n * the record on `input` so this stays undefined for them.\n */\n recordId?: string;\n /**\n * Action only: the record loaded by the dispatcher before the action ran\n * (when the dispatcher pre-fetches it). May be undefined for actions\n * declared with `requiresRecord: false` or when no `recordId` was supplied.\n */\n record?: unknown;\n /** Engine-side `result` (only set for after* hooks). */\n result?: unknown;\n api?: unknown;\n log?: {\n info: (msg: string, data?: unknown) => void;\n warn: (msg: string, data?: unknown) => void;\n error: (msg: string, data?: unknown) => void;\n };\n crypto?: {\n randomUUID?: () => string;\n hash?: (algo: string, data: string | Uint8Array) => Promise<string>;\n };\n}\n\n/**\n * Result returned to the caller after script execution.\n * - For hooks the `value` is typically `undefined` (mutations happen on `ctx`).\n * - For actions the `value` is the script's return value.\n */\nexport interface ScriptResult {\n value: unknown;\n /** Total wall-clock time inside the sandbox, milliseconds. */\n durationMs: number;\n /**\n * Snapshot of `ctx.input` *as observed inside the VM after the script settled*.\n *\n * Hooks frequently mutate `ctx.input.x = y` directly without returning a value.\n * The runner dumps the post-execution `ctx.input` so the host body-runner can\n * write the mutations back through to the engine's `hookContext.input` (which\n * is itself usually a flat-record Proxy).\n *\n * `undefined` if the dump failed or the script context did not expose `input`.\n */\n mutatedInput?: Record<string, unknown>;\n}\n\nexport interface ScriptRunOptions {\n origin: ScriptOrigin;\n /** Hard timeout for this invocation. The smaller of body.timeoutMs and this wins. */\n timeoutMs?: number;\n /** Optional abort signal from the surrounding kernel. */\n signal?: AbortSignal;\n}\n\n/**\n * The sandbox engine contract. Implementations live under\n * `packages/runtime/src/sandbox/engines/`.\n */\nexport interface ScriptRunner {\n /** Execute an L1 expression. Pure, side-effect-free. */\n evalExpression(body: ExpressionBody, ctx: ScriptContext, opts: ScriptRunOptions): Promise<ScriptResult>;\n\n /** Execute an L2 sandboxed JS script body. */\n runScript(body: ScriptBody, ctx: ScriptContext, opts: ScriptRunOptions): Promise<ScriptResult>;\n\n /** Convenience dispatch on the discriminated union. */\n run(body: HookBody, ctx: ScriptContext, opts: ScriptRunOptions): Promise<ScriptResult>;\n\n /** Release any underlying VM resources. */\n dispose(): Promise<void>;\n}\n\n/**\n * Default no-op runner — throws on every call. The real engine is injected\n * during runtime bootstrap once `quickjs-emscripten` is wired in. This stub\n * lets the rest of the pipeline (loader, dispatcher, type plumbing) compile\n * and be unit-tested ahead of the engine landing.\n */\nexport class UnimplementedScriptRunner implements ScriptRunner {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n evalExpression(_body: ExpressionBody, _ctx: ScriptContext, _opts: ScriptRunOptions): Promise<ScriptResult> {\n return Promise.reject(new Error('ScriptRunner not configured: install a quickjs engine first.'));\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n runScript(_body: ScriptBody, _ctx: ScriptContext, _opts: ScriptRunOptions): Promise<ScriptResult> {\n return Promise.reject(new Error('ScriptRunner not configured: install a quickjs engine first.'));\n }\n run(body: HookBody, ctx: ScriptContext, opts: ScriptRunOptions): Promise<ScriptResult> {\n return body.language === 'expression'\n ? this.evalExpression(body, ctx, opts)\n : this.runScript(body, ctx, opts);\n }\n dispose(): Promise<void> {\n return Promise.resolve();\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nexport {\n UnimplementedScriptRunner,\n} from './script-runner.js';\nexport type {\n ScriptRunner,\n ScriptContext,\n ScriptOrigin,\n ScriptResult,\n ScriptRunOptions,\n} from './script-runner.js';\nexport { QuickJSScriptRunner, SandboxError } from './quickjs-runner.js';\nexport type { QuickJSScriptRunnerOptions } from './quickjs-runner.js';\nexport { hookBodyRunnerFactory, actionBodyRunnerFactory } from './body-runner.js';\n"],"mappings":"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","names":["resolvePath","import_node_path","wrapped","resolve","import_data","resolve","resolvePath","DriverPlugin","AppPlugin","import_node_path","import_node_fs","import_types","import_core","import_node_path","import_node_fs","resolvePath","import_core","import_system","import_shared","safeJsonParse","ql","protocol","labels","result","import_observability","generateRequestId","import_observability","generateRequestId","ctx","import_node_path","entry","resolvePathNode","import_node_crypto","import_core","import_types","driver","seedProjectOrganization","seedProjectOwner","seedProjectMember","import_node_crypto","headers","body","import_promises","import_node_path","resolvePath","DriverPlugin","import_node_fs","import_node_path","import_types","SeedLoaderService","import_types"]}
|
|
1
|
+
{"version":3,"sources":["../src/load-artifact-bundle.ts","../src/driver-plugin.ts","../src/seed-loader.ts","../src/package-state-store.ts","../src/sandbox/quickjs-runner.ts","../src/sandbox/body-runner.ts","../src/app-plugin.ts","../src/standalone-stack.ts","../src/cloud/environment-org-seed.ts","../src/cloud/environment-owner-seed.ts","../src/index.ts","../src/runtime.ts","../src/default-host.ts","../src/external-validation-plugin.ts","../src/http-dispatcher.ts","../src/security/resolve-execution-context.ts","../src/security/security-headers.ts","../src/security/rate-limit.ts","../src/observability/request-context.ts","../src/observability/metrics.ts","../src/observability/error-reporter.ts","../src/observability/instrument.ts","../src/observability/observability-service-plugin.ts","../src/dispatcher-plugin.ts","../src/system-environment-plugin.ts","../src/http-server.ts","../src/middleware.ts","../src/cloud/kernel-manager.ts","../src/cloud/artifact-api-client.ts","../src/cloud/artifact-environment-registry.ts","../src/cloud/artifact-kernel-factory.ts","../src/cloud/capability-loader.ts","../src/cloud/platform-sso.ts","../src/cloud/auth-proxy-plugin.ts","../src/cloud/cloud-url.ts","../src/cloud/marketplace-public-url.ts","../src/cloud/marketplace-proxy-plugin.ts","../src/cloud/runtime-config-plugin.ts","../src/cloud/file-artifact-api-client.ts","../src/cloud/objectos-stack.ts","../src/cloud/marketplace-install-local-plugin.ts","../src/sandbox/script-runner.ts","../src/sandbox/index.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Shared artifact loader used by every code path that boots a kernel\n * from an `objectstack build` artifact:\n *\n * - `FsAppBundleResolver` — cloud / multi-environment file binding\n * - `runtime-stack.ts:basePlugins` — single-environment local boot\n * - `StandaloneStack` — `objectstack serve --standalone`\n * - `http-dispatcher.ts` — in-flight artifact rebind\n *\n * Reads the JSON artifact (from a local path *or* an `http(s)://` URL) and,\n * for **local** artifacts only, if the bundle declares a sibling\n * `runtimeModule` (the ESM produced by `packages/cli/src/utils/build-runtime.ts`),\n * dynamic-imports it and merges its `functions` map onto the bundle so\n * declarative Hooks resolve their handlers at boot.\n *\n * For **remote** (`http(s)://`) artifacts the `runtimeModule` reference is\n * intentionally ignored — Node cannot dynamic-import arbitrary URLs and we\n * refuse to execute remote code by default. Remote artifacts are therefore\n * expected to be fully declarative (Hooks/Flows carry their bodies inline).\n *\n * Mutates the returned bundle in place. Returns `null` on read/parse\n * failure (callers may treat as \"no bundle for this project yet\").\n * Runtime-module load failures are logged but non-fatal — the bundle\n * is still returned, just without runtime functions.\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { resolve as resolvePath, isAbsolute, dirname } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nexport interface LoadArtifactBundleOptions {\n /** Optional log tag for warnings (defaults to `[loadArtifactBundle]`). */\n tag?: string;\n /** When true, an unwrapped `{ schemaVersion, metadata }` envelope is unwrapped. */\n unwrapEnvelope?: boolean;\n /** Optional fetch timeout in ms for `http(s)://` sources (default 15000). */\n fetchTimeoutMs?: number;\n}\n\n/** Returns true when `pathOrUrl` looks like an `http://` or `https://` URL. */\nexport function isHttpUrl(pathOrUrl: string): boolean {\n return /^https?:\\/\\//i.test(pathOrUrl);\n}\n\n/**\n * Read a JSON artifact from either a local file path or an `http(s)://` URL.\n * Returns the raw text body. Throws on network or filesystem failure.\n */\nexport async function readArtifactSource(\n pathOrUrl: string,\n opts: { fetchTimeoutMs?: number } = {},\n): Promise<string> {\n if (isHttpUrl(pathOrUrl)) {\n const timeoutMs = opts.fetchTimeoutMs ?? 15_000;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(pathOrUrl, {\n redirect: 'follow',\n signal: controller.signal,\n headers: { Accept: 'application/json, text/plain;q=0.9, */*;q=0.5' },\n });\n if (!res.ok) {\n throw new Error(`HTTP ${res.status} ${res.statusText} for ${pathOrUrl}`);\n }\n return await res.text();\n } finally {\n clearTimeout(timer);\n }\n }\n return readFile(pathOrUrl, 'utf-8');\n}\n\nexport async function loadArtifactBundle(\n absArtifactPath: string,\n opts: LoadArtifactBundleOptions = {},\n): Promise<any | null> {\n const tag = opts.tag ?? '[loadArtifactBundle]';\n const isUrl = isHttpUrl(absArtifactPath);\n let bundle: any;\n try {\n const raw = await readArtifactSource(absArtifactPath, { fetchTimeoutMs: opts.fetchTimeoutMs });\n const parsed = JSON.parse(raw);\n bundle = opts.unwrapEnvelope && parsed?.schemaVersion != null && parsed?.metadata !== undefined\n ? parsed.metadata\n : parsed;\n } catch (err: any) {\n // eslint-disable-next-line no-console\n console.warn(`${tag} artifact read FAILED: path='${absArtifactPath}' error=${err?.message ?? err}`);\n return null;\n }\n\n if (isUrl) {\n // Remote artifacts cannot dynamic-import a sibling ESM runtime module\n // safely (Node does not allow importing arbitrary URLs and we never\n // want to execute remote code by default). Hooks/flow handlers must\n // be carried in the JSON itself (declarative bodies, sandbox-eval).\n if (typeof bundle?.runtimeModule === 'string' && bundle.runtimeModule.length > 0) {\n // eslint-disable-next-line no-console\n console.warn(\n `${tag} ignoring runtimeModule='${bundle.runtimeModule}' for remote artifact ${absArtifactPath} ` +\n `(remote ESM imports are not supported; embed handlers in the JSON instead)`,\n );\n // Strip the reference so downstream code doesn't try to resolve it\n // as a local path against process.cwd().\n delete bundle.runtimeModule;\n }\n return bundle;\n }\n\n await mergeRuntimeModule(bundle, absArtifactPath, tag);\n return bundle;\n}\n\nexport async function mergeRuntimeModule(bundle: any, artifactAbsPath: string, tag = '[loadArtifactBundle]'): Promise<void> {\n const ref = bundle?.runtimeModule;\n if (typeof ref !== 'string' || ref.length === 0) return;\n const moduleAbsPath = isAbsolute(ref) ? ref : resolvePath(dirname(artifactAbsPath), ref);\n try {\n const mod: any = await import(pathToFileURL(moduleAbsPath).href);\n const fns = (mod && (mod.functions ?? mod.default?.functions)) ?? null;\n if (!fns || typeof fns !== 'object') {\n // eslint-disable-next-line no-console\n console.warn(`${tag} runtime module '${moduleAbsPath}' exported no \\`functions\\` map`);\n return;\n }\n const existing = (bundle.functions && typeof bundle.functions === 'object' && !Array.isArray(bundle.functions))\n ? bundle.functions as Record<string, unknown>\n : {};\n bundle.functions = { ...existing, ...fns };\n } catch (err: any) {\n // eslint-disable-next-line no-console\n console.warn(`${tag} runtime module load FAILED: path='${moduleAbsPath}' error=${err?.message ?? err}`);\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { Plugin, PluginContext } from '@objectstack/core';\n\n/**\n * Driver Plugin\n * \n * Generic plugin wrapper for ObjectQL drivers.\n * Registers a driver with the ObjectQL engine.\n * \n * Dependencies: None (Registers service for ObjectQL to discover)\n * Services: driver.{name}\n * \n * @example\n * const memoryDriver = new InMemoryDriver();\n * const driverPlugin = new DriverPlugin(memoryDriver, 'memory');\n * kernel.use(driverPlugin);\n */\nexport interface DriverPluginOptions {\n /**\n * If set, registers a named datasource so packages declaring\n * `defaultDatasource: '<name>'` resolve to this driver.\n */\n datasourceName?: string;\n /**\n * If `true` (default), registers this driver as the `default` datasource\n * when none exists. Set to `false` for proxy drivers (e.g. cloud proxy)\n * that should never become the default.\n */\n registerAsDefault?: boolean;\n}\n\nexport class DriverPlugin implements Plugin {\n name: string;\n type = 'driver';\n version = '1.0.0';\n\n private driver: any;\n private options: DriverPluginOptions;\n\n constructor(driver: any, driverNameOrOptions?: string | DriverPluginOptions, options?: DriverPluginOptions) {\n this.driver = driver;\n const driverName = typeof driverNameOrOptions === 'string' ? driverNameOrOptions : undefined;\n this.options = (typeof driverNameOrOptions === 'object' ? driverNameOrOptions : options) ?? {};\n this.name = `com.objectstack.driver.${driverName || driver.name || 'unknown'}`;\n }\n\n init = async (ctx: PluginContext) => {\n const serviceName = `driver.${this.driver.name || 'unknown'}`;\n ctx.registerService(serviceName, this.driver);\n ctx.logger.info('Driver service registered', { \n serviceName, \n driverName: this.driver.name,\n driverVersion: this.driver.version \n });\n }\n\n start = async (ctx: PluginContext) => {\n try {\n const metadata = ctx.getService<any>('metadata');\n if (!metadata?.addDatasource) return;\n\n // Register a named datasource for this driver (e.g. 'cloud').\n if (this.options.datasourceName) {\n await metadata.addDatasource({\n name: this.options.datasourceName,\n driver: this.driver.name,\n });\n ctx.logger.info(`[DriverPlugin] Registered named datasource '${this.options.datasourceName}'`, { driver: this.driver.name });\n }\n\n // Auto-register as 'default' datasource unless explicitly disabled.\n if (this.options.registerAsDefault !== false) {\n const datasources = metadata.getDatasources ? metadata.getDatasources() : [];\n const hasDefault = datasources.some((ds: any) => ds.name === 'default');\n if (!hasDefault) {\n ctx.logger.info(`[DriverPlugin] No 'default' datasource found — registering '${this.driver.name}' as default.`);\n await metadata.addDatasource({ name: 'default', driver: this.driver.name });\n }\n }\n } catch (e) {\n ctx.logger.debug('[DriverPlugin] Failed to configure datasource (metadata service missing?)', { error: e });\n }\n\n ctx.logger.debug('Driver plugin started', { driverName: this.driver.name || 'unknown' });\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { IDataEngine, IMetadataService, ISeedLoaderService } from '@objectstack/spec/contracts';\nimport type {\n SeedLoaderRequest,\n SeedLoaderResult,\n SeedLoaderConfig,\n SeedLoaderConfigInput,\n ObjectDependencyGraph,\n ObjectDependencyNode,\n ReferenceResolution,\n ReferenceResolutionError,\n DatasetLoadResult,\n Dataset,\n} from '@objectstack/spec/data';\nimport { SeedLoaderConfigSchema } from '@objectstack/spec/data';\nimport { resolveSeedRecord } from '@objectstack/formula';\n\ninterface Logger {\n info(message: string, meta?: Record<string, any>): void;\n warn(message: string, meta?: Record<string, any>): void;\n error(message: string, error?: Error, meta?: Record<string, any>): void;\n debug(message: string, meta?: Record<string, any>): void;\n}\n\n/** Default field used for externalId matching on target objects */\nconst DEFAULT_EXTERNAL_ID_FIELD = 'name';\n\n/**\n * SeedLoaderService — Runtime implementation of ISeedLoaderService\n *\n * Provides metadata-driven seed data loading with:\n * - Automatic lookup/master_detail reference resolution via externalId\n * - Topological dependency ordering (parents before children)\n * - Multi-pass loading for circular references\n * - Dry-run validation mode\n * - Upsert support honoring DatasetSchema mode\n * - Actionable error reporting\n */\nexport class SeedLoaderService implements ISeedLoaderService {\n private engine: IDataEngine;\n private metadata: IMetadataService;\n private logger: Logger;\n\n constructor(engine: IDataEngine, metadata: IMetadataService, logger: Logger) {\n this.engine = engine;\n this.metadata = metadata;\n this.logger = logger;\n }\n\n // ==========================================================================\n // Public API\n // ==========================================================================\n\n async load(request: SeedLoaderRequest): Promise<SeedLoaderResult> {\n const startTime = Date.now();\n const config = request.config;\n const allErrors: ReferenceResolutionError[] = [];\n const allResults: DatasetLoadResult[] = [];\n\n // 1. Filter datasets by environment\n const datasets = this.filterByEnv(request.datasets, config.env);\n\n if (datasets.length === 0) {\n return this.buildEmptyResult(config, Date.now() - startTime);\n }\n\n // 2. Build dependency graph\n const objectNames = datasets.map(d => d.object);\n const graph = await this.buildDependencyGraph(objectNames);\n\n this.logger.info('[SeedLoader] Dependency graph built', {\n objects: objectNames.length,\n insertOrder: graph.insertOrder,\n circularDeps: graph.circularDependencies.length,\n });\n\n // 3. Order datasets by topological insert order\n const orderedDatasets = this.orderDatasets(datasets, graph.insertOrder);\n\n // 4. Build reference lookup map from metadata (field → target object)\n const refMap = this.buildReferenceMap(graph);\n\n // 5. Pass 1: Insert/upsert records, resolving references\n const insertedRecords = new Map<string, Map<string, string>>(); // object → externalIdValue → internalId\n const deferredUpdates: DeferredUpdate[] = [];\n\n for (const dataset of orderedDatasets) {\n const result = await this.loadDataset(\n dataset, config, refMap, insertedRecords, deferredUpdates, allErrors\n );\n allResults.push(result);\n\n if (config.haltOnError && result.errored > 0) {\n this.logger.warn('[SeedLoader] Halting on first error', { object: dataset.object });\n break;\n }\n }\n\n // 6. Pass 2: Resolve deferred references (circular dependencies)\n if (config.multiPass && deferredUpdates.length > 0 && !config.dryRun) {\n this.logger.info('[SeedLoader] Pass 2: resolving deferred references', {\n count: deferredUpdates.length,\n });\n await this.resolveDeferredUpdates(deferredUpdates, insertedRecords, allResults, allErrors, config.organizationId);\n }\n\n // 7. Build final result\n const durationMs = Date.now() - startTime;\n return this.buildResult(config, graph, allResults, allErrors, durationMs);\n }\n\n async buildDependencyGraph(objectNames: string[]): Promise<ObjectDependencyGraph> {\n const nodes: ObjectDependencyNode[] = [];\n const objectSet = new Set(objectNames);\n\n for (const objectName of objectNames) {\n const objDef = await this.metadata.getObject(objectName) as any;\n const dependsOn: string[] = [];\n const references: ReferenceResolution[] = [];\n\n if (objDef && objDef.fields) {\n const fields = objDef.fields as Record<string, any>;\n for (const [fieldName, fieldDef] of Object.entries(fields)) {\n if (\n (fieldDef.type === 'lookup' || fieldDef.type === 'master_detail') &&\n fieldDef.reference\n ) {\n const targetObject = fieldDef.reference as string;\n\n // Track dependency ordering only for objects within the graph\n if (objectSet.has(targetObject) && !dependsOn.includes(targetObject)) {\n dependsOn.push(targetObject);\n }\n\n // Track ALL references for resolution (target may exist in database)\n references.push({\n field: fieldName,\n targetObject,\n targetField: DEFAULT_EXTERNAL_ID_FIELD,\n fieldType: fieldDef.type as 'lookup' | 'master_detail',\n });\n }\n }\n }\n\n nodes.push({ object: objectName, dependsOn, references });\n }\n\n // Topological sort\n const { insertOrder, circularDependencies } = this.topologicalSort(nodes);\n\n return { nodes, insertOrder, circularDependencies };\n }\n\n async validate(datasets: Dataset[], config?: SeedLoaderConfigInput): Promise<SeedLoaderResult> {\n const parsedConfig = SeedLoaderConfigSchema.parse({ ...config, dryRun: true });\n return this.load({ datasets, config: parsedConfig });\n }\n\n // ==========================================================================\n // Internal: Dataset Loading\n // ==========================================================================\n\n private async loadDataset(\n dataset: Dataset,\n config: SeedLoaderConfig,\n refMap: Map<string, ReferenceResolution[]>,\n insertedRecords: Map<string, Map<string, string>>,\n deferredUpdates: DeferredUpdate[],\n allErrors: ReferenceResolutionError[],\n ): Promise<DatasetLoadResult> {\n const objectName = dataset.object;\n const mode = dataset.mode || config.defaultMode;\n const externalId = dataset.externalId || 'name';\n\n let inserted = 0;\n let updated = 0;\n let skipped = 0;\n let errored = 0;\n let referencesResolved = 0;\n let referencesDeferred = 0;\n const errors: ReferenceResolutionError[] = [];\n\n // Ensure the object's record map exists\n if (!insertedRecords.has(objectName)) {\n insertedRecords.set(objectName, new Map());\n }\n\n // Pre-load existing records for upsert matching. When a target\n // organization is set, scope the lookup so each tenant gets its\n // own copy (otherwise upsert would clobber other tenants' rows\n // that share the same natural key — e.g. `name: 'Acme Corp'`).\n let existingRecords: Map<string, any> | undefined;\n if ((mode === 'upsert' || mode === 'update' || mode === 'ignore') && !config.dryRun) {\n existingRecords = await this.loadExistingRecords(\n objectName,\n externalId,\n config.organizationId,\n );\n }\n\n // Get reference resolutions for this object\n const objectRefs = refMap.get(objectName) || [];\n\n // Pin a single `now()` snapshot for the entire dataset so multi-pass\n // loads see one logical clock — the M9 determinism guarantee for seeds.\n const seedNow = new Date();\n\n // Identity/context bound to seed CEL expressions. `os.user` / `os.org`\n // resolve from here, so `owner_id: cel\\`os.user.id\\`` works. When no\n // identity is supplied, `os.user` / `os.org` are simply unbound and any\n // record that references them fails loudly below (rather than silently\n // writing a raw Expression envelope into the column).\n const seedIdentity = config.identity;\n const baseEvalCtx = {\n now: seedNow,\n user: seedIdentity?.user,\n // Fall back to the per-tenant organizationId so `os.org.id` resolves\n // during per-org replay even without an explicit identity.org.\n org: seedIdentity?.org ?? (config.organizationId ? { id: config.organizationId } : undefined),\n env: config.env,\n };\n\n for (let i = 0; i < dataset.records.length; i++) {\n // Resolve any embedded Expression envelopes (e.g. `cel\\`daysFromNow(30)\\``,\n // `cel\\`os.user.id\\``) BEFORE reference resolution so downstream lookups\n // see resolved values.\n const seedResult = resolveSeedRecord(\n dataset.records[i] as Record<string, never>,\n baseEvalCtx,\n );\n if (!seedResult.ok) {\n // LOUD FAILURE: a record whose dynamic values cannot be resolved is\n // dropped — but never silently. Record an actionable error (so it\n // surfaces in result.errors and flips success=false) instead of\n // writing the unresolved Expression envelope into the database.\n errored++;\n const error: ReferenceResolutionError = {\n sourceObject: objectName,\n field: '(expression)',\n targetObject: objectName,\n targetField: '(expression)',\n attemptedValue: dataset.records[i],\n recordIndex: i,\n message:\n `Cannot resolve dynamic seed values for ${objectName} record #${i}: ${seedResult.error.message}. ` +\n 'Records using cel`os.user.id` / cel`os.org.id` require a seed identity — ' +\n 'ensure a system/admin user exists before seeding (see SeedLoaderConfig.identity).',\n };\n errors.push(error);\n allErrors.push(error);\n this.logger.warn(`[SeedLoader] ${error.message}`);\n continue;\n }\n const record = { ...(seedResult.value as Record<string, unknown>) };\n\n // Per-tenant tagging: when a target org is set, stamp every\n // seeded row with it (unless the record itself already supplies\n // an explicit organization_id — respect dataset author overrides).\n // Skipped objects that don't declare `organization_id` will have\n // the extra key silently ignored by the engine.\n if (config.organizationId && record['organization_id'] == null) {\n record['organization_id'] = config.organizationId;\n }\n\n // Resolve references\n for (const ref of objectRefs) {\n const fieldValue = record[ref.field];\n if (fieldValue === undefined || fieldValue === null) continue;\n\n // LOUD FAILURE: a reference must be a natural-key string (or an\n // internal id). An object value — e.g. the wrapper `{ externalId: 'X' }`\n // — never resolves: it would otherwise fall through unresolved and reach\n // the driver as a non-bindable value (\"SQLite3 can only bind ...\"). This\n // used to be silently skipped (and only crashed on a persistent DB's\n // update path), so catch it here and report the actionable fix instead.\n if (typeof fieldValue === 'object') {\n const wrapped = (fieldValue as Record<string, unknown>).externalId;\n const hint =\n wrapped !== undefined\n ? ` Pass the natural key directly: ${ref.field}: ${JSON.stringify(wrapped)}.`\n : ` Pass the target's ${ref.targetField} value as a plain string.`;\n const error: ReferenceResolutionError = {\n sourceObject: objectName,\n field: ref.field,\n targetObject: ref.targetObject,\n targetField: ref.targetField,\n attemptedValue: fieldValue,\n recordIndex: i,\n message:\n `Invalid reference for ${objectName}.${ref.field}: expected a ` +\n `${ref.targetObject}.${ref.targetField} natural-key string but got an object.${hint}`,\n };\n errors.push(error);\n allErrors.push(error);\n this.logger.warn(`[SeedLoader] ${error.message}`, { recordIndex: i });\n // Drop the unresolvable value so it never reaches the driver.\n record[ref.field] = null;\n continue;\n }\n\n // Skip if value looks like an internal ID (not a natural key)\n if (typeof fieldValue !== 'string' || this.looksLikeInternalId(fieldValue)) continue;\n\n // Try to resolve via already-inserted records\n const targetMap = insertedRecords.get(ref.targetObject);\n const resolvedId = targetMap?.get(String(fieldValue));\n\n if (resolvedId) {\n record[ref.field] = resolvedId;\n referencesResolved++;\n } else if (!config.dryRun) {\n // Try to resolve from existing data in the database\n const dbId = await this.resolveFromDatabase(ref.targetObject, ref.targetField, fieldValue, config.organizationId);\n if (dbId) {\n record[ref.field] = dbId;\n referencesResolved++;\n } else if (config.multiPass) {\n // Defer to pass 2\n record[ref.field] = null;\n deferredUpdates.push({\n objectName,\n recordExternalId: String(record[externalId] ?? ''),\n field: ref.field,\n targetObject: ref.targetObject,\n targetField: ref.targetField,\n attemptedValue: fieldValue,\n recordIndex: i,\n });\n referencesDeferred++;\n } else {\n // Cannot resolve - record error\n const error: ReferenceResolutionError = {\n sourceObject: objectName,\n field: ref.field,\n targetObject: ref.targetObject,\n targetField: ref.targetField,\n attemptedValue: fieldValue,\n recordIndex: i,\n message: `Cannot resolve reference: ${objectName}.${ref.field} = '${fieldValue}' → ${ref.targetObject}.${ref.targetField} not found`,\n };\n errors.push(error);\n allErrors.push(error);\n }\n } else {\n // Dry-run: attempt resolution, report error if not found\n const targetMap2 = insertedRecords.get(ref.targetObject);\n if (!targetMap2?.has(String(fieldValue))) {\n const error: ReferenceResolutionError = {\n sourceObject: objectName,\n field: ref.field,\n targetObject: ref.targetObject,\n targetField: ref.targetField,\n attemptedValue: fieldValue,\n recordIndex: i,\n message: `[dry-run] Reference may not resolve: ${objectName}.${ref.field} = '${fieldValue}' → ${ref.targetObject}.${ref.targetField}`,\n };\n errors.push(error);\n allErrors.push(error);\n }\n }\n }\n\n // Insert/upsert the record\n if (!config.dryRun) {\n try {\n const result = await this.writeRecord(\n objectName, record, mode, externalId, existingRecords\n );\n\n if (result.action === 'inserted') inserted++;\n else if (result.action === 'updated') updated++;\n else if (result.action === 'skipped') skipped++;\n\n // Track the inserted/updated record's ID for reference resolution\n const externalIdValue = String(record[externalId] ?? '');\n const internalId = result.id;\n if (externalIdValue && internalId) {\n insertedRecords.get(objectName)!.set(externalIdValue, String(internalId));\n }\n } catch (err: any) {\n // LOUD FAILURE: write errors were previously only counted +\n // warn-logged, so dropped rows were invisible in result.errors and\n // the boot summary. Surface them as actionable errors too, so the\n // overall load is marked unsuccessful and the reason is reported.\n errored++;\n const error: ReferenceResolutionError = {\n sourceObject: objectName,\n field: '(write)',\n targetObject: objectName,\n targetField: externalId,\n attemptedValue: record[externalId] ?? null,\n recordIndex: i,\n message: `Failed to write ${objectName} record #${i} (${externalId}=${String(record[externalId] ?? '')}): ${err.message}`,\n };\n errors.push(error);\n allErrors.push(error);\n this.logger.warn(`[SeedLoader] ${error.message}`, { recordIndex: i });\n }\n } else {\n // Dry-run: simulate insert tracking\n const externalIdValue = String(record[externalId] ?? '');\n if (externalIdValue) {\n insertedRecords.get(objectName)!.set(externalIdValue, `dry-run-id-${i}`);\n }\n inserted++; // Count as \"would be inserted\"\n }\n }\n\n return {\n object: objectName,\n mode,\n inserted,\n updated,\n skipped,\n errored,\n total: dataset.records.length,\n referencesResolved,\n referencesDeferred,\n errors,\n };\n }\n\n // ==========================================================================\n // Internal: Reference Resolution\n // ==========================================================================\n\n private async resolveFromDatabase(\n targetObject: string,\n targetField: string,\n value: unknown,\n organizationId?: string,\n ): Promise<string | null> {\n try {\n const where: Record<string, unknown> = { [targetField]: value };\n // Per-tenant replay: when scoping is requested, only consider\n // rows that belong to the target tenant so cross-tenant rows\n // never get borrowed as a \"resolved\" reference (would silently\n // create a cross-org FK).\n if (organizationId) where.organization_id = organizationId;\n const records = await this.engine.find(targetObject, {\n where,\n fields: ['id'],\n limit: 1,\n context: { isSystem: true },\n } as any);\n if (records && records.length > 0) {\n return String(records[0].id || records[0]._id);\n }\n } catch {\n // Target object may not exist yet\n }\n return null;\n }\n\n private async resolveDeferredUpdates(\n deferredUpdates: DeferredUpdate[],\n insertedRecords: Map<string, Map<string, string>>,\n allResults: DatasetLoadResult[],\n allErrors: ReferenceResolutionError[],\n organizationId?: string,\n ): Promise<void> {\n for (const deferred of deferredUpdates) {\n // Try to resolve from inserted records\n const targetMap = insertedRecords.get(deferred.targetObject);\n let resolvedId = targetMap?.get(String(deferred.attemptedValue));\n\n // Try database fallback\n if (!resolvedId) {\n resolvedId = (await this.resolveFromDatabase(\n deferred.targetObject, deferred.targetField, deferred.attemptedValue, organizationId\n )) ?? undefined;\n }\n\n if (resolvedId) {\n // Find the record and update the reference\n const objectRecordMap = insertedRecords.get(deferred.objectName);\n const recordId = objectRecordMap?.get(deferred.recordExternalId);\n\n if (recordId) {\n try {\n await this.engine.update(deferred.objectName, {\n id: recordId,\n [deferred.field]: resolvedId,\n }, { context: { isSystem: true } } as any);\n\n // Update result stats\n const resultEntry = allResults.find(r => r.object === deferred.objectName);\n if (resultEntry) {\n resultEntry.referencesResolved++;\n resultEntry.referencesDeferred--;\n }\n } catch (err: any) {\n this.logger.warn('[SeedLoader] Failed to resolve deferred reference', {\n object: deferred.objectName,\n field: deferred.field,\n error: err.message,\n });\n }\n }\n } else {\n // Still unresolved after pass 2\n const error: ReferenceResolutionError = {\n sourceObject: deferred.objectName,\n field: deferred.field,\n targetObject: deferred.targetObject,\n targetField: deferred.targetField,\n attemptedValue: deferred.attemptedValue,\n recordIndex: deferred.recordIndex,\n message: `Deferred reference unresolved after pass 2: ${deferred.objectName}.${deferred.field} = '${deferred.attemptedValue}' → ${deferred.targetObject}.${deferred.targetField} not found`,\n };\n\n const resultEntry = allResults.find(r => r.object === deferred.objectName);\n if (resultEntry) {\n resultEntry.errors.push(error);\n }\n allErrors.push(error);\n }\n }\n }\n\n // ==========================================================================\n // Internal: Write Operations\n // ==========================================================================\n\n /**\n * Seed writes always run as a privileged system context. This bypasses\n * RBAC checks (so seeds can target system tables like `sys_*`) and\n * disables the SecurityPlugin's auto-injection of `organization_id` /\n * `owner_id` — seeds either declare those fields explicitly per\n * record, or are intentionally cross-tenant / global.\n */\n private static readonly SEED_OPTIONS = { context: { isSystem: true } } as const;\n\n private async writeRecord(\n objectName: string,\n record: Record<string, unknown>,\n mode: string,\n externalId: string,\n existingRecords?: Map<string, any>,\n ): Promise<{ action: 'inserted' | 'updated' | 'skipped'; id?: string }> {\n const externalIdValue = record[externalId];\n const existing = existingRecords?.get(String(externalIdValue ?? ''));\n const opts = SeedLoaderService.SEED_OPTIONS as any;\n\n switch (mode) {\n case 'insert': {\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n\n case 'update': {\n if (!existing) {\n return { action: 'skipped' };\n }\n const id = this.extractId(existing);\n await this.engine.update(objectName, { ...record, id }, opts);\n return { action: 'updated', id };\n }\n\n case 'upsert': {\n if (existing) {\n const id = this.extractId(existing);\n await this.engine.update(objectName, { ...record, id }, opts);\n return { action: 'updated', id };\n } else {\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n }\n\n case 'ignore': {\n if (existing) {\n return { action: 'skipped', id: this.extractId(existing) };\n }\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n\n case 'replace': {\n // Replace mode: just insert (caller should have cleared the table)\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n\n default: {\n const result = await this.engine.insert(objectName, record, opts);\n return { action: 'inserted', id: this.extractId(result) };\n }\n }\n }\n\n // ==========================================================================\n // Internal: Dependency Graph\n // ==========================================================================\n\n /**\n * Kahn's algorithm for topological sort with cycle detection.\n */\n private topologicalSort(\n nodes: ObjectDependencyNode[],\n ): { insertOrder: string[]; circularDependencies: string[][] } {\n const inDegree = new Map<string, number>();\n const adjacency = new Map<string, string[]>();\n const objectSet = new Set(nodes.map(n => n.object));\n\n // Initialize\n for (const node of nodes) {\n inDegree.set(node.object, 0);\n adjacency.set(node.object, []);\n }\n\n // Build adjacency list and in-degree counts\n for (const node of nodes) {\n for (const dep of node.dependsOn) {\n // Exclude self-references from ordering (e.g., employee.manager_id → employee).\n // Self-referencing fields are still tracked in node.references for resolution.\n if (objectSet.has(dep) && dep !== node.object) {\n adjacency.get(dep)!.push(node.object);\n inDegree.set(node.object, (inDegree.get(node.object) || 0) + 1);\n }\n }\n }\n\n // Kahn's algorithm\n const queue: string[] = [];\n for (const [obj, degree] of inDegree) {\n if (degree === 0) queue.push(obj);\n }\n\n const insertOrder: string[] = [];\n while (queue.length > 0) {\n const current = queue.shift()!;\n insertOrder.push(current);\n\n for (const neighbor of (adjacency.get(current) || [])) {\n const newDegree = (inDegree.get(neighbor) || 0) - 1;\n inDegree.set(neighbor, newDegree);\n if (newDegree === 0) {\n queue.push(neighbor);\n }\n }\n }\n\n // Detect circular dependencies\n const circularDependencies: string[][] = [];\n const remaining = nodes.filter(n => !insertOrder.includes(n.object));\n\n if (remaining.length > 0) {\n // Find cycles using DFS\n const cycles = this.findCycles(remaining);\n circularDependencies.push(...cycles);\n\n // Add remaining objects to insertOrder (they'll need multi-pass)\n for (const node of remaining) {\n if (!insertOrder.includes(node.object)) {\n insertOrder.push(node.object);\n }\n }\n }\n\n return { insertOrder, circularDependencies };\n }\n\n private findCycles(nodes: ObjectDependencyNode[]): string[][] {\n const cycles: string[][] = [];\n const nodeMap = new Map(nodes.map(n => [n.object, n]));\n const visited = new Set<string>();\n const inStack = new Set<string>();\n\n const dfs = (current: string, path: string[]) => {\n if (inStack.has(current)) {\n // Found a cycle\n const cycleStart = path.indexOf(current);\n if (cycleStart !== -1) {\n cycles.push([...path.slice(cycleStart), current]);\n }\n return;\n }\n if (visited.has(current)) return;\n\n visited.add(current);\n inStack.add(current);\n path.push(current);\n\n const node = nodeMap.get(current);\n if (node) {\n for (const dep of node.dependsOn) {\n if (nodeMap.has(dep)) {\n dfs(dep, [...path]);\n }\n }\n }\n\n inStack.delete(current);\n };\n\n for (const node of nodes) {\n if (!visited.has(node.object)) {\n dfs(node.object, []);\n }\n }\n\n return cycles;\n }\n\n // ==========================================================================\n // Internal: Helpers\n // ==========================================================================\n\n private filterByEnv(datasets: Dataset[], env?: string): Dataset[] {\n if (!env) return datasets;\n return datasets.filter(d => (d.env as string[]).includes(env));\n }\n\n private orderDatasets(datasets: Dataset[], insertOrder: string[]): Dataset[] {\n const orderMap = new Map(insertOrder.map((name, i) => [name, i]));\n return [...datasets].sort((a, b) => {\n const orderA = orderMap.get(a.object) ?? Number.MAX_SAFE_INTEGER;\n const orderB = orderMap.get(b.object) ?? Number.MAX_SAFE_INTEGER;\n return orderA - orderB;\n });\n }\n\n private buildReferenceMap(graph: ObjectDependencyGraph): Map<string, ReferenceResolution[]> {\n const map = new Map<string, ReferenceResolution[]>();\n for (const node of graph.nodes) {\n if (node.references.length > 0) {\n map.set(node.object, node.references);\n }\n }\n return map;\n }\n\n private async loadExistingRecords(\n objectName: string,\n externalId: string,\n organizationId?: string,\n ): Promise<Map<string, any>> {\n const map = new Map<string, any>();\n try {\n const findArgs: Record<string, unknown> = {\n fields: ['id', externalId],\n context: { isSystem: true },\n };\n // Per-tenant replay: restrict to the target tenant's own rows\n // so upsert key matching never returns another tenant's record\n // (would silently steal/overwrite rows across orgs).\n if (organizationId) findArgs.where = { organization_id: organizationId };\n const records = await this.engine.find(objectName, findArgs as any);\n for (const record of records || []) {\n const key = String(record[externalId] ?? '');\n if (key) {\n map.set(key, record);\n }\n }\n } catch {\n // Object may not have records yet\n }\n return map;\n }\n\n private looksLikeInternalId(value: string): boolean {\n // UUID v4 pattern\n if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)) {\n return true;\n }\n // MongoDB ObjectId pattern (24 hex chars)\n if (/^[0-9a-f]{24}$/i.test(value)) {\n return true;\n }\n return false;\n }\n\n private extractId(record: any): string | undefined {\n if (!record) return undefined;\n return String(record.id || record._id || '');\n }\n\n private buildEmptyResult(config: SeedLoaderConfig, durationMs: number): SeedLoaderResult {\n return {\n success: true,\n dryRun: config.dryRun,\n dependencyGraph: { nodes: [], insertOrder: [], circularDependencies: [] },\n results: [],\n errors: [],\n summary: {\n objectsProcessed: 0,\n totalRecords: 0,\n totalInserted: 0,\n totalUpdated: 0,\n totalSkipped: 0,\n totalErrored: 0,\n totalReferencesResolved: 0,\n totalReferencesDeferred: 0,\n circularDependencyCount: 0,\n durationMs,\n },\n };\n }\n\n private buildResult(\n config: SeedLoaderConfig,\n graph: ObjectDependencyGraph,\n results: DatasetLoadResult[],\n errors: ReferenceResolutionError[],\n durationMs: number,\n ): SeedLoaderResult {\n const summary = {\n objectsProcessed: results.length,\n totalRecords: results.reduce((sum, r) => sum + r.total, 0),\n totalInserted: results.reduce((sum, r) => sum + r.inserted, 0),\n totalUpdated: results.reduce((sum, r) => sum + r.updated, 0),\n totalSkipped: results.reduce((sum, r) => sum + r.skipped, 0),\n totalErrored: results.reduce((sum, r) => sum + r.errored, 0),\n totalReferencesResolved: results.reduce((sum, r) => sum + r.referencesResolved, 0),\n totalReferencesDeferred: results.reduce((sum, r) => sum + r.referencesDeferred, 0),\n circularDependencyCount: graph.circularDependencies.length,\n durationMs,\n };\n\n const hasErrors = errors.length > 0 || summary.totalErrored > 0;\n\n return {\n success: !hasErrors,\n dryRun: config.dryRun,\n dependencyGraph: graph,\n results,\n errors,\n summary,\n };\n }\n}\n\n// ==========================================================================\n// Internal Types\n// ==========================================================================\n\ninterface DeferredUpdate {\n objectName: string;\n recordExternalId: string;\n field: string;\n targetObject: string;\n targetField: string;\n attemptedValue: unknown;\n recordIndex: number;\n}\n","/**\n * Package lifecycle-state persistence (local-first).\n *\n * The in-memory {@link SchemaRegistry} loses package enable/disable state on\n * every restart because packages are re-registered from the compiled artifact\n * (always enabled). This store persists the *runtime lifecycle state* (which\n * packages an operator has disabled) outside the artifact so the choice\n * survives restarts.\n *\n * Storage is a small JSON file under the ObjectStack home directory, keyed by\n * environment id so disables never leak between environments (e.g. `env_local`\n * vs staging):\n *\n * <OS_HOME>/package-state/<environmentId>.json → { \"disabled\": [\"id\", …] }\n *\n * This is intentionally a flat file rather than a `sys_*` object: package\n * lifecycle state is runtime/operational state, not project metadata, and the\n * local-first install path already keeps per-environment data under OS_HOME.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport { resolveObjectStackHome } from './standalone-stack.js';\n\nconst DEFAULT_ENVIRONMENT_ID = 'default';\n\ninterface PackageStateFile {\n disabled?: string[];\n}\n\nfunction sanitizeEnvironmentId(environmentId?: string): string {\n const raw = (environmentId ?? process.env.OS_ENVIRONMENT_ID ?? DEFAULT_ENVIRONMENT_ID).trim();\n const safe = raw.replace(/[^a-zA-Z0-9._-]/g, '_');\n return safe.length > 0 ? safe : DEFAULT_ENVIRONMENT_ID;\n}\n\nfunction stateFilePath(environmentId?: string): string {\n return join(resolveObjectStackHome(), 'package-state', `${sanitizeEnvironmentId(environmentId)}.json`);\n}\n\nfunction readState(environmentId?: string): PackageStateFile {\n const file = stateFilePath(environmentId);\n if (!existsSync(file)) return {};\n try {\n const parsed = JSON.parse(readFileSync(file, 'utf8')) as PackageStateFile;\n return parsed && typeof parsed === 'object' ? parsed : {};\n } catch {\n // Corrupt/partial file — treat as empty rather than crashing boot.\n return {};\n }\n}\n\nfunction writeState(environmentId: string | undefined, state: PackageStateFile): void {\n const file = stateFilePath(environmentId);\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, `${JSON.stringify(state, null, 2)}\\n`, 'utf8');\n}\n\n/** Set of package ids currently persisted as disabled for the environment. */\nexport function loadDisabledPackageIds(environmentId?: string): Set<string> {\n const disabled = readState(environmentId).disabled;\n return new Set(Array.isArray(disabled) ? disabled.filter((id) => typeof id === 'string') : []);\n}\n\n/**\n * Persist the disabled/enabled state of a single package. Best-effort: failures\n * are surfaced to the caller so the HTTP layer can log, but disabling already\n * took effect in-memory regardless.\n */\nexport function setPackageDisabled(environmentId: string | undefined, packageId: string, disabled: boolean): void {\n const ids = loadDisabledPackageIds(environmentId);\n if (disabled) ids.add(packageId);\n else ids.delete(packageId);\n writeState(environmentId, { disabled: Array.from(ids).sort() });\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * # QuickJS-backed ScriptRunner\n *\n * Implements `ScriptRunner` using `quickjs-emscripten` (pure-WASM, edge-safe).\n *\n * Responsibilities:\n * - L1 ExpressionBody — evaluated as a `return (<source>)` snippet.\n * - L2 ScriptBody — wrapped in `(async (ctx) => { <source> })(ctx)` (hooks)\n * or `(async (input, ctx) => { <source> })(input, ctx)` (actions).\n * - Hard timeout via QuickJS interrupt handler.\n * - Capability gating — host-side `ctx.api`, `ctx.crypto`, `ctx.log` are only\n * wired into the VM if the body declares the matching capability.\n * - Structured marshalling — JSON-serialisable values cross the VM boundary.\n * Functions are exposed as host-resident proxies (the script calls\n * `ctx.api.object('foo').count(...)` and the host method runs in node).\n *\n * Trade-offs:\n * - Per-invocation overhead is dominated by VM creation. We pool runtimes per\n * `(origin.kind, capabilities-set)` to amortise startup. Pool size is bounded\n * by `maxPooled` (default 8); evicted runtimes are disposed.\n * - Memory caps are advisory under quickjs (engine has no hard MB cap); the\n * runner uses `setMemoryLimit(memoryMb * 1MB)` which is best-effort.\n */\n\nimport {\n newAsyncContext,\n type QuickJSAsyncContext,\n type QuickJSHandle,\n} from 'quickjs-emscripten';\nimport type { HookBody, ScriptBody, ExpressionBody, HookBodyCapability } from '@objectstack/spec/data';\nimport type {\n ScriptContext,\n ScriptOrigin,\n ScriptResult,\n ScriptRunOptions,\n ScriptRunner,\n} from './script-runner.js';\n\nconst DEFAULT_HOOK_TIMEOUT_MS = 250;\nconst DEFAULT_ACTION_TIMEOUT_MS = 5000;\nconst DEFAULT_MEMORY_MB = 32;\n\nexport interface QuickJSScriptRunnerOptions {\n /** Default per-invocation timeout for hooks (ms). */\n hookTimeoutMs?: number;\n /** Default per-invocation timeout for actions (ms). */\n actionTimeoutMs?: number;\n /** Default memory cap in MB. */\n memoryMb?: number;\n}\n\nexport class QuickJSScriptRunner implements ScriptRunner {\n private opts: Required<QuickJSScriptRunnerOptions>;\n\n constructor(opts: QuickJSScriptRunnerOptions = {}) {\n this.opts = {\n hookTimeoutMs: opts.hookTimeoutMs ?? DEFAULT_HOOK_TIMEOUT_MS,\n actionTimeoutMs: opts.actionTimeoutMs ?? DEFAULT_ACTION_TIMEOUT_MS,\n memoryMb: opts.memoryMb ?? DEFAULT_MEMORY_MB,\n };\n }\n\n async evalExpression(\n body: ExpressionBody,\n ctx: ScriptContext,\n opts: ScriptRunOptions,\n ): Promise<ScriptResult> {\n return this.execute({\n isExpression: true,\n source: body.source,\n capabilities: [],\n timeoutMs: this.resolveTimeout(opts, undefined),\n memoryMb: this.opts.memoryMb,\n ctx,\n origin: opts.origin,\n });\n }\n\n async runScript(\n body: ScriptBody,\n ctx: ScriptContext,\n opts: ScriptRunOptions,\n ): Promise<ScriptResult> {\n return this.execute({\n isExpression: false,\n source: body.source,\n capabilities: body.capabilities,\n timeoutMs: this.resolveTimeout(opts, body.timeoutMs),\n memoryMb: body.memoryMb ?? this.opts.memoryMb,\n ctx,\n origin: opts.origin,\n });\n }\n\n run(body: HookBody, ctx: ScriptContext, opts: ScriptRunOptions): Promise<ScriptResult> {\n return body.language === 'expression'\n ? this.evalExpression(body, ctx, opts)\n : this.runScript(body, ctx, opts);\n }\n\n async dispose(): Promise<void> {\n /* no-op — runtimes are per-invocation in v1 */\n }\n\n /** Pick the smallest of body / opts / engine-default. */\n private resolveTimeout(opts: ScriptRunOptions, bodyTimeoutMs: number | undefined): number {\n const def = opts.origin.kind === 'hook' ? this.opts.hookTimeoutMs : this.opts.actionTimeoutMs;\n return Math.min(...[def, opts.timeoutMs, bodyTimeoutMs].filter((n): n is number => typeof n === 'number'));\n }\n\n private async execute(args: {\n isExpression: boolean;\n source: string;\n capabilities: HookBodyCapability[];\n timeoutMs: number;\n memoryMb: number;\n ctx: ScriptContext;\n origin: ScriptOrigin;\n }): Promise<ScriptResult> {\n // Each invocation gets its own WebAssembly module via newAsyncContext().\n // This is the canonical \"per-invocation isolate\" model and avoids the\n // shared-runtime HostRef double-free issues we hit with a singleton\n // QuickJSAsyncWASMModule when contexts are disposed concurrently.\n const vm = await newAsyncContext();\n const runtime = vm.runtime;\n runtime.setMemoryLimit(args.memoryMb * 1024 * 1024);\n runtime.setMaxStackSize(512 * 1024);\n\n const start = Date.now();\n const deadline = start + args.timeoutMs;\n runtime.setInterruptHandler(() => Date.now() > deadline);\n\n try {\n this.installCtx(vm, args.ctx, new Set(args.capabilities), args.origin);\n\n // L1 expressions are pure-sync: evaluate and read __result.\n if (args.isExpression) {\n const wrapped = `globalThis.__result = JSON.stringify((function(){ return (${args.source}); })());`;\n const result = vm.evalCode(wrapped);\n if (result.error) {\n const err = vm.dump(result.error);\n result.error.dispose();\n throw new SandboxError(`${args.origin.kind} '${args.origin.name}' threw: ${formatErr(err)}`);\n }\n result.value.dispose();\n const resH = vm.getProp(vm.global, '__result');\n const resStr = vm.dump(resH);\n resH.dispose();\n const value = resStr === undefined || resStr === null || resStr === 'null'\n ? undefined\n : safeJsonParse(resStr);\n return { value, durationMs: Date.now() - start };\n }\n\n // L2 scripts: wrap as async IIFE and use side-channel + asyncified pump.\n // Each pump iteration:\n // 1. yield to the host event loop (lets asyncified host calls resolve)\n // 2. drain QuickJS pending jobs (advances the .then chain)\n // 3. read __result/__error from the VM\n const wrapped = args.origin.kind === 'hook'\n ? `globalThis.__result = undefined; globalThis.__error = undefined;\n (async (ctx) => { ${args.source} })(globalThis.__ctx).then(\n function(v){ globalThis.__result = JSON.stringify(v === undefined ? null : v); },\n function(e){ globalThis.__error = (e && e.message) ? (e.name + ': ' + e.message) : String(e); }\n );`\n : `globalThis.__result = undefined; globalThis.__error = undefined;\n (async (input, ctx) => { ${args.source} })(globalThis.__input, globalThis.__ctx).then(\n function(v){ globalThis.__result = JSON.stringify(v === undefined ? null : v); },\n function(e){ globalThis.__error = (e && e.message) ? (e.name + ': ' + e.message) : String(e); }\n );`;\n\n const evalRes = await vm.evalCodeAsync(wrapped);\n if (evalRes.error) {\n const err = vm.dump(evalRes.error);\n evalRes.error.dispose();\n throw new SandboxError(`${args.origin.kind} '${args.origin.name}' threw: ${formatErr(err)}`);\n }\n evalRes.value.dispose();\n\n let pumps = 0;\n while (pumps < 1000) {\n // Yield to host event loop so any in-flight asyncified host promises resolve.\n await new Promise<void>((resolve) => setImmediate(resolve));\n\n const pending = runtime.executePendingJobs();\n if (pending.error) {\n const err = vm.dump(pending.error);\n pending.error.dispose();\n throw new SandboxError(`${args.origin.kind} '${args.origin.name}' threw: ${formatErr(err)}`);\n }\n\n const errH = vm.getProp(vm.global, '__error');\n const errStr = vm.dump(errH);\n errH.dispose();\n if (errStr) {\n throw new SandboxError(`${args.origin.kind} '${args.origin.name}' threw: ${errStr}`);\n }\n\n const resH = vm.getProp(vm.global, '__result');\n const resStr = vm.dump(resH);\n resH.dispose();\n if (resStr !== undefined && resStr !== null) {\n const value = resStr === 'null' ? undefined : safeJsonParse(resStr);\n // Capture mutated ctx.input so the host can write through.\n const mutatedInput = readCtxInputJson(vm);\n return { value, mutatedInput, durationMs: Date.now() - start };\n }\n\n if (Date.now() > deadline) {\n throw new SandboxError(\n `${args.origin.kind} '${args.origin.name}' exceeded timeout of ${args.timeoutMs}ms`,\n );\n }\n pumps++;\n }\n throw new SandboxError(\n `${args.origin.kind} '${args.origin.name}' did not resolve after ${pumps} pump iterations`,\n );\n } finally {\n // newAsyncContext() owns its WASM module; disposing the context disposes\n // the runtime + module together.\n vm.dispose();\n }\n }\n\n /**\n * Install ctx onto the VM's globalThis. Each capability is wired in only if\n * the body declared it; missing methods throw at call-time inside the VM\n * with a clear diagnostic.\n *\n * Host API methods are installed via {@link QuickJSAsyncContext.newAsyncifiedFunction}\n * so they may return Promises (real ObjectQL `find/count/insert/...` are async).\n */\n private installCtx(\n vm: QuickJSAsyncContext,\n ctx: ScriptContext,\n caps: Set<HookBodyCapability>,\n origin: ScriptOrigin,\n ): void {\n setGlobalJson(vm, '__input', ctx.input);\n setGlobalJson(vm, '__previous', ctx.previous);\n\n const ctxObj = vm.newObject();\n setObjectJson(vm, ctxObj, 'input', ctx.input);\n setObjectJson(vm, ctxObj, 'previous', ctx.previous);\n setObjectJson(vm, ctxObj, 'user', ctx.user);\n setObjectJson(vm, ctxObj, 'session', ctx.session);\n if (typeof ctx.event === 'string') {\n const evH = vm.newString(ctx.event);\n vm.setProp(ctxObj, 'event', evH);\n evH.dispose();\n }\n if (typeof ctx.object === 'string') {\n const obH = vm.newString(ctx.object);\n vm.setProp(ctxObj, 'object', obH);\n obH.dispose();\n }\n if (typeof ctx.recordId === 'string') {\n const idH = vm.newString(ctx.recordId);\n vm.setProp(ctxObj, 'recordId', idH);\n idH.dispose();\n }\n if (ctx.record !== undefined) {\n setObjectJson(vm, ctxObj, 'record', ctx.record);\n }\n if (ctx.result !== undefined) {\n setObjectJson(vm, ctxObj, 'result', ctx.result);\n }\n\n const apiObj = vm.newObject();\n const objectFn = vm.newFunction('object', (nameH) => {\n const objectName = vm.getString(nameH);\n const wrap = vm.newObject();\n const READ = ['find', 'findOne', 'count', 'aggregate'] as const;\n const WRITE = ['insert', 'update', 'delete', 'updateMany', 'deleteMany', 'upsert'] as const;\n for (const m of READ) installApiMethod(vm, wrap, m, objectName, ctx, caps, 'api.read', origin);\n for (const m of WRITE) installApiMethod(vm, wrap, m, objectName, ctx, caps, 'api.write', origin);\n return wrap;\n });\n vm.setProp(apiObj, 'object', objectFn);\n objectFn.dispose();\n vm.setProp(ctxObj, 'api', apiObj);\n apiObj.dispose();\n\n const logObj = vm.newObject();\n for (const level of ['info', 'warn', 'error'] as const) {\n const fn = vm.newFunction(level, (msgH, dataH) => {\n if (!caps.has('log')) {\n throw new SandboxError(`capability 'log' not granted to ${origin.kind} '${origin.name}'`);\n }\n const msg = vm.getString(msgH);\n const data = dataH ? safeJsonParse(vm.getString(dataH)) : undefined;\n ctx.log?.[level]?.(msg, data);\n return vm.undefined;\n });\n vm.setProp(logObj, level, fn);\n fn.dispose();\n }\n vm.setProp(ctxObj, 'log', logObj);\n logObj.dispose();\n\n const cryptoObj = vm.newObject();\n const uuidFn = vm.newFunction('randomUUID', () => {\n if (!caps.has('crypto.uuid')) {\n throw new SandboxError(`capability 'crypto.uuid' not granted to ${origin.kind} '${origin.name}'`);\n }\n const v = ctx.crypto?.randomUUID?.() ?? cryptoRandomUUID();\n return vm.newString(v);\n });\n vm.setProp(cryptoObj, 'randomUUID', uuidFn);\n uuidFn.dispose();\n vm.setProp(ctxObj, 'crypto', cryptoObj);\n cryptoObj.dispose();\n\n vm.setProp(vm.global, '__ctx', ctxObj);\n ctxObj.dispose();\n }\n}\n\n/**\n * Asyncified host-bound API method.\n *\n * Awaits Promise return values from the host implementation and marshals the\n * resolved value back into the VM. Capability check happens at call time and\n * surfaces inside the VM as a thrown error with a clear diagnostic.\n */\nfunction installApiMethod(\n vm: QuickJSAsyncContext,\n parent: QuickJSHandle,\n method: string,\n objectName: string,\n ctx: ScriptContext,\n caps: Set<HookBodyCapability>,\n required: HookBodyCapability,\n origin: ScriptOrigin,\n): void {\n const fn = vm.newAsyncifiedFunction(method, async (...argHandles) => {\n if (!caps.has(required)) {\n throw new SandboxError(\n `capability '${required}' not granted to ${origin.kind} '${origin.name}' (called ctx.api.object('${objectName}').${method})`,\n );\n }\n const apiAny = ctx.api as Record<string, unknown> | undefined;\n if (!apiAny || typeof apiAny.object !== 'function') {\n throw new SandboxError(`ctx.api unavailable in ${origin.kind} '${origin.name}'`);\n }\n const args = argHandles.map((h) => vm.dump(h));\n const proxy = (apiAny.object as (n: string) => Record<string, unknown>)(objectName);\n const m = proxy[method] as ((...a: unknown[]) => unknown) | undefined;\n if (typeof m !== 'function') {\n throw new SandboxError(`ctx.api.object('${objectName}').${method} not implemented`);\n }\n const ret = await Promise.resolve(m.apply(proxy, args));\n return jsonToHandle(vm, ret);\n });\n vm.setProp(parent, method, fn);\n fn.dispose();\n}\n\n/** Marshal a host JSON-serializable value into a QuickJS handle. */\nfunction jsonToHandle(vm: QuickJSAsyncContext, v: unknown): QuickJSHandle {\n const json = JSON.stringify(v ?? null);\n const r = vm.evalCode(`(${json})`);\n if (r.error) {\n const msg = vm.dump(r.error);\n r.error.dispose();\n throw new SandboxError(`failed to marshal host value: ${formatErr(msg)}`);\n }\n return r.value;\n}\n\nfunction setGlobalJson(vm: QuickJSAsyncContext, name: string, v: unknown): void {\n const json = JSON.stringify(v ?? null);\n const result = vm.evalCode(`(${json})`);\n if (result.error) {\n result.error.dispose();\n return;\n }\n vm.setProp(vm.global, name, result.value);\n result.value.dispose();\n}\n\nfunction setObjectJson(vm: QuickJSAsyncContext, parent: QuickJSHandle, key: string, v: unknown): void {\n const json = JSON.stringify(v ?? null);\n const result = vm.evalCode(`(${json})`);\n if (result.error) {\n result.error.dispose();\n vm.setProp(parent, key, vm.null);\n return;\n }\n vm.setProp(parent, key, result.value);\n result.value.dispose();\n}\n\n/**\n * After the script has settled, dump `globalThis.__ctx.input` so the host can\n * write through any direct property mutations the script performed (e.g.\n * `ctx.input.account_number = 'ABC'`).\n *\n * Returns `undefined` if the read fails for any reason — callers fall back to\n * the script's return value in that case.\n */\nfunction readCtxInputJson(vm: QuickJSAsyncContext): Record<string, unknown> | undefined {\n try {\n const r = vm.evalCode(`JSON.stringify(globalThis.__ctx && globalThis.__ctx.input || null)`);\n if (r.error) {\n r.error.dispose();\n return undefined;\n }\n const s = vm.dump(r.value);\n r.value.dispose();\n if (typeof s !== 'string' || s === 'null') return undefined;\n const parsed = safeJsonParse(s);\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction safeJsonParse(s: string | undefined): unknown {\n if (s === undefined || s === '') return undefined;\n try {\n return JSON.parse(s);\n } catch {\n return s;\n }\n}\n\nfunction cryptoRandomUUID(): string {\n if (typeof globalThis.crypto?.randomUUID === 'function') return globalThis.crypto.randomUUID();\n // RFC 4122 v4 fallback\n const r = () => Math.floor(Math.random() * 0x100000000).toString(16).padStart(8, '0');\n return `${r()}-${r().slice(0, 4)}-4${r().slice(0, 3)}-${r().slice(0, 4)}-${r()}${r().slice(0, 4)}`;\n}\n\nfunction formatErr(err: unknown): string {\n if (err && typeof err === 'object') {\n const o = err as { message?: string; name?: string; stack?: string };\n if (o.message) return `${o.name ?? 'Error'}: ${o.message}`;\n return JSON.stringify(err);\n }\n return String(err);\n}\n\nexport class SandboxError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'SandboxError';\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Hook & Action Body Runner Factory\n *\n * Bridges the metadata-only `Hook.body` / `Action.body` discriminated union\n * (defined in `@objectstack/spec/data/hook-body.zod`) into an executable\n * handler registered on the ObjectQL engine.\n *\n * The runtime owns this bridge — `objectql` itself never imports the\n * sandbox engine, so it can stay light enough to embed in tooling and\n * tests. `AppPlugin` constructs one factory per bundle bind and passes it\n * through `bindHooksToEngine({ bodyRunner })` for hooks, and walks the\n * bundle actions to register them via `engine.registerAction`.\n *\n * Per-invocation flow when a triggered hook fires:\n * 1. ObjectQL calls the wrapped handler with its native `(ctx)` arg.\n * 2. We adapt that engine-context into the sandbox `ScriptContext`\n * shape and proxy `ctx.api.object(...)` to the running ObjectQL\n * proxy bound to the current organization/user.\n * 3. `ScriptRunner.runScript` evaluates the body inside QuickJS with\n * the declared capabilities + timeout.\n * 4. After settle, we write back two kinds of mutations to the host\n * `ctx.input`:\n * a. `result.mutatedInput` — a snapshot of `ctx.input` taken inside\n * the VM, used to propagate direct property writes such as\n * `ctx.input.account_number = 'ABC'`.\n * b. `result.value` — if the script returned an object, it is\n * shallow-merged on top of `mutatedInput` as an explicit patch.\n * Writes go through `Object.assign`, which means the host engine's\n * flat-record Proxy (installed by `wrapDeclarativeHook`) sees them\n * via its set trap.\n */\n\nimport type { Hook } from '@objectstack/spec/data';\nimport { HookBodySchema } from '@objectstack/spec/data';\nimport type { ScriptRunner, ScriptContext, ScriptResult } from './script-runner.js';\n\ninterface FactoryOptions {\n ql: any;\n appId: string;\n logger?: any;\n}\n\nexport function hookBodyRunnerFactory(\n runner: ScriptRunner,\n opts: FactoryOptions,\n): (hook: Hook) => ((engineCtx: any) => Promise<void>) | undefined {\n return (hook: Hook) => {\n const raw = (hook as any).body;\n if (!raw) return undefined;\n\n const parsed = HookBodySchema.safeParse(raw);\n if (!parsed.success) {\n opts.logger?.warn?.('[BodyRunner] invalid hook.body shape', {\n appId: opts.appId,\n hook: hook.name,\n issues: parsed.error.issues.slice(0, 3),\n });\n return undefined;\n }\n const body = parsed.data;\n\n return async function boundBodyHandler(engineCtx: any): Promise<void> {\n const sandboxCtx = buildSandboxContext(engineCtx, opts.ql);\n try {\n opts.logger?.debug?.('[BodyRunner] hook fired', { appId: opts.appId, hook: hook.name });\n const result = await runner.run(body, sandboxCtx, {\n origin: {\n kind: 'hook',\n name: hook.name,\n object: typeof (hook as any).object === 'string' ? (hook as any).object : undefined,\n },\n timeoutMs: (body as any).timeoutMs ?? 250,\n });\n applyMutationsToInput(engineCtx, result);\n } catch (err: any) {\n opts.logger?.error?.('[BodyRunner] sandboxed hook threw', err, {\n appId: opts.appId,\n hook: hook.name,\n });\n throw err;\n }\n };\n };\n}\n\n/**\n * Action body runner factory.\n *\n * Returns a handler with the shape ObjectQL's `executeAction` expects:\n * `(actionCtx) => Promise<unknown>`. The action's return value bubbles up\n * to the HTTP dispatcher which JSON-serialises it back to the caller.\n */\nexport function actionBodyRunnerFactory(\n runner: ScriptRunner,\n opts: FactoryOptions,\n): (action: { name: string; body?: unknown; object?: string; timeoutMs?: number }) =>\n | ((actionCtx: any) => Promise<unknown>)\n | undefined {\n return (action) => {\n const raw = action.body;\n if (!raw) return undefined;\n\n const parsed = HookBodySchema.safeParse(raw);\n if (!parsed.success) {\n opts.logger?.warn?.('[BodyRunner] invalid action.body shape', {\n appId: opts.appId,\n action: action.name,\n issues: parsed.error.issues.slice(0, 3),\n });\n return undefined;\n }\n const body = parsed.data;\n\n return async function boundActionHandler(actionCtx: any): Promise<unknown> {\n const sandboxCtx = buildActionSandboxContext(actionCtx, opts.ql);\n try {\n opts.logger?.debug?.('[BodyRunner] action fired', {\n appId: opts.appId,\n action: action.name,\n object: action.object,\n });\n const result = await runner.run(body, sandboxCtx, {\n origin: { kind: 'action', name: action.name, object: action.object },\n timeoutMs: (body as any).timeoutMs ?? action.timeoutMs ?? 5000,\n });\n return result.value;\n } catch (err: any) {\n opts.logger?.error?.('[BodyRunner] sandboxed action threw', err, {\n appId: opts.appId,\n action: action.name,\n });\n throw err;\n }\n };\n };\n}\n\nfunction applyMutationsToInput(engineCtx: any, result: ScriptResult): void {\n const target = engineCtx?.input;\n if (!target || typeof target !== 'object') return;\n if (result.mutatedInput && typeof result.mutatedInput === 'object') {\n Object.assign(target, result.mutatedInput);\n }\n if (\n result.value &&\n typeof result.value === 'object' &&\n !Array.isArray(result.value)\n ) {\n Object.assign(target, result.value);\n }\n}\n\nfunction buildEngineRepoFacade(ql: any, objectName: string) {\n // Minimal repository surface that proxies to the raw engine.\n // Actions execute as the system user (no user context at HTTP boundary\n // beyond `actionCtx.user`); ObjectQL's permission middleware will still\n // gate writes via the engine's standard insert/update path.\n return {\n async find(opts?: any) { return ql.find(objectName, opts); },\n async findOne(opts?: any) {\n const rows = await ql.find(objectName, opts);\n return Array.isArray(rows) ? rows[0] ?? null : null;\n },\n async count(opts?: any) {\n if (typeof ql.count === 'function') return ql.count(objectName, opts);\n const rows = await ql.find(objectName, opts);\n return Array.isArray(rows) ? rows.length : 0;\n },\n async insert(data: any) { return ql.insert(objectName, data); },\n async update(data: any, opts?: any) { return ql.update(objectName, data, opts); },\n async upsert(data: any, opts?: any) {\n if (typeof ql.upsert === 'function') return ql.upsert(objectName, data, opts);\n return ql.insert(objectName, data);\n },\n async delete(opts?: any) { return ql.delete(objectName, opts); },\n };\n}\n\nfunction buildSandboxApi(engineCtx: any, ql: any, errLabel: string) {\n const engineApi = engineCtx?.api;\n if (engineApi && typeof engineApi.object === 'function') return engineApi;\n return {\n object: (objectName: string) => {\n if (!ql) throw new Error(`ObjectQL engine unavailable to ${errLabel}`);\n // Prefer the engine's own ScopedContext-based `.object()` when\n // present; otherwise synthesize a minimal repo facade against the\n // engine's CRUD primitives (so the body can call .insert/.find/etc).\n if (typeof ql.object === 'function') {\n try { return ql.object(objectName); } catch { /* fall through */ }\n }\n return buildEngineRepoFacade(ql, objectName);\n },\n };\n}\n\nfunction buildSandboxContext(engineCtx: any, ql: any): ScriptContext {\n const inputSnapshot = unwrapProxyToPlain(engineCtx?.input ?? engineCtx?.doc);\n const previousRaw = engineCtx?.previous ?? engineCtx?.previousDoc;\n return {\n input: inputSnapshot ?? {},\n // Preserve `undefined` for `previous` on insert events so hooks can\n // reliably distinguish create (`!ctx.previous`) from update/delete.\n previous: unwrapProxyToPlain(previousRaw),\n user: engineCtx?.user ?? engineCtx?.session?.user,\n session: engineCtx?.session,\n event: typeof engineCtx?.event === 'string' ? engineCtx.event : undefined,\n object: typeof engineCtx?.object === 'string' ? engineCtx.object : undefined,\n result: engineCtx?.result,\n api: buildSandboxApi(engineCtx, ql, 'hook body'),\n log: engineCtx?.logger,\n crypto: globalThis.crypto,\n };\n}\n\nfunction buildActionSandboxContext(actionCtx: any, ql: any): ScriptContext {\n // Action ctx convention (mirrors http-dispatcher.ts):\n // { record, params, recordId, user, session, engine, services, ... }\n // The script signature is `(input, ctx)` — input gets `params`, ctx gets\n // the full action context.\n const recordId =\n typeof actionCtx?.recordId === 'string'\n ? actionCtx.recordId\n : typeof actionCtx?.record?.id === 'string'\n ? actionCtx.record.id\n : undefined;\n return {\n input: unwrapProxyToPlain(actionCtx?.params ?? {}),\n previous: undefined,\n user: actionCtx?.user ?? actionCtx?.session?.user,\n session: actionCtx?.session,\n object: typeof actionCtx?.object === 'string' ? actionCtx.object : undefined,\n recordId,\n record: unwrapProxyToPlain(actionCtx?.record),\n api: buildSandboxApi(actionCtx, ql, 'action body'),\n log: actionCtx?.logger,\n crypto: globalThis.crypto,\n };\n}\n\n/**\n * Convert a Proxy-wrapped record into a plain object so it round-trips through\n * JSON cleanly. `Object.fromEntries(Object.entries(p))` triggers the proxy's\n * ownKeys + get traps, materialising every visible field.\n */\nfunction unwrapProxyToPlain(v: unknown): Record<string, unknown> | undefined {\n if (v === undefined || v === null) return undefined;\n if (typeof v !== 'object') return undefined;\n if (Array.isArray(v)) return undefined;\n try {\n return Object.fromEntries(Object.entries(v as Record<string, unknown>));\n } catch {\n return undefined;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { Plugin, PluginContext } from '@objectstack/core';\nimport { readEnvWithDeprecation } from '@objectstack/types';\nimport { SeedLoaderService } from './seed-loader.js';\nimport { loadDisabledPackageIds } from './package-state-store.js';\nimport type { IMetadataService, II18nService } from '@objectstack/spec/contracts';\nimport { SystemUserId } from '@objectstack/spec/system';\nimport { QuickJSScriptRunner } from './sandbox/quickjs-runner.js';\nimport { hookBodyRunnerFactory, actionBodyRunnerFactory } from './sandbox/body-runner.js';\n\n/**\n * Optional per-project context attached when AppPlugin is instantiated by the\n * project kernel factory. Required for the `app:registered` / `app:unregistered`\n * hooks that drive the org-scoped `sys_app` catalog. Standalone (single-tenant)\n * usages may omit this — no catalog hooks are emitted in that case.\n */\nexport interface AppPluginProjectContext {\n environmentId: string;\n organizationId: string;\n projectName?: string;\n /** When the app comes from a package installation, the source package id. */\n packageId?: string;\n /** Defaults to 'package' when packageId is set, otherwise 'user'. */\n source?: 'package' | 'user';\n}\n\n/**\n * AppPlugin\n * \n * Adapts a generic App Bundle (Manifest + Runtime Code) into a Kernel Plugin.\n * \n * Responsibilities:\n * 1. Register App Manifest as a service (for ObjectQL discovery)\n * 2. Execute Runtime `onEnable` hook (for code logic)\n * 3. Auto-load i18n translation bundles into the kernel's i18n service\n */\nexport class AppPlugin implements Plugin {\n name: string;\n type = 'app';\n version?: string;\n \n private bundle: any;\n private projectContext?: AppPluginProjectContext;\n /** When true, init/start become no-ops — env has no app payload. */\n private readonly empty: boolean = false;\n\n constructor(bundle: any, projectContext?: AppPluginProjectContext) {\n this.bundle = bundle;\n this.projectContext = projectContext;\n // Support both direct manifest (legacy) and Stack Definition (nested manifest)\n const sys = bundle?.manifest || bundle;\n const appId = sys?.id || sys?.name;\n\n if (!appId) {\n // No app id at all. Two scenarios:\n // (a) Empty environment — the artifact only ships the bootstrap\n // envelope ({ manifest: { plugins, drivers, engines }, functions: [] })\n // with no app categories. We must NOT crash kernel boot\n // here, otherwise every brand-new env returns 500.\n // (b) Malformed envelope where an app payload exists but the\n // caller forgot to pass `manifest`. We throw loudly with\n // diagnostics so the bug surfaces immediately.\n // App-category keys that indicate \"this bundle was supposed to\n // register an app\". `manifest`/`functions` are envelope-level\n // wrappers and don't count.\n const APP_CATEGORY_KEYS = [\n 'objects', 'views', 'apps', 'pages', 'dashboards', 'reports',\n 'flows', 'workflows', 'triggers', 'agents', 'tools', 'skills',\n 'actions', 'permissions', 'roles', 'profiles', 'translations',\n 'sharingRules', 'ragPipelines', 'data', 'emailTemplates',\n ];\n const hasAppPayload = APP_CATEGORY_KEYS.some((k) => {\n const v = (bundle && bundle[k]) ?? (sys && sys[k]);\n return Array.isArray(v) && v.length > 0;\n });\n\n if (!hasAppPayload) {\n // Empty env — degrade to a no-op plugin so kernel boot\n // succeeds. Auth / data routes will still work; there's\n // simply nothing to register.\n this.empty = true;\n const envSlug = projectContext?.environmentId\n ? projectContext.environmentId.slice(0, 8)\n : 'empty';\n this.name = `plugin.app.empty-${envSlug}`;\n return;\n }\n\n // Has app payload but no id — genuine malformed envelope.\n const bundleKeys = bundle && typeof bundle === 'object'\n ? Object.keys(bundle).slice(0, 20).join(',')\n : typeof bundle;\n const sysKeys = sys && typeof sys === 'object'\n ? Object.keys(sys).slice(0, 20).join(',')\n : typeof sys;\n const ctxHint = projectContext\n ? ` projectContext=${JSON.stringify({\n environmentId: projectContext.environmentId,\n packageId: projectContext.packageId,\n source: projectContext.source,\n })}`\n : '';\n throw new Error(\n `[AppPlugin] bundle has app payload but no manifest.id / manifest.name — `\n + `cannot register as a plugin. bundleKeys=[${bundleKeys}] `\n + `sysKeys=[${sysKeys}]${ctxHint}`,\n );\n }\n\n this.name = `plugin.app.${appId}`;\n this.version = sys?.version;\n }\n\n init = async (ctx: PluginContext) => {\n if (this.empty) {\n ctx.logger.debug('[AppPlugin] empty env — no app payload, skipping init', {\n pluginName: this.name,\n });\n return;\n }\n const sys = this.bundle.manifest || this.bundle;\n const appId = sys.id || sys.name;\n\n ctx.logger.info('Registering App Service', { \n appId, \n pluginName: this.name,\n version: this.version \n });\n \n // Register the app manifest directly via the manifest service.\n // This immediately decomposes the manifest into SchemaRegistry entries.\n const servicePayload = this.bundle.manifest\n ? { ...this.bundle.manifest, ...this.bundle }\n : this.bundle;\n\n console.warn(\n `[AppPlugin:init] appId=${appId} keys=${Object.keys(servicePayload).join(',')} flows=${Array.isArray((servicePayload as any).flows) ? (servicePayload as any).flows.length : 'n/a'}`,\n );\n\n // Seed persisted package disable-state into the registry BEFORE the\n // manifest is decomposed, so disabled packages are installed disabled\n // and stay hidden after restart. Honors every later registration path\n // (boot artifact, marketplace rehydrate, import) via the registry's\n // initial-disabled set. Best-effort — never block boot on this.\n try {\n const ql = ctx.getService<{ registry?: { setInitialDisabledPackageIds?: (ids: Iterable<string>) => void } }>('objectql');\n const setter = ql?.registry?.setInitialDisabledPackageIds;\n if (typeof setter === 'function') {\n const disabled = loadDisabledPackageIds(this.projectContext?.environmentId);\n if (disabled.size > 0) {\n setter.call(ql!.registry, disabled);\n ctx.logger.info('[AppPlugin] seeded persisted disabled packages', {\n environmentId: this.projectContext?.environmentId,\n disabled: Array.from(disabled),\n });\n }\n }\n } catch (err) {\n ctx.logger.warn('[AppPlugin] failed to seed persisted package state', {\n error: (err as Error)?.message ?? String(err),\n });\n }\n\n ctx.getService<{ register(m: any): void }>('manifest').register(servicePayload);\n }\n\n start = async (ctx: PluginContext) => {\n if (this.empty) {\n ctx.logger.debug('[AppPlugin] empty env — no app payload, skipping start', {\n pluginName: this.name,\n });\n return;\n }\n const sys = this.bundle.manifest || this.bundle;\n const appId = sys.id || sys.name;\n \n // Execute Runtime Step\n // Retrieve ObjectQL engine from services\n // ctx.getService throws when a service is not registered, so we\n // must use try/catch instead of a null-check.\n let ql: any;\n try {\n ql = ctx.getService('objectql');\n } catch {\n // Service not registered — handled below\n }\n\n if (!ql) {\n ctx.logger.warn('ObjectQL engine service not found', { \n appName: this.name,\n appId \n });\n return;\n }\n\n ctx.logger.debug('Retrieved ObjectQL engine service', { appId });\n\n // Configure datasourceMapping if provided in the stack definition\n if (this.bundle.datasourceMapping && Array.isArray(this.bundle.datasourceMapping)) {\n ctx.logger.info('Configuring datasource mapping rules', {\n appId,\n ruleCount: this.bundle.datasourceMapping.length\n });\n ql.setDatasourceMapping(this.bundle.datasourceMapping);\n }\n\n // Surface code-defined datasources (ADR-0015 Addendum) in the metadata\n // registry so the datasource-admin list returns them alongside any\n // UI-created (`origin:'runtime'`) ones. These are GitOps-managed\n // (declared in `*.datasource.ts`), so they are registered IN MEMORY\n // ONLY — never persisted to the runtime DB store — and stamped\n // `origin:'code'` so the admin service enforces them as read-only.\n // The engine already indexed them for the write gate via registerApp().\n try {\n const dsDefs = this.bundle.datasources;\n const dsList = Array.isArray(dsDefs)\n ? dsDefs\n : dsDefs && typeof dsDefs === 'object'\n ? Object.entries(dsDefs).map(([name, def]) => ({ name, ...(def as any) }))\n : [];\n if (dsList.length > 0) {\n const metadata = ctx.getService('metadata') as\n | { registerInMemory?: (t: string, n: string, d: unknown) => void }\n | undefined;\n if (typeof metadata?.registerInMemory === 'function') {\n for (const ds of dsList) {\n if (!ds?.name) continue;\n metadata.registerInMemory('datasource', ds.name, { ...ds, origin: 'code' });\n }\n ctx.logger.info('Registered code-defined datasources in metadata registry', {\n appId,\n count: dsList.length,\n });\n }\n }\n } catch (err) {\n ctx.logger.warn('[AppPlugin] failed to register code-defined datasources', {\n error: (err as Error)?.message ?? String(err),\n });\n }\n\n // Resolve the runtime hook owner. Modules that declare both a\n // `default` (defineStack(...)) export and a named `onEnable` export\n // hide the named export from `bundle.default`, so we fall back to the\n // top-level bundle when the default doesn't carry the hook.\n const stackBundle = this.bundle.default || this.bundle;\n const runtime: any = (stackBundle && typeof stackBundle.onEnable === 'function')\n ? stackBundle\n : this.bundle;\n\n if (runtime && typeof runtime.onEnable === 'function') {\n ctx.logger.info('Executing runtime.onEnable', { \n appName: this.name,\n appId \n });\n \n // Construct the Host Context (mirroring old ObjectQL.use logic)\n const hostContext = {\n ...ctx,\n ql,\n logger: ctx.logger,\n drivers: {\n register: (driver: any) => {\n ctx.logger.debug('Registering driver via app runtime', { \n driverName: driver.name,\n appId \n });\n ql.registerDriver(driver);\n }\n },\n };\n \n await runtime.onEnable(hostContext);\n ctx.logger.debug('Runtime.onEnable completed', { appId });\n } else {\n ctx.logger.debug('No runtime.onEnable function found', { appId });\n }\n\n // ── Auto-bind declarative Hook metadata ─────────────────────────\n // Hooks declared via `defineStack({ hooks })` (or attached to the\n // bundle by other tooling) are wired into the ObjectQL execution\n // pipeline here, with no boilerplate from user code. Inline\n // function handlers are resolved directly; string-named handlers\n // are looked up in `bundle.functions` (also auto-registered) or in\n // any function previously registered on the engine.\n //\n // Runs AFTER `runtime.onEnable` so user code may still\n // imperatively register additional hooks/functions for advanced\n // cases — both will coexist on the engine.\n try {\n const hooks = collectBundleHooks(this.bundle);\n const functions = collectBundleFunctions(this.bundle);\n if (hooks.length > 0 || Object.keys(functions).length > 0) {\n if (typeof ql.bindHooks === 'function') {\n ql.bindHooks(hooks, {\n packageId: `app:${appId}`,\n functions,\n bodyRunner: hookBodyRunnerFactory(new QuickJSScriptRunner(), {\n ql,\n logger: ctx.logger,\n appId,\n }),\n });\n ctx.logger.info('[AppPlugin] Bound declarative hooks', {\n appId,\n hookCount: hooks.length,\n functionCount: Object.keys(functions).length,\n });\n } else {\n ctx.logger.warn('[AppPlugin] ql.bindHooks unavailable; declarative hooks ignored', {\n appId,\n hookCount: hooks.length,\n });\n }\n }\n } catch (err: any) {\n ctx.logger.error('[AppPlugin] Failed to bind declarative hooks', err as Error, {\n appId,\n });\n }\n\n // ── Auto-register declarative Action handlers ───────────────────\n // Actions with an inline `handler` (or extracted `body`) are wired\n // to the engine here so HTTP `POST /api/v1/actions/<obj>/<name>`\n // can invoke them. Actions without a body are left for legacy\n // imperative `engine.registerAction(...)` registration in user code.\n try {\n const actions = collectBundleActions(this.bundle);\n const actionBodyRunner = actionBodyRunnerFactory(new QuickJSScriptRunner(), {\n ql,\n logger: ctx.logger,\n appId,\n });\n let registered = 0;\n if (actions.length > 0 && typeof ql.registerAction === 'function') {\n for (const action of actions) {\n const handler = actionBodyRunner(action);\n if (!handler) continue;\n const objectKey =\n typeof action.object === 'string' && action.object.length > 0\n ? action.object\n : 'global';\n try {\n ql.registerAction(objectKey, action.name, handler, `app:${appId}`);\n registered++;\n } catch (err: any) {\n ctx.logger.warn('[AppPlugin] Failed to register action body', {\n appId,\n action: action.name,\n object: objectKey,\n error: err?.message ?? String(err),\n });\n }\n }\n }\n if (registered > 0) {\n ctx.logger.info('[AppPlugin] Bound declarative actions', {\n appId,\n actionCount: registered,\n });\n }\n } catch (err: any) {\n ctx.logger.error('[AppPlugin] Failed to bind declarative actions', err as Error, {\n appId,\n });\n }\n\n // ── Auto-register declarative Background Jobs ────────────────────\n // Jobs declared via `defineStack({ jobs })` are scheduled against the\n // running `IJobService` on `kernel:ready` (so the service plugin and\n // ObjectQL engine have had a chance to register). Handler strings are\n // resolved through `collectBundleFunctions(bundle)` — the same\n // registry used by hooks/actions, keeping the surface uniform.\n try {\n const jobs: any[] = Array.isArray(this.bundle.jobs)\n ? this.bundle.jobs\n : Array.isArray((this.bundle.manifest || {}).jobs)\n ? (this.bundle.manifest as any).jobs\n : [];\n if (jobs.length > 0) {\n ctx.hook('kernel:ready', async () => {\n let svc: any;\n try { svc = ctx.getService('job'); } catch { /* not installed */ }\n if (!svc || typeof svc.schedule !== 'function') {\n ctx.logger.warn('[AppPlugin] job service not registered — skipping declarative jobs', {\n appId, jobCount: jobs.length,\n });\n return;\n }\n const fnMap = collectBundleFunctions(this.bundle);\n let ok = 0;\n for (const job of jobs) {\n const jobName: string = job?.name;\n if (!jobName) {\n ctx.logger.warn('[AppPlugin] skipping job without name', { appId, job });\n continue;\n }\n if (job.enabled === false) {\n ctx.logger.debug('[AppPlugin] job disabled — skipping', { appId, job: jobName });\n continue;\n }\n const handler = fnMap[job.handler];\n if (typeof handler !== 'function') {\n ctx.logger.warn('[AppPlugin] job handler not found in bundle.functions — skipping', {\n appId, job: jobName, handler: job.handler,\n });\n continue;\n }\n try {\n await svc.schedule(\n jobName,\n job.schedule,\n async (jobCtx: any) => {\n await handler({ ...jobCtx, jobId: jobName, bundle: this.bundle });\n },\n );\n ok++;\n } catch (err: any) {\n ctx.logger.warn('[AppPlugin] Failed to schedule job', {\n appId, job: jobName, error: err?.message ?? String(err),\n });\n }\n }\n ctx.logger.info('[AppPlugin] Scheduled background jobs', { appId, count: ok });\n });\n }\n } catch (err: any) {\n ctx.logger.error('[AppPlugin] Failed to schedule background-job registration', err as Error, { appId });\n }\n\n // ── Org-Scoped App Catalog Sync ──────────────────────────────────\n // Emit `app:registered` so AppCatalogService (running on the\n // control-plane kernel) can mirror this app into `sys_app`. Skipped\n // for standalone (single-tenant) usages where no project context is\n // attached.\n this.emitCatalogEvent(ctx, 'app:registered', sys);\n\n // ── i18n Translation Loading ─────────────────────────────────────\n // Auto-load translation bundles from the app config into the\n // kernel's i18n service, so discovery and handlers stay consistent.\n await this.loadTranslations(ctx, appId);\n\n // Data Seeding\n // Collect seed data from multiple locations (top-level `data` preferred, `manifest.data` for backward compat)\n const seedDatasets: any[] = [];\n \n // 1. Top-level `data` field (new standard location on ObjectStackDefinition)\n if (Array.isArray(this.bundle.data)) {\n seedDatasets.push(...this.bundle.data);\n }\n \n // 2. Legacy: `manifest.data` (backward compatibility)\n const manifest = this.bundle.manifest || this.bundle;\n if (manifest && Array.isArray(manifest.data)) {\n seedDatasets.push(...manifest.data);\n }\n\n // Object names in seed data are used as-is — no FQN expansion.\n // Under the current naming convention, the object's short name IS\n // the canonical name and the physical table name.\n\n if (seedDatasets.length > 0) {\n ctx.logger.info(`[AppPlugin] Found ${seedDatasets.length} seed datasets for ${appId}`);\n\n // Pass seed datasets through unchanged — object names are canonical\n const normalizedDatasets = seedDatasets\n .filter((d: any) => d.object && Array.isArray(d.records))\n .map((d: any) => ({\n ...d,\n object: d.object,\n }));\n\n // Resolve the seed identity (os.user / os.org) BEFORE any seed\n // runs. Deterministically ensures a non-loginable system user\n // exists so identity-derived seed values (e.g.\n // `owner_id: cel`os.user.id``) resolve at boot — before the\n // first human sign-up. See ensureSeedIdentity().\n const seedIdentity = await this.ensureSeedIdentity(ql, ctx.logger);\n\n // Stash datasets on a kernel service so SecurityPlugin's\n // sys_organization insert hook can replay them per-tenant\n // (Salesforce-sandbox style: every new org gets its own\n // private copy of the artifact's demo data).\n //\n // We also register a `seed-replayer` callable so the\n // SecurityPlugin doesn't need to import @objectstack/runtime\n // (would create a circular workspace dep). The replayer\n // captures the SeedLoaderService closure and exposes a\n // narrow `(orgId) => Promise<summary>` surface.\n try {\n const kernel: any = (ctx as any).kernel;\n const existing = (() => {\n try { return kernel?.getService?.('seed-datasets'); } catch { return undefined; }\n })();\n const merged = Array.isArray(existing)\n ? [...existing, ...normalizedDatasets]\n : normalizedDatasets;\n const registerSvc = (name: string, value: any) => {\n if (kernel?.registerService) kernel.registerService(name, value);\n else if (typeof (ctx as any).registerService === 'function') (ctx as any).registerService(name, value);\n };\n registerSvc('seed-datasets', merged);\n\n const metadataNow = ctx.getService('metadata') as IMetadataService | undefined;\n const loggerRef = ctx.logger;\n const replayer = async (organizationId: string) => {\n if (!organizationId) return { inserted: 0, updated: 0, errors: [] as any[] };\n const md = metadataNow ?? (ctx.getService('metadata') as IMetadataService | undefined);\n if (!md) {\n loggerRef.warn('[seed-replayer] metadata service unavailable');\n return { inserted: 0, updated: 0, errors: [] as any[] };\n }\n const datasetsNow = (() => {\n try { return kernel?.getService?.('seed-datasets'); } catch { return merged; }\n })() ?? merged;\n if (!Array.isArray(datasetsNow) || datasetsNow.length === 0) {\n return { inserted: 0, updated: 0, errors: [] as any[] };\n }\n const seedLoader = new SeedLoaderService(ql, md, loggerRef);\n const { SeedLoaderRequestSchema } = await import('@objectstack/spec/data');\n const request = SeedLoaderRequestSchema.parse({\n datasets: datasetsNow,\n config: {\n defaultMode: 'upsert',\n multiPass: true,\n organizationId,\n // Bind os.user (system identity) and os.org (this\n // tenant) so identity-derived seed values resolve\n // per-org. org.id falls back to organizationId\n // inside the loader when identity.org is absent.\n identity: seedIdentity,\n },\n });\n const result = await seedLoader.load(request);\n return {\n inserted: result.summary.totalInserted,\n updated: result.summary.totalUpdated,\n errors: result.errors,\n };\n };\n registerSvc('seed-replayer', replayer);\n ctx.logger.info(`[Seeder] Registered ${normalizedDatasets.length} datasets + replayer on kernel (total datasets: ${merged.length})`);\n } catch (e: any) {\n ctx.logger.warn('[Seeder] Failed to register seed-datasets/seed-replayer service', { error: e?.message });\n }\n\n // Decide whether to also run the seed inline at AppPlugin\n // start. In multi-tenant mode, the per-org replay (driven\n // by OrgScopingPlugin's sys_organization middleware) is the\n // source of truth — running it here too would create NULL-\n // org rows that pollute reads and need a separate claim\n // step. So we skip it. Single-tenant deployments keep the\n // legacy behaviour: seed immediately at boot so there's\n // always demo data without needing an org insert.\n const multiTenant = String(readEnvWithDeprecation('OS_MULTI_ORG_ENABLED', 'OS_MULTI_TENANT') ?? 'false').toLowerCase() !== 'false';\n if (multiTenant) {\n ctx.logger.info('[Seeder] multi-tenant mode — skipping inline seed; per-org replay will run on sys_organization insert');\n } else {\n // Inline seed budget: large bundles (e.g. CRM Starter's 10\n // datasets) can easily exceed the kernel's plugin-start\n // timeout. We MUST NOT let seed work tear the kernel down —\n // a 500 on /auth and /data is far worse than a delayed seed.\n // Race the actual seed work against a soft budget; if we run\n // out of time, log loudly and let the kernel proceed.\n const seedBudgetMs = Number(process.env.OS_INLINE_SEED_BUDGET_MS ?? 8000);\n const seedPromise = (async () => {\n try {\n const metadata = ctx.getService('metadata') as IMetadataService | undefined;\n if (metadata) {\n const seedLoader = new SeedLoaderService(ql, metadata, ctx.logger);\n const { SeedLoaderRequestSchema } = await import('@objectstack/spec/data');\n const request = SeedLoaderRequestSchema.parse({\n datasets: normalizedDatasets,\n config: { defaultMode: 'upsert', multiPass: true, identity: seedIdentity },\n });\n const result = await seedLoader.load(request);\n const { totalInserted, totalUpdated, totalSkipped, totalErrored } = result.summary;\n if (result.success) {\n ctx.logger.info('[Seeder] Seed loading complete', {\n inserted: totalInserted,\n updated: totalUpdated,\n skipped: totalSkipped,\n errored: totalErrored,\n });\n } else {\n // LOUD FAILURE: dropped records were previously\n // invisible (the summary only logged errors.length and\n // omitted totalErrored). Report the count AND each\n // actionable reason so broken seeds can't pass silently.\n ctx.logger.warn(\n `[Seeder] Seed loading completed with ${totalErrored} dropped record(s) and ${result.errors.length} error(s) for ${appId}`,\n {\n inserted: totalInserted,\n updated: totalUpdated,\n skipped: totalSkipped,\n errored: totalErrored,\n },\n );\n for (const e of result.errors.slice(0, 20)) {\n ctx.logger.warn(`[Seeder] ✗ ${e.message}`);\n }\n if (result.errors.length > 20) {\n ctx.logger.warn(`[Seeder] …and ${result.errors.length - 20} more error(s)`);\n }\n }\n } else {\n // Fallback: basic insert when metadata service is not available\n ctx.logger.debug('[Seeder] No metadata service; using basic insert fallback');\n for (const dataset of normalizedDatasets) {\n ctx.logger.info(`[Seeder] Seeding ${dataset.records.length} records for ${dataset.object}`);\n for (const record of dataset.records) {\n try {\n await ql.insert(dataset.object, record, { context: { isSystem: true } } as any);\n } catch (err: any) {\n ctx.logger.warn(`[Seeder] Failed to insert ${dataset.object} record:`, { error: err.message });\n }\n }\n }\n ctx.logger.info('[Seeder] Data seeding complete.');\n }\n } catch (err: any) {\n // If SeedLoaderService fails (e.g., metadata not available), fall back to basic insert\n ctx.logger.warn('[Seeder] SeedLoaderService failed, falling back to basic insert', { error: err.message });\n for (const dataset of normalizedDatasets) {\n for (const record of dataset.records) {\n try {\n await ql.insert(dataset.object, record, { context: { isSystem: true } } as any);\n } catch (insertErr: any) {\n ctx.logger.warn(`[Seeder] Failed to insert ${dataset.object} record:`, { error: insertErr.message });\n }\n }\n }\n ctx.logger.info('[Seeder] Data seeding complete (fallback).');\n }\n })();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const budget = new Promise<'budget'>((resolve) => {\n timer = setTimeout(() => resolve('budget'), seedBudgetMs);\n });\n const winner = await Promise.race([seedPromise.then(() => 'done' as const), budget]);\n if (timer) clearTimeout(timer);\n if (winner === 'budget') {\n ctx.logger.warn(\n `[Seeder] Inline seed exceeded ${seedBudgetMs}ms budget for ${appId}; continuing in background to avoid blocking kernel start.`,\n );\n // Don't leave the promise unobserved.\n seedPromise.catch((err: any) => {\n ctx.logger.warn('[Seeder] Background seed failed after budget', { appId, error: err?.message ?? String(err) });\n });\n }\n }\n }\n }\n\n stop = async (ctx: PluginContext) => {\n const sys = this.bundle.manifest || this.bundle;\n this.emitCatalogEvent(ctx, 'app:unregistered', sys);\n }\n\n /**\n * Resolve the identity bound to `os.user` / `os.org` for seed CEL values.\n *\n * On a fresh boot there are zero users until the first human sign-up\n * (which the SeedLoader runs *before*), so identity-derived seeds like\n * `owner_id: cel`os.user.id`` had nothing to resolve against and were\n * dropped silently. To make seeds deterministic and self-sufficient we\n * upsert a single non-loginable **system user** (`usr_system`) and bind\n * it as `os.user`.\n *\n * Why a dedicated system user rather than the login admin:\n * - `sys_user` is better-auth-managed and schema-locked (ADR-0010); the\n * password lives in `sys_account`, so a *loginable* admin can only be\n * minted through better-auth (the CLI does this via HTTP sign-up after\n * boot). A raw insert here would bypass those invariants.\n * - `usr_system` is an owner identity only (no credential row), analogous\n * to Salesforce's \"Automated Process\" user. The human admin is created\n * independently and need not be the seed owner.\n *\n * Idempotent: matches by the stable id, inserts once, reuses thereafter.\n * Failures are non-fatal (logged) — records that actually need `os.user`\n * then fail loudly in the loader with an actionable message.\n */\n private async ensureSeedIdentity(\n ql: any,\n logger: PluginContext['logger'],\n ): Promise<{ user: { id: string; role: string; email: string } }> {\n // Deterministic, non-loginable service identity that owns seeded data.\n const SYSTEM_USER_ID = SystemUserId.SYSTEM;\n const SYSTEM_USER_EMAIL = 'system@objectstack.local';\n const identity = { user: { id: SYSTEM_USER_ID, role: 'system', email: SYSTEM_USER_EMAIL } };\n const opts = { context: { isSystem: true } } as any;\n\n try {\n const existing = await (ql as any).find(\n 'sys_user',\n { where: { id: SYSTEM_USER_ID }, limit: 1 },\n opts,\n );\n if (Array.isArray(existing) && existing.length > 0) {\n return identity;\n }\n await (ql as any).insert(\n 'sys_user',\n {\n id: SYSTEM_USER_ID,\n name: 'System',\n email: SYSTEM_USER_EMAIL,\n email_verified: true,\n role: 'system',\n },\n opts,\n );\n logger.info(\n `[Seeder] Provisioned deterministic system user (${SYSTEM_USER_ID}) as seed owner — binds os.user for identity-derived seed values`,\n );\n } catch (err: any) {\n // Non-fatal: identity-dependent records will fail loudly in the\n // loader; identity-free records still seed normally.\n logger.warn('[Seeder] Failed to ensure system seed user; os.user-dependent seeds may be dropped', {\n error: err?.message ?? String(err),\n });\n }\n return identity;\n }\n\n /**\n * Emit a kernel hook so the control-plane `AppCatalogService` can\n * upsert / delete the corresponding `sys_app` row. Silently no-ops\n * when no project context is attached (standalone single-tenant mode)\n * or when the kernel has no `trigger` API available.\n */\n private emitCatalogEvent(ctx: PluginContext, event: 'app:registered' | 'app:unregistered', sys: any): void {\n if (!this.projectContext) return;\n\n const trigger = (ctx as any).trigger;\n if (typeof trigger !== 'function') {\n ctx.logger.debug('[AppPlugin] kernel has no trigger() — skipping catalog hook', { event });\n return;\n }\n\n const appName = sys.name || sys.id;\n if (!appName) return;\n\n const payload = {\n environmentId: this.projectContext.environmentId,\n organizationId: this.projectContext.organizationId,\n projectName: this.projectContext.projectName,\n app: {\n name: appName,\n label: sys.label,\n icon: sys.icon,\n branding: sys.branding,\n isDefault: sys.isDefault ?? sys.is_default,\n active: sys.active !== false,\n },\n source: this.projectContext.source ?? (this.projectContext.packageId ? 'package' : 'user'),\n packageId: this.projectContext.packageId,\n };\n\n try {\n trigger.call(ctx, event, payload);\n } catch (err: any) {\n ctx.logger.warn('[AppPlugin] catalog hook trigger failed', { event, error: err?.message });\n }\n }\n\n /**\n * Auto-load i18n translation bundles from the app config into the\n * kernel's i18n service. Handles both `translations` (array of\n * TranslationBundle) and `i18n` config (default locale, etc.).\n *\n * Gracefully skips when the i18n service is not registered —\n * this keeps AppPlugin resilient across server/dev/mock environments.\n */\n private async loadTranslations(ctx: PluginContext, appId: string): Promise<void> {\n // ctx.getService throws when a service is not registered, so we\n // must use try/catch to gracefully skip when no i18n plugin is loaded.\n let i18nService: II18nService | undefined;\n try {\n i18nService = ctx.getService('i18n') as II18nService;\n } catch {\n // Service not registered — handled below\n }\n\n // Collect translation bundles early to determine if we have data\n const bundles: Array<Record<string, unknown>> = [];\n if (Array.isArray(this.bundle.translations)) {\n bundles.push(...this.bundle.translations);\n }\n const manifest = this.bundle.manifest || this.bundle;\n if (manifest && Array.isArray(manifest.translations) && manifest.translations !== this.bundle.translations) {\n bundles.push(...manifest.translations);\n }\n\n if (!i18nService) {\n if (bundles.length > 0) {\n // Auto-register the in-memory i18n fallback so the bundles\n // we already loaded server-side become discoverable through\n // `getService('i18n')` (used by the REST API to localize\n // view / action / object metadata). Without this step,\n // bundles authored in `defineStack({ translations })` were\n // silently dropped on standalone/dev stacks that didn't\n // explicitly install I18nServicePlugin.\n try {\n const mod = await import('@objectstack/core');\n const createMemoryI18n = (mod as any).createMemoryI18n;\n if (typeof createMemoryI18n === 'function') {\n const fallback = createMemoryI18n();\n (ctx as any).registerService('i18n', fallback);\n i18nService = fallback;\n ctx.logger.info(\n `[i18n] Auto-registered in-memory i18n fallback for \"${appId}\" (${bundles.length} bundle(s) detected). ` +\n 'Install I18nServicePlugin from @objectstack/service-i18n for file-based / production use.'\n );\n }\n } catch (err: any) {\n ctx.logger.warn(\n `[i18n] App \"${appId}\" has ${bundles.length} translation bundle(s) but auto-fallback failed: ${err?.message ?? err}.`\n );\n return;\n }\n if (!i18nService) {\n ctx.logger.warn(\n `[i18n] App \"${appId}\" has ${bundles.length} translation bundle(s) but no i18n service is registered.`\n );\n return;\n }\n } else {\n ctx.logger.debug('[i18n] No i18n service registered; skipping translation loading', { appId });\n return;\n }\n }\n\n // Apply i18n config (default locale, etc.)\n const i18nConfig = this.bundle.i18n || (this.bundle.manifest || this.bundle)?.i18n;\n if (i18nConfig?.defaultLocale && typeof i18nService.setDefaultLocale === 'function') {\n i18nService.setDefaultLocale(i18nConfig.defaultLocale);\n ctx.logger.debug('[i18n] Set default locale', { appId, locale: i18nConfig.defaultLocale });\n }\n\n if (bundles.length === 0) {\n return;\n }\n\n let loadedLocales = 0;\n for (const bundle of bundles) {\n // Each bundle is a TranslationBundle: Record<locale, TranslationData>\n for (const [locale, data] of Object.entries(bundle)) {\n if (data && typeof data === 'object') {\n try {\n i18nService.loadTranslations(locale, data as Record<string, unknown>);\n loadedLocales++;\n } catch (err: any) {\n ctx.logger.warn('[i18n] Failed to load translations', { appId, locale, error: err.message });\n }\n }\n }\n }\n\n // Emit diagnostic when the active i18n service is a fallback/stub\n const svcAny = i18nService as unknown as Record<string, unknown>;\n if (svcAny._fallback || svcAny._dev) {\n ctx.logger.info(\n `[i18n] Loaded ${loadedLocales} locale(s) into in-memory i18n fallback for \"${appId}\". ` +\n 'For production, consider registering I18nServicePlugin from @objectstack/service-i18n.'\n );\n } else {\n ctx.logger.info('[i18n] Loaded translation bundles', { appId, bundles: bundles.length, locales: loadedLocales });\n }\n }\n}\n\n// ─── Bundle hook & function collectors ──────────────────────────────\n// Hooks declared in `defineStack({ hooks })` end up at `bundle.hooks`;\n// some legacy bundles still nest them under `manifest.hooks`. We dedupe\n// (by reference) so the same array isn't bound twice when both shapes\n// happen to point at the same list.\n\n/** Collect declarative `Hook` definitions from a bundle (top-level + manifest). */\nexport function collectBundleHooks(bundle: any): any[] {\n const out: any[] = [];\n const seen = new Set<any>();\n const push = (arr: any) => {\n if (!Array.isArray(arr)) return;\n for (const h of arr) {\n if (h && !seen.has(h)) {\n seen.add(h);\n out.push(h);\n }\n }\n };\n push(bundle?.hooks);\n push(bundle?.manifest?.hooks);\n return out;\n}\n\n/**\n * Collect declarative actions from the bundle. Walks both root-level\n * `actions[]` and per-object `objects[*].actions[]`, attaching the parent\n * object name where applicable so `engine.registerAction(object, name, ...)`\n * sees the correct routing key.\n *\n * Each returned record is a shallow copy with `object` set when the action\n * originated under an object (and not already present on the action itself).\n */\nexport function collectBundleActions(\n bundle: any,\n): Array<{ name: string; object?: string; body?: unknown; type?: string; [k: string]: unknown }> {\n const out: any[] = [];\n const seen = new Set<any>();\n const push = (arr: any, parentObject?: string) => {\n if (!Array.isArray(arr)) return;\n for (const a of arr) {\n if (!a || typeof a !== 'object' || typeof a.name !== 'string') continue;\n if (seen.has(a)) continue;\n seen.add(a);\n const inferredObject =\n typeof a.object === 'string' ? a.object\n : typeof a.objectName === 'string' ? a.objectName\n : parentObject;\n out.push(inferredObject ? { ...a, object: inferredObject } : { ...a });\n }\n };\n push(bundle?.actions);\n push(bundle?.manifest?.actions);\n if (Array.isArray(bundle?.objects)) {\n for (const o of bundle.objects) push(o?.actions, o?.name);\n }\n if (Array.isArray(bundle?.manifest?.objects)) {\n for (const o of bundle.manifest.objects) push(o?.actions, o?.name);\n }\n return out;\n}\n\n/**\n * Collect a name → handler map from `bundle.functions`. Accepted shapes:\n *\n * - `{ functions: { foo: fn, bar: fn } }` ← preferred map form\n * - `{ functions: [{ name: 'foo', handler: fn }] }` ← array of records\n *\n * String-named hook handlers (`Hook.handler: 'foo'`) are resolved against\n * this map (and the engine's persistent function registry).\n */\nexport function collectBundleFunctions(bundle: any): Record<string, (ctx: any) => any> {\n const out: Record<string, (ctx: any) => any> = {};\n const merge = (src: any) => {\n if (!src) return;\n if (Array.isArray(src)) {\n for (const item of src) {\n if (item && typeof item.name === 'string' && typeof item.handler === 'function') {\n out[item.name] = item.handler;\n }\n }\n } else if (typeof src === 'object') {\n for (const [name, fn] of Object.entries(src)) {\n if (typeof fn === 'function') out[name] = fn as any;\n }\n }\n };\n merge(bundle?.functions);\n merge(bundle?.manifest?.functions);\n return out;\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Standalone (runtime-only) stack factory.\n *\n * Builds the minimal plugin list for embedding ObjectStack in another\n * framework: ObjectQL + Driver + Metadata, plus AppPlugin if a compiled\n * artifact is available. No authentication, no Studio data, no control\n * plane — REST routes are served unauthenticated.\n *\n * Auto-detects the appropriate driver from the database URL scheme:\n * - `memory://*` → InMemoryDriver\n * - `postgres[ql]://`, `pg://` → SqlDriver (pg)\n * - `mongodb[+srv]://` → MongoDBDriver (peer-dep `@objectstack/driver-mongodb`)\n * - `file:` / no scheme → SqlDriver (better-sqlite3)\n *\n * Unknown URL schemes throw — we never silently fall back to sqlite, since\n * that historically created bogus directories on disk (e.g. `mongodb:/`)\n * when an unsupported URL was treated as a file path.\n *\n * NOTE: `libsql://` / Turso support is provided by `@objectstack/driver-turso`,\n * which ships separately in the ObjectStack Cloud distribution. The open-core\n * runtime no longer dispatches `libsql://` URLs; cloud builds register the\n * Turso driver via their own stack composition (`cloud-stack.ts`).\n */\n\nimport { resolve as resolvePath } from 'node:path';\nimport { mkdirSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { z } from 'zod';\nimport { readEnvWithDeprecation } from '@objectstack/types';\nimport { loadArtifactBundle, isHttpUrl } from './load-artifact-bundle.js';\n\n/**\n * Resolve the ObjectStack home directory used to store cwd-independent\n * runtime data (default sqlite database, downloaded marketplace apps,\n * installed plugin cache).\n *\n * Resolution order:\n * 1. `OS_HOME` env var (absolute path; `~` expanded)\n * 2. `~/.objectstack` (cross-platform user-home default)\n *\n * The directory is created lazily by callers that actually write to it\n * (e.g. the sqlite driver's `mkdirSync(...)`); this helper does not\n * touch the filesystem.\n */\nexport function resolveObjectStackHome(): string {\n const raw = process.env.OS_HOME?.trim();\n if (raw && raw.length > 0) {\n if (raw.startsWith('~')) return resolvePath(homedir(), raw.slice(1).replace(/^[/\\\\]/, ''));\n return resolvePath(raw);\n }\n return resolvePath(homedir(), '.objectstack');\n}\n\nexport const StandaloneStackConfigSchema = z.object({\n databaseUrl: z.string().optional(),\n databaseAuthToken: z.string().optional(),\n databaseDriver: z.enum(['sqlite', 'sqlite-wasm', 'memory', 'postgres', 'mongodb']).optional(),\n environmentId: z.string().optional(),\n artifactPath: z.string().optional(),\n /**\n * Project root directory. When set (typically by the CLI after locating\n * `objectstack.config.ts`), the default sqlite database is placed under\n * `<projectRoot>/.objectstack/data/standalone.db` instead of the global\n * `~/.objectstack/data/standalone.db`. This keeps per-project data\n * scoped to the project folder so different examples / apps don't\n * share a single database by accident.\n *\n * Explicit `databaseUrl` / `OS_DATABASE_URL` / `OS_HOME` still take\n * precedence over this default.\n */\n projectRoot: z.string().optional(),\n});\n\nexport type StandaloneStackConfig = z.input<typeof StandaloneStackConfigSchema>;\n\nexport interface StandaloneStackResult {\n plugins: any[];\n api: { enableProjectScoping: false; projectResolution: 'none' };\n /**\n * Top-level metadata copied from the loaded artifact bundle (when an\n * artifact was successfully loaded). These are surfaced so callers\n * that wrap this result as a `defineStack()`-shaped config (e.g. the\n * CLI's `serve` command without a host `objectstack.config.ts`) can\n * still drive tier resolution, capability detection and driver\n * auto-registration off the artifact's declarations.\n */\n requires?: string[];\n objects?: any[];\n manifest?: any;\n}\n\ntype ResolvedDriverKind = 'memory' | 'postgres' | 'mongodb' | 'sqlite' | 'sqlite-wasm';\n\nfunction detectDriverFromUrl(dbUrl: string): ResolvedDriverKind {\n if (/^memory:\\/\\//i.test(dbUrl)) return 'memory';\n if (/^(postgres(ql)?|pg):\\/\\//i.test(dbUrl)) return 'postgres';\n if (/^mongodb(\\+srv)?:\\/\\//i.test(dbUrl)) return 'mongodb';\n if (/^wasm-sqlite:\\/\\//i.test(dbUrl)) return 'sqlite-wasm';\n if (/\\.wasm\\.db$/i.test(dbUrl)) return 'sqlite-wasm';\n if (/^file:/i.test(dbUrl)) return 'sqlite';\n // Bare path without a scheme — treat as a sqlite file path.\n if (!/^[a-z][a-z0-9+.-]*:\\/\\//i.test(dbUrl)) return 'sqlite';\n throw new Error(\n `[StandaloneStack] Unsupported database URL scheme: ${dbUrl}. ` +\n `Supported schemes: memory://, postgres://, pg://, mongodb://, mongodb+srv://, file:`\n );\n}\n\nexport async function createStandaloneStack(config?: StandaloneStackConfig): Promise<StandaloneStackResult> {\n const cfg = StandaloneStackConfigSchema.parse(config ?? {});\n\n const { ObjectQLPlugin } = await import('@objectstack/objectql');\n const { MetadataPlugin } = await import('@objectstack/metadata');\n const { DriverPlugin } = await import('./driver-plugin.js');\n const { AppPlugin } = await import('./app-plugin.js');\n\n const cwd = process.cwd();\n const environmentId = cfg.environmentId ?? process.env.OS_ENVIRONMENT_ID ?? 'proj_local';\n const artifactPathInput = cfg.artifactPath\n ?? process.env.OS_ARTIFACT_PATH\n ?? resolvePath(cwd, 'dist/objectstack.json');\n const artifactPath = isHttpUrl(artifactPathInput)\n ? artifactPathInput\n : (artifactPathInput.startsWith('/')\n ? artifactPathInput\n : resolvePath(cwd, artifactPathInput));\n\n const dbUrl = cfg.databaseUrl\n ?? readEnvWithDeprecation('OS_DATABASE_URL', 'DATABASE_URL')?.trim()\n ?? process.env.TURSO_DATABASE_URL?.trim()\n ?? (process.env.OS_HOME?.trim()\n ? `file:${resolvePath(resolveObjectStackHome(), 'data/standalone.db')}`\n : (cfg.projectRoot\n ? `file:${resolvePath(cfg.projectRoot, '.objectstack/data/standalone.db')}`\n : `file:${resolvePath(resolveObjectStackHome(), 'data/standalone.db')}`));\n // `databaseAuthToken` / `OS_DATABASE_AUTH_TOKEN` are preserved in the\n // config schema for cloud builds that compose their own turso driver;\n // the standalone (open-core) runtime no longer consumes them directly.\n const explicitDriver = cfg.databaseDriver\n ?? (process.env.OS_DATABASE_DRIVER?.trim() as ResolvedDriverKind | undefined);\n const dbDriver: ResolvedDriverKind = explicitDriver ?? detectDriverFromUrl(dbUrl);\n\n let driverPlugin: any;\n if (dbDriver === 'memory') {\n const { InMemoryDriver } = await import('@objectstack/driver-memory');\n driverPlugin = new DriverPlugin(new InMemoryDriver());\n } else if (dbDriver === 'postgres') {\n const { SqlDriver } = await import('@objectstack/driver-sql');\n driverPlugin = new DriverPlugin(\n new SqlDriver({\n client: 'pg',\n connection: dbUrl,\n pool: { min: 0, max: 5 },\n }) as any,\n );\n } else if (dbDriver === 'mongodb') {\n // MongoDB driver is an optional peer dependency. Importing it lazily\n // avoids forcing every standalone consumer to install the mongo SDK.\n let MongoDBDriver: any;\n try {\n ({ MongoDBDriver } = await import('@objectstack/driver-mongodb' as any));\n } catch (err: any) {\n throw new Error(\n `[StandaloneStack] mongodb URL detected but @objectstack/driver-mongodb is not installed. ` +\n `Add it as a dependency or pass an explicit driverPlugin. (${err?.message ?? err})`\n );\n }\n driverPlugin = new DriverPlugin(new MongoDBDriver({ url: dbUrl }) as any);\n } else if (dbDriver === 'sqlite-wasm') {\n const { SqliteWasmDriver } = await import('@objectstack/driver-sqlite-wasm' as any);\n const filename = dbUrl\n .replace(/^wasm-sqlite:(\\/\\/)?/i, '')\n .replace(/^file:(\\/\\/)?/i, '');\n if (filename && filename !== ':memory:') {\n mkdirSync(resolvePath(filename, '..'), { recursive: true });\n }\n driverPlugin = new DriverPlugin(\n new SqliteWasmDriver({\n filename: filename || ':memory:',\n persist: filename && filename !== ':memory:' ? 'on-write' : undefined,\n }) as any,\n );\n } else {\n // sqlite\n const { SqlDriver } = await import('@objectstack/driver-sql');\n const filename = dbUrl.replace(/^file:(\\/\\/)?/, '');\n if (!filename || /^[a-z][a-z0-9+.-]*:\\/\\//i.test(filename)) {\n throw new Error(\n `[StandaloneStack] sqlite driver was selected but the URL does not look like a file path: \"${dbUrl}\". ` +\n `Use file:/path/to/db.sqlite, or set OS_DATABASE_DRIVER explicitly.`\n );\n }\n mkdirSync(resolvePath(filename, '..'), { recursive: true });\n driverPlugin = new DriverPlugin(\n new SqlDriver({\n client: 'better-sqlite3',\n connection: { filename },\n useNullAsDefault: true,\n }),\n );\n }\n\n const artifactBundle = await loadArtifactBundle(artifactPath, {\n tag: '[StandaloneStack]',\n unwrapEnvelope: true,\n });\n if (artifactBundle) {\n const flowsCount = Array.isArray(artifactBundle?.flows) ? artifactBundle.flows.length : 'n/a';\n // eslint-disable-next-line no-console\n console.warn(\n `[StandaloneStack] artifact loaded: path=${artifactPath} keys=${Object.keys(artifactBundle).join(',')} flows=${flowsCount}`,\n );\n }\n\n const plugins: any[] = [\n driverPlugin,\n new MetadataPlugin({\n // Source-file scanner OFF — declarative metadata is loaded\n // from the compiled artifact, not from yaml/json files on\n // disk. Scanning would also recursively watch the project\n // root (incl. node_modules), which is expensive and prone\n // to EMFILE.\n watch: false,\n // Artifact-file HMR ON in non-production so edits to\n // `*.view.ts` / `*.flow.ts` (which the CLI dev-mode watcher\n // recompiles into `dist/objectstack.json`) are picked up by\n // the running server WITHOUT requiring a manual restart.\n // Uses polling under the hood (see plugin.ts) to avoid\n // `fs.watch` EMFILE on macOS / busy dev hosts.\n artifactWatch: process.env.NODE_ENV !== 'production',\n environmentId,\n artifactSource: { mode: 'local-file', path: artifactPath },\n }),\n new ObjectQLPlugin({ environmentId }),\n ];\n if (artifactBundle) plugins.push(new AppPlugin(artifactBundle));\n\n // Surface artifact-declared metadata so a caller using this result\n // directly as a `defineStack()`-shaped config (no host\n // `objectstack.config.ts`) can still drive CLI tier resolution\n // and driver auto-registration. We copy *references* — no clone — so\n // the caller can `{ ...originalConfig, ...standaloneStack }` without\n // double-merging large object arrays.\n const requires: string[] | undefined =\n Array.isArray(artifactBundle?.requires)\n ? (artifactBundle.requires.filter((c: unknown) => typeof c === 'string') as string[])\n : undefined;\n const objects: any[] | undefined =\n Array.isArray(artifactBundle?.objects) ? artifactBundle.objects : undefined;\n const manifest: any | undefined = artifactBundle?.manifest;\n\n return {\n plugins,\n api: {\n enableProjectScoping: false,\n projectResolution: 'none',\n },\n ...(requires ? { requires } : {}),\n ...(objects ? { objects } : {}),\n ...(manifest ? { manifest } : {}),\n };\n}\n","/**\n * Pre-seed the OWNING cloud organization into a freshly-provisioned\n * project DB.\n *\n * Why this exists\n * ---------------\n * Every project at the cloud control plane is owned by exactly one\n * `sys_organization` (cloud-side). Mirroring that org into the project\n * DB makes the project's primary org match the cloud team that owns\n * it, so the owner's session resolves an `activeOrganizationId` on\n * first sign-in instead of landing on the empty \"create your first\n * organization\" prompt.\n *\n * Subsequent JIT-provisioned members of the same cloud org get\n * attached to this same row (Phase 2 — claim-driven by the SSO\n * callback).\n *\n * Idempotency\n * -----------\n * Keyed by the cloud `organization_id`. Re-runs across cold-boots are\n * safe no-ops; a row with that id either already exists or gets\n * inserted on the first boot of the project worker.\n */\n\nimport type { ObjectKernel } from '@objectstack/core';\n\nexport interface ProjectOrgSeed {\n /** Cloud `sys_organization.id` of the project's owning org. Reused as the project-side `sys_organization.id` so cross-tier references stay consistent. */\n id: string;\n /** Display name copied from the cloud org. */\n name: string;\n /** URL slug copied from the cloud org. */\n slug?: string | null;\n /** Optional logo URL. */\n logo?: string | null;\n}\n\nconst SYS_ORG = 'sys_organization';\n\n/**\n * Insert the project's owning organization into the project's\n * `sys_organization` table.\n *\n * Returns:\n * - `'inserted'` — the row was newly seeded\n * - `'exists'` — a row with this id already existed (no-op)\n * - `'skipped'` — payload missing required fields (no-op)\n * - `'error'` — an unexpected failure; details logged via `logger.warn`\n * (we never throw — org seed is best-effort)\n */\nexport async function seedProjectOrganization(\n kernel: ObjectKernel,\n seed: ProjectOrgSeed,\n logger?: { info?: (msg: string, ctx?: any) => void; warn?: (msg: string, ctx?: any) => void },\n): Promise<'inserted' | 'exists' | 'skipped' | 'error'> {\n if (!seed?.id || !seed?.name) return 'skipped';\n\n try {\n const ql: any = kernel.getService('objectql');\n if (!ql?.insert || !ql?.find) {\n logger?.warn?.('[seedProjectOrganization] objectql service unavailable', { orgId: seed.id });\n return 'skipped';\n }\n\n try {\n const existing = await ql.find(SYS_ORG, { where: { id: seed.id } } as any);\n const rows = Array.isArray(existing) ? existing : (existing?.value ?? []);\n if (Array.isArray(rows) && rows.length > 0) return 'exists';\n } catch {\n // schema may not be fully synced on first cold-boot; fall\n // through to insert — the DB layer will enforce uniqueness.\n }\n\n const nowIso = new Date().toISOString();\n await ql.insert(SYS_ORG, {\n id: seed.id,\n name: seed.name,\n slug: seed.slug ?? null,\n logo: seed.logo ?? null,\n metadata: null,\n created_at: nowIso,\n });\n\n logger?.info?.('[seedProjectOrganization] org seeded', {\n orgId: seed.id,\n name: seed.name,\n });\n return 'inserted';\n } catch (err: any) {\n logger?.warn?.('[seedProjectOrganization] failed (non-fatal)', {\n orgId: seed.id,\n error: err?.message,\n });\n return 'error';\n }\n}\n\n/**\n * Insert a `sys_member` row linking a user to an organization with a\n * given role. Idempotent on (user_id, organization_id).\n *\n * Used in tandem with `seedProjectOrganization` to bind the project\n * owner to the mirrored cloud org so the owner's first sign-in\n * already resolves an `activeOrganizationId` instead of landing on\n * the empty \"create your first organization\" prompt.\n *\n * Returns the same status enum as the org/owner seed helpers.\n */\nexport async function seedProjectMember(\n kernel: ObjectKernel,\n args: {\n userId: string;\n organizationId: string;\n role?: 'owner' | 'admin' | 'member';\n },\n logger?: { info?: (msg: string, ctx?: any) => void; warn?: (msg: string, ctx?: any) => void },\n): Promise<'inserted' | 'exists' | 'skipped' | 'error'> {\n const { userId, organizationId } = args;\n const role = args.role ?? 'member';\n if (!userId || !organizationId) return 'skipped';\n\n try {\n const ql: any = kernel.getService('objectql');\n if (!ql?.insert || !ql?.find) {\n logger?.warn?.('[seedProjectMember] objectql service unavailable', { userId, organizationId });\n return 'skipped';\n }\n\n try {\n const existing = await ql.find('sys_member', {\n where: { user_id: userId, organization_id: organizationId },\n } as any);\n const rows = Array.isArray(existing) ? existing : (existing?.value ?? []);\n if (Array.isArray(rows) && rows.length > 0) return 'exists';\n } catch {\n // see comment in seedProjectOrganization\n }\n\n const nowIso = new Date().toISOString();\n // sys_member's primary key is generated by the org plugin; we\n // pre-generate a stable id of the form `mem_<short>` to match\n // the existing convention used by the cloud control plane.\n const memId = `mem_${Math.random().toString(36).slice(2, 14)}`;\n await ql.insert('sys_member', {\n id: memId,\n organization_id: organizationId,\n user_id: userId,\n role,\n created_at: nowIso,\n });\n\n logger?.info?.('[seedProjectMember] member seeded', {\n userId,\n organizationId,\n role,\n });\n return 'inserted';\n } catch (err: any) {\n logger?.warn?.('[seedProjectMember] failed (non-fatal)', {\n userId,\n organizationId,\n error: err?.message,\n });\n return 'error';\n }\n}\n","/**\n * Pre-seed the project owner into a freshly-provisioned project DB.\n *\n * Why this exists\n * ---------------\n * When a user creates a project on the cloud control plane, the project\n * gets a brand-new isolated database. On first access, the SSO callback\n * would otherwise treat the project owner as just another anonymous JIT\n * user — no admin role, no membership, no recognition that *this is the\n * person who owns this project*. The owner then has to manually promote\n * themselves via the org membership UI, which is friction the user does\n * not deserve to pay.\n *\n * Worse: better-auth's `accountLinking` safety check rejects implicit\n * link of an unverified local row with an unverified OAuth identity\n * (`error=account_not_linked`). Pre-seeding with `emailVerified: true`\n * (cloud already verified them upstream) makes the link clean.\n *\n * Idempotency\n * -----------\n * The seed is keyed by the cloud `userId`. If a `sys_user` row with that\n * id already exists in the project DB, this is a no-op — safe to call\n * on every cold-boot. SecurityPlugin's `sys_user` insert middleware\n * (mounted by ArtifactKernelFactory) auto-creates the personal\n * organization + `sys_member(owner)` binding as a side effect of the\n * insert, so callers do not need to wire membership themselves.\n */\n\nimport type { ObjectKernel } from '@objectstack/core';\n\nexport interface ProjectOwnerSeed {\n /** Cloud `sys_user.id` of the project creator. Used as the project-side `sys_user.id` so SSO callbacks link by id, not by email-match. */\n userId: string;\n /** Verified email at cloud — copied here so the link check passes without a project-side verification flow. */\n email: string;\n /** Display name; nullable to tolerate users who never set one. */\n name?: string | null;\n /** Avatar URL; nullable. */\n image?: string | null;\n}\n\nconst SYS_USER = 'sys_user';\n\n/**\n * Insert the project owner into the project's `sys_user` table.\n *\n * Returns:\n * - `'inserted'` — the row was newly seeded\n * - `'exists'` — a row with this id already existed (no-op)\n * - `'skipped'` — payload missing required fields (no-op)\n * - `'error'` — an unexpected failure; details logged via `logger.warn`\n * (we never throw — owner seed is best-effort)\n */\nexport async function seedProjectOwner(\n kernel: ObjectKernel,\n seed: ProjectOwnerSeed,\n logger?: { info?: (msg: string, ctx?: any) => void; warn?: (msg: string, ctx?: any) => void },\n): Promise<'inserted' | 'exists' | 'skipped' | 'error'> {\n if (!seed?.userId || !seed?.email) return 'skipped';\n\n try {\n const ql: any = kernel.getService('objectql');\n if (!ql?.insert || !ql?.find) {\n logger?.warn?.('[seedProjectOwner] objectql service unavailable', { userId: seed.userId });\n return 'skipped';\n }\n\n // Idempotency check: bail if the owner is already present. We key\n // off `id` (not email) so re-runs are safe even if the user later\n // changes their cloud email.\n try {\n const existing = await ql.find(SYS_USER, { where: { id: seed.userId } } as any);\n const rows = Array.isArray(existing) ? existing : (existing?.value ?? []);\n if (Array.isArray(rows) && rows.length > 0) return 'exists';\n } catch {\n // `find` may legitimately fail on cold-start before the schema\n // is fully synced. Fall through to the insert — uniqueness will\n // also be enforced at the DB layer.\n }\n\n const nowIso = new Date().toISOString();\n await ql.insert(SYS_USER, {\n id: seed.userId,\n email: seed.email,\n name: seed.name ?? seed.email.split('@')[0] ?? 'Owner',\n image: seed.image ?? null,\n // Cloud already verified the upstream email. Marking it verified\n // here is what unblocks better-auth's accountLinking check on\n // the first SSO callback (alongside the trustedProviders config\n // in plugin-auth/auth-manager.ts).\n email_verified: true,\n created_at: nowIso,\n updated_at: nowIso,\n });\n\n logger?.info?.('[seedProjectOwner] owner seeded', {\n userId: seed.userId,\n email: seed.email,\n });\n return 'inserted';\n } catch (err: any) {\n // Common benign cases: race with another cold-boot, or unique\n // constraint violation if two requests interleave. Log + swallow.\n logger?.warn?.('[seedProjectOwner] failed (non-fatal)', {\n userId: seed.userId,\n error: err?.message,\n });\n return 'error';\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n// Export Kernels\nexport { ObjectKernel } from '@objectstack/core';\n\n// Export Runtime\nexport { Runtime } from './runtime.js';\nexport type { RuntimeConfig } from './runtime.js';\n\n// Export Standalone Stack\nexport { createStandaloneStack, resolveObjectStackHome } from './standalone-stack.js';\nexport type { StandaloneStackConfig, StandaloneStackResult } from './standalone-stack.js';\n\n// Export Default Host (artifact-first, no objectstack.config.ts required)\nexport { createDefaultHostConfig, resolveDefaultArtifactPath } from './default-host.js';\nexport type { DefaultHostConfigOptions, DefaultHostConfigResult } from './default-host.js';\n\n// Export Plugins\nexport { DriverPlugin } from './driver-plugin.js';\nexport { AppPlugin, collectBundleHooks, collectBundleFunctions, collectBundleActions } from './app-plugin.js';\nexport { SeedLoaderService } from './seed-loader.js';\n// External Datasource Federation — boot-validation gate (ADR-0015, Gate 2)\nexport { ExternalValidationPlugin, createExternalValidationPlugin } from './external-validation-plugin.js';\nexport type { ExternalSchemaDriftEvent } from './external-validation-plugin.js';\n// NOTE: the runtime-UI datasource lifecycle host glue (ADR-0015 Addendum —\n// default driver factory + secret binder) was extracted into the private\n// `@objectstack/datasource-admin` package and no longer ships here.\nexport { createDispatcherPlugin } from './dispatcher-plugin.js';\nexport type { DispatcherPluginConfig } from './dispatcher-plugin.js';\nexport { createSystemEnvironmentPlugin, SYSTEM_ENVIRONMENT_ID } from './system-environment-plugin.js';\nexport type { SystemEnvironmentPluginConfig } from './system-environment-plugin.js';\n\n// Export HTTP Server Components\nexport { HttpServer } from './http-server.js';\nexport { HttpDispatcher } from './http-dispatcher.js';\nexport type { HttpProtocolContext, HttpDispatcherResult } from './http-dispatcher.js';\nexport { MiddlewareManager } from './middleware.js';\n\n// ── Security primitives ───────────────────────────────────────────────\n// Adapter-agnostic helpers for response hardening (CSP/HSTS/XCTO/…)\n// and per-IP token-bucket rate limiting. The dispatcher plugin wires\n// security headers automatically; rate limiting is exposed as a\n// primitive so adapters can mount it at the appropriate layer (see\n// `docs/guide/hardening.md`).\nexport {\n buildSecurityHeaders,\n type SecurityHeadersOptions,\n RateLimiter,\n DEFAULT_RATE_LIMITS,\n type RateLimitBucketConfig,\n type RateLimitDecision,\n type RateLimitDefaults,\n type RateLimitStore,\n} from './security/index.js';\n\n// ── Observability primitives ──────────────────────────────────────────\n// Request-id propagation (X-Request-Id + W3C traceparent), pluggable\n// MetricsRegistry, and pluggable ErrorReporter. The dispatcher plugin\n// wraps every route with instrumentation when these are configured;\n// see `docs/guide/observability.md`.\nexport {\n extractRequestId,\n generateRequestId,\n resolveRequestId,\n parseTraceparent,\n formatTraceparent,\n type TraceContext,\n NoopMetricsRegistry,\n InMemoryMetricsRegistry,\n RUNTIME_METRICS,\n type MetricsRegistry,\n type MetricSample,\n NoopErrorReporter,\n InMemoryErrorReporter,\n type ErrorReporter,\n type CapturedError,\n ObservabilityServicePlugin,\n OBSERVABILITY_METRICS_SERVICE,\n OBSERVABILITY_ERRORS_SERVICE,\n resolveMetrics,\n resolveErrorReporter,\n type ObservabilityServicePluginOptions,\n} from './observability/index.js';\n\n// Export Artifact Loader\nexport { loadArtifactBundle, mergeRuntimeModule, isHttpUrl, readArtifactSource } from './load-artifact-bundle.js';\nexport type { LoadArtifactBundleOptions } from './load-artifact-bundle.js';\n\n// ── ObjectOS Cloud Runtime (artifact-fetching shared multi-tenant host) ───────\n// Boot a host process that resolves incoming hostnames to projects and\n// dispatches every request to the matching per-project ObjectKernel. The\n// artifact is fetched either from an HTTP control plane (apps/cloud or\n// the hosted ObjectStack Cloud) or from a local JSON file for single-\n// project dev workflows. See `cloud/objectos-stack.ts`.\nexport { createObjectOSStack } from './cloud/objectos-stack.js';\nexport type { ObjectOSStackConfig, ObjectOSStackResult } from './cloud/objectos-stack.js';\nexport { MarketplaceProxyPlugin } from './cloud/marketplace-proxy-plugin.js';\nexport type { MarketplaceProxyPluginConfig } from './cloud/marketplace-proxy-plugin.js';\nexport { MarketplaceInstallLocalPlugin } from './cloud/marketplace-install-local-plugin.js';\nexport type { MarketplaceInstallLocalPluginConfig } from './cloud/marketplace-install-local-plugin.js';\nexport { RuntimeConfigPlugin } from './cloud/runtime-config-plugin.js';\nexport type { RuntimeConfigPluginConfig } from './cloud/runtime-config-plugin.js';\nexport { DEFAULT_CLOUD_URL, resolveCloudUrl } from './cloud/cloud-url.js';\nexport { ArtifactApiClient } from './cloud/artifact-api-client.js';\nexport type {\n ArtifactApiClientConfig,\n EnvironmentArtifactResponse,\n EnvironmentRuntimeConfig,\n ResolvedHostname,\n} from './cloud/artifact-api-client.js';\nexport { FileArtifactApiClient } from './cloud/file-artifact-api-client.js';\nexport type { FileArtifactApiClientConfig } from './cloud/file-artifact-api-client.js';\nexport { ArtifactEnvironmentRegistry } from './cloud/artifact-environment-registry.js';\nexport type { ArtifactEnvironmentRegistryConfig } from './cloud/artifact-environment-registry.js';\nexport { ArtifactKernelFactory } from './cloud/artifact-kernel-factory.js';\nexport type { ArtifactKernelFactoryConfig } from './cloud/artifact-kernel-factory.js';\nexport { AuthProxyPlugin } from './cloud/auth-proxy-plugin.js';\nexport { KernelManager } from './cloud/kernel-manager.js';\nexport type { EnvironmentKernelFactory, KernelManagerConfig } from './cloud/kernel-manager.js';\nexport type { EnvironmentDriverRegistry } from './cloud/environment-registry.js';\nexport {\n PLATFORM_SSO_PROVIDER_ID,\n derivePlatformSsoClientId,\n derivePlatformSsoClientSecret,\n buildPlatformSsoRedirectUri,\n seedPlatformSsoClient,\n backfillPlatformSsoClients,\n} from './cloud/platform-sso.js';\nexport type {\n SeedPlatformSsoClientOptions,\n BackfillPlatformSsoClientsOptions,\n} from './cloud/platform-sso.js';\n\n// Export Sandbox (script body runner) — engine choice is quickjs-emscripten.\n// See packages/runtime/src/sandbox/script-runner.ts for the decision rationale.\nexport { UnimplementedScriptRunner, QuickJSScriptRunner, SandboxError, hookBodyRunnerFactory, actionBodyRunnerFactory } from './sandbox/index.js';\nexport type {\n ScriptRunner,\n ScriptContext,\n ScriptOrigin,\n ScriptResult,\n ScriptRunOptions,\n QuickJSScriptRunnerOptions,\n} from './sandbox/index.js';\n\n// Re-export from @objectstack/rest\nexport {\n RestServer,\n RouteManager,\n RouteGroupBuilder,\n createRestApiPlugin,\n} from '@objectstack/rest';\nexport type {\n RouteEntry,\n RestApiPluginConfig,\n} from '@objectstack/rest';\n\n// Export Types\nexport * from '@objectstack/core';\nexport { readEnvWithDeprecation, _resetEnvDeprecationWarnings } from '@objectstack/types';\n\n\n\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectKernel, Plugin, IHttpServer, ObjectKernelConfig } from '@objectstack/core';\nimport {\n ClusterServicePlugin,\n MetadataClusterBridgePlugin,\n type ClusterServicePluginOptions,\n} from '@objectstack/service-cluster';\nimport type { ClusterCapabilityConfigInput } from '@objectstack/spec/kernel';\n\nexport interface RuntimeConfig {\n /**\n * Optional existing server instance (e.g. Hono, Express app)\n * If provided, Runtime will use it as the 'http.server' service.\n * If not provided, Runtime expects a server plugin (like HonoServerPlugin) to be registered manually.\n */\n server?: IHttpServer;\n\n /**\n * Kernel Configuration\n */\n kernel?: ObjectKernelConfig;\n\n /**\n * Cluster service configuration.\n *\n * - Omit (default): a single-node `memory` cluster is auto-registered.\n * - `false`: skip auto-registration entirely. Register your own\n * `ClusterServicePlugin` if you need it later.\n * - `ClusterCapabilityConfigInput`: forwarded to `defineCluster()`.\n * - `{ cluster: IClusterService }`: bring your own instance.\n *\n * See `content/docs/concepts/cluster-semantics.mdx` for driver options.\n */\n cluster?: false | ClusterCapabilityConfigInput | ClusterServicePluginOptions;\n}\n\n/**\n * ObjectStack Runtime\n * \n * High-level entry point for bootstrapping an ObjectStack application.\n * Wraps ObjectKernel and provides standard orchestration for:\n * - HTTP Server binding\n * - Plugin Management\n * \n * REST API is opt-in — register it explicitly:\n * ```ts\n * import { createRestApiPlugin } from '@objectstack/rest';\n * runtime.use(createRestApiPlugin());\n * ```\n */\nexport class Runtime {\n readonly kernel: ObjectKernel;\n \n constructor(config: RuntimeConfig = {}) {\n this.kernel = new ObjectKernel(config.kernel);\n \n // If external server provided, register it immediately\n if (config.server) {\n this.kernel.registerService('http.server', config.server);\n }\n\n // Auto-register cluster service (memory driver by default) unless\n // explicitly opted out. Plugins resolve it via\n // `ctx.getService<IClusterService>('cluster')`.\n if (config.cluster !== false) {\n const opts = this.normalizeClusterOptions(config.cluster);\n this.kernel.use(new ClusterServicePlugin(opts));\n // Bridge metadata cache invalidation across nodes. Late-binds\n // via kernel:ready so it picks up a metadata service whether\n // it's registered by a plugin or directly.\n this.kernel.use(new MetadataClusterBridgePlugin());\n }\n }\n\n private normalizeClusterOptions(\n raw: RuntimeConfig['cluster'],\n ): ClusterServicePluginOptions {\n if (!raw) return {};\n // Discriminate by shape: presence of `cluster` (instance) or\n // explicit `config` key means it's already an options bag.\n if (\n typeof raw === 'object' &&\n ('cluster' in raw || 'config' in raw) &&\n !('driver' in raw)\n ) {\n return raw as ClusterServicePluginOptions;\n }\n // Otherwise treat as `ClusterCapabilityConfigInput`.\n return { config: raw as ClusterCapabilityConfigInput };\n }\n \n /**\n * Register a plugin\n */\n use(plugin: Plugin) {\n this.kernel.use(plugin);\n return this;\n }\n \n /**\n * Start the runtime\n * 1. Initializes all plugins (init phase)\n * 2. Starts all plugins (start phase)\n */\n async start() {\n await this.kernel.bootstrap();\n return this;\n }\n \n /**\n * Get the kernel instance\n */\n getKernel() {\n return this.kernel;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Default host config — built-in fallback used by `objectstack start`\n * (and `objectstack serve`) when the project does NOT ship an explicit\n * `objectstack.config.ts`.\n *\n * Goal: an `objectstack build` artifact (`dist/objectstack.json`) is\n * fully self-describing — it carries the manifest, objects, views,\n * flows and a `requires: [...]` capability list. That should be enough\n * to boot a runtime, with zero hand-written host code.\n *\n * Boot mode: **standalone only**. This module deliberately has zero\n * dependency on the cloud distribution — cloud / multi-environment hosts\n * ship their own bootstrap and write their own `objectstack.config.ts`.\n *\n * Resolution order for the artifact path:\n * 1. `options.artifactPath` (explicit caller override)\n * 2. `OS_ARTIFACT_PATH` env var (file path **or** `http(s)://` URL)\n * 3. `<cwd>/dist/objectstack.json`\n *\n * The returned object is shaped like the result of `defineStack()` —\n * `{ plugins, api, requires, objects, manifest }` — so the CLI can use\n * it interchangeably with a user-authored stack config.\n */\n\nimport { resolve as resolvePath } from 'node:path';\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { createStandaloneStack, resolveObjectStackHome, type StandaloneStackConfig, type StandaloneStackResult } from './standalone-stack.js';\nimport { isHttpUrl } from './load-artifact-bundle.js';\n\nexport interface DefaultHostConfigOptions extends StandaloneStackConfig {\n /**\n * When true (the default), throws if no artifact source can be\n * resolved (no explicit `artifactPath`, no `OS_ARTIFACT_PATH` env,\n * and `<cwd>/dist/objectstack.json` does not exist).\n *\n * Set to false to allow booting an empty kernel — useful for tests\n * that want to assemble plugins manually after the stack is built.\n */\n requireArtifact?: boolean;\n}\n\nexport type DefaultHostConfigResult = StandaloneStackResult;\n\n/**\n * Resolve the artifact source for a default-host boot.\n *\n * Returns the explicit override, then `OS_ARTIFACT_PATH`, then the\n * canonical `<cwd>/dist/objectstack.json` if it exists on disk.\n * Returns `undefined` if none of these are available.\n *\n * URLs (`http(s)://`) are returned as-is — they are validated lazily by\n * the loader, since we cannot stat a remote resource cheaply.\n */\nexport function resolveDefaultArtifactPath(\n explicitPath?: string,\n cwd: string = process.cwd(),\n): string | undefined {\n const candidate = explicitPath\n ?? process.env.OS_ARTIFACT_PATH\n ?? resolvePath(cwd, 'dist/objectstack.json');\n\n if (isHttpUrl(candidate)) return candidate;\n if (explicitPath || process.env.OS_ARTIFACT_PATH) return candidate;\n return existsSync(candidate) ? candidate : undefined;\n}\n\n/**\n * Build a `defineStack()`-shaped config from an `objectstack build`\n * artifact, with no `objectstack.config.ts` required.\n *\n * @example\n * // packages/cli/src/commands/serve.ts\n * if (!fs.existsSync(absolutePath)) {\n * config = await createDefaultHostConfig();\n * }\n */\nexport async function createDefaultHostConfig(\n options: DefaultHostConfigOptions = {},\n): Promise<DefaultHostConfigResult> {\n const { requireArtifact = true, ...standaloneOpts } = options;\n\n let resolvedArtifact = resolveDefaultArtifactPath(standaloneOpts.artifactPath);\n if (!resolvedArtifact && requireArtifact) {\n throw new Error(\n '[createDefaultHostConfig] No artifact source available. ' +\n 'Set OS_ARTIFACT_PATH (file path or http(s):// URL), ' +\n 'place the artifact at <cwd>/dist/objectstack.json, ' +\n 'or pass `{ artifactPath: ... }` explicitly. ' +\n 'To boot an empty kernel anyway, pass `{ requireArtifact: false }`.',\n );\n }\n\n // Empty-boot path: synthesize a minimal artifact stub inside the\n // ObjectStack home directory so MetadataPlugin has a real file to\n // read (and to watch for marketplace installs that land later).\n if (!resolvedArtifact && !requireArtifact) {\n const home = resolveObjectStackHome();\n const stubPath = resolvePath(home, 'dist/objectstack.json');\n if (!existsSync(stubPath)) {\n mkdirSync(resolvePath(stubPath, '..'), { recursive: true });\n writeFileSync(\n stubPath,\n JSON.stringify(\n {\n manifest: {\n id: 'com.objectstack.empty',\n name: 'empty',\n version: '0.0.0',\n type: 'app',\n description: 'Empty starter kernel — install apps via the Studio marketplace.',\n },\n objects: [],\n views: [],\n apps: [],\n flows: [],\n requires: [],\n },\n null,\n 2,\n ),\n 'utf8',\n );\n }\n resolvedArtifact = stubPath;\n }\n\n return createStandaloneStack({\n ...standaloneOpts,\n artifactPath: resolvedArtifact,\n });\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Plugin, PluginContext } from '@objectstack/core';\nimport {\n ExternalSchemaMismatchError,\n type SchemaDiffEntry,\n} from '@objectstack/spec/shared';\n\n/**\n * Structural subset of `IExternalDatasourceService` used here, to avoid a hard\n * dependency on the service package from runtime.\n */\ninterface ExternalDatasourceServiceLike {\n validateAll(): Promise<{\n ok: boolean;\n results: Array<{ ok: boolean; datasource: string; object: string; diffs: SchemaDiffEntry[] }>;\n }>;\n}\n\ninterface MetadataServiceLike {\n get?: (type: string, name: string) => Promise<unknown>;\n list?: (type: string) => Promise<unknown[]>;\n}\n\ninterface DatasourceDef {\n name?: string;\n schemaMode?: string;\n external?: {\n validation?: {\n onMismatch?: 'fail' | 'warn' | 'ignore';\n checkIntervalMs?: number;\n };\n };\n}\n\n/**\n * Payload of the `external.schema.drift` event emitted on the kernel bus by the\n * background drift checker (ADR-0015 §5.2). Consumed by `audit` / `notification`\n * services. One event per drifted federated object.\n */\nexport interface ExternalSchemaDriftEvent {\n datasource: string;\n object: string;\n diffs: SchemaDiffEntry[];\n}\n\n/**\n * Boot-validation plugin — Gate 2 of ADR-0015 §5.2.\n *\n * On `kernel:ready`, validates every federated object against its remote table\n * (via the `external-datasource` service) and applies the datasource's\n * `external.validation.onMismatch` policy:\n * - `fail` → throws `ExternalSchemaMismatchError` (aborts boot) — default,\n * - `warn` → logs the diff and continues,\n * - `ignore` → does nothing.\n *\n * No-op when the `external-datasource` service is not registered (federation\n * unused).\n */\nexport class ExternalValidationPlugin implements Plugin {\n name = 'com.objectstack.external-validation';\n type = 'standard';\n version = '1.0.0';\n\n /** Active background drift-check timers, keyed by datasource name. */\n private driftTimers = new Map<string, ReturnType<typeof setInterval>>();\n\n init = (_ctx: PluginContext): void => {\n // Nothing to register; validation runs on kernel:ready (see start()).\n };\n\n start = (ctx: PluginContext): void => {\n // Subscribe to kernel-ready so validation runs after every plugin (drivers,\n // services, manifests) has been registered.\n ctx.hook('kernel:ready', async () => {\n await this.runValidation(ctx);\n // Boot validation done; arm any background drift checks (ADR-0015 §5.2).\n await this.scheduleDriftChecks(ctx);\n });\n };\n\n /** Tear down background drift-check timers (idempotent). */\n stop = (): void => {\n for (const timer of this.driftTimers.values()) clearInterval(timer);\n this.driftTimers.clear();\n };\n\n /** Exposed for testing; invoked from the kernel:ready handler. */\n async runValidation(ctx: PluginContext): Promise<void> {\n const svc = safeGet<ExternalDatasourceServiceLike>(ctx, 'external-datasource');\n if (!svc?.validateAll) {\n ctx.logger?.debug?.('[external-validation] service not registered; skipping');\n return;\n }\n\n const metadata = safeGet<MetadataServiceLike>(ctx, 'metadata');\n let report: Awaited<ReturnType<ExternalDatasourceServiceLike['validateAll']>>;\n try {\n report = await svc.validateAll();\n } catch (err) {\n ctx.logger?.warn?.('[external-validation] validateAll failed', { err });\n return;\n }\n\n const failures = report.results.filter((r) => !r.ok);\n if (failures.length === 0) {\n ctx.logger?.info?.('[external-validation] all federated objects match their remote schema', {\n objects: report.results.length,\n });\n return;\n }\n\n for (const r of failures) {\n const mode = await resolveOnMismatch(metadata, r.datasource);\n if (mode === 'ignore') continue;\n if (mode === 'warn') {\n ctx.logger?.warn?.('[external-validation] external schema drift', {\n datasource: r.datasource,\n object: r.object,\n diffs: r.diffs,\n });\n continue;\n }\n // mode === 'fail' (default)\n throw new ExternalSchemaMismatchError(r.datasource, r.object, r.diffs);\n }\n }\n\n /**\n * Arm a background drift checker for every federated datasource that declares\n * `external.validation.checkIntervalMs`. Each fires on its own interval and\n * emits `external.schema.drift` events — it never throws or aborts the\n * process, since drift past boot is observational, not fatal.\n *\n * No-op when metadata can't be enumerated or no datasource opts in. Re-arming\n * (e.g. a second `kernel:ready`) first clears existing timers so intervals\n * don't accumulate.\n */\n async scheduleDriftChecks(ctx: PluginContext): Promise<void> {\n this.stop();\n const metadata = safeGet<MetadataServiceLike>(ctx, 'metadata');\n if (!metadata?.list) return;\n\n let datasources: unknown[];\n try {\n datasources = await metadata.list('datasource');\n } catch (err) {\n ctx.logger?.warn?.('[external-validation] could not list datasources for drift checks', { err });\n return;\n }\n\n for (const def of datasources as DatasourceDef[]) {\n const interval = def?.external?.validation?.checkIntervalMs;\n const name = def?.name;\n if (!name || typeof interval !== 'number' || interval <= 0) continue;\n\n const timer = setInterval(() => {\n // Fire-and-forget: the checker swallows its own errors.\n void this.runDriftCheck(ctx, name);\n }, interval);\n // Don't let the drift timer keep the process alive on its own.\n (timer as { unref?: () => void }).unref?.();\n this.driftTimers.set(name, timer);\n ctx.logger?.info?.('[external-validation] armed background drift check', {\n datasource: name,\n intervalMs: interval,\n });\n }\n }\n\n /**\n * Re-validate one datasource's federated objects and emit an\n * `external.schema.drift` event per mismatch. Exposed for testing; invoked\n * from the interval armed by {@link scheduleDriftChecks}. Never throws.\n *\n * @returns the number of drift events emitted.\n */\n async runDriftCheck(ctx: PluginContext, datasource: string): Promise<number> {\n const svc = safeGet<ExternalDatasourceServiceLike>(ctx, 'external-datasource');\n if (!svc?.validateAll) return 0;\n\n let report: Awaited<ReturnType<ExternalDatasourceServiceLike['validateAll']>>;\n try {\n report = await svc.validateAll();\n } catch (err) {\n ctx.logger?.warn?.('[external-validation] drift check validateAll failed', {\n datasource,\n err,\n });\n return 0;\n }\n\n const drifted = report.results.filter((r) => !r.ok && r.datasource === datasource);\n for (const r of drifted) {\n const event: ExternalSchemaDriftEvent = {\n datasource: r.datasource,\n object: r.object,\n diffs: r.diffs,\n };\n try {\n await ctx.trigger('external.schema.drift', event);\n } catch (err) {\n ctx.logger?.warn?.('[external-validation] failed to emit drift event', {\n datasource,\n object: r.object,\n err,\n });\n }\n }\n if (drifted.length > 0) {\n ctx.logger?.warn?.('[external-validation] background drift detected', {\n datasource,\n objects: drifted.map((r) => r.object),\n });\n }\n return drifted.length;\n }\n}\n\n/** Convenience factory mirroring the createXxxPlugin convention. */\nexport function createExternalValidationPlugin(): ExternalValidationPlugin {\n return new ExternalValidationPlugin();\n}\n\nasync function resolveOnMismatch(\n metadata: MetadataServiceLike | undefined,\n datasource: string,\n): Promise<'fail' | 'warn' | 'ignore'> {\n try {\n const ds = (await metadata?.get?.('datasource', datasource)) as DatasourceDef | undefined;\n return ds?.external?.validation?.onMismatch ?? 'fail';\n } catch {\n return 'fail';\n }\n}\n\nfunction safeGet<T>(ctx: PluginContext, name: string): T | undefined {\n try {\n return ctx.getService<T>(name);\n } catch {\n return undefined;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectKernel, getEnv, resolveLocale } from '@objectstack/core';\nimport { CoreServiceName } from '@objectstack/spec/system';\nimport { pluralToSingular, PLURAL_TO_SINGULAR } from '@objectstack/spec/shared';\nimport type { ExecutionContext } from '@objectstack/spec/kernel';\nimport type { KernelManager } from './cloud/kernel-manager.js';\nimport { setPackageDisabled } from './package-state-store.js';\n\n/** Minimal local interface — full EnvironmentScopeManager was removed in Phase R. */\ninterface EnvironmentScopeManager {\n touch(environmentId: string): void;\n}\nimport {\n resolveExecutionContext,\n isPermissionDeniedError,\n} from './security/resolve-execution-context.js';\n\n/** Browser-safe UUID generator — prefers Web Crypto, falls back to RFC 4122 v4 */\nfunction randomUUID(): string {\n if (globalThis.crypto && typeof globalThis.crypto.randomUUID === 'function') {\n return globalThis.crypto.randomUUID();\n }\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\nexport interface HttpProtocolContext {\n request: any;\n response?: any;\n environmentId?: string; // Resolved environment ID\n dataDriver?: any; // IDataDriver - Resolved environment-scoped driver\n /**\n * Identity envelope resolved by `resolveExecutionContext` and threaded\n * into every ObjectQL call so the SecurityPlugin middleware can apply\n * RBAC/RLS/FLS. Optional — anonymous requests carry an empty context.\n */\n executionContext?: ExecutionContext;\n}\n\nexport interface HttpDispatcherResult {\n handled: boolean;\n response?: {\n status: number;\n body?: any;\n headers?: Record<string, string>;\n };\n result?: any; // For flexible return types or direct response objects (Response/NextResponse)\n}\n\n/**\n * Optional configuration passed to the dispatcher constructor. Supports the\n * legacy `enforceProjectMembership` toggle plus the new multi-kernel\n * scheduling hook required by ADR-0003's cloud runtime mode.\n */\nexport interface HttpDispatcherOptions {\n enforceProjectMembership?: boolean;\n /**\n * Optional {@link KernelManager}. When present, the dispatcher resolves\n * `context.environmentId` first and then routes the request against the\n * project's dedicated kernel via `kernelManager.getOrCreate(environmentId)`.\n * Requests that fail to resolve a environmentId fall through to the\n * constructor-supplied kernel (self-hosted / legacy behavior).\n */\n kernelManager?: KernelManager;\n /**\n * Optional {@link EnvironmentScopeManager}. When present, `touch(environmentId)` is\n * called on every scoped request so idle projects are evicted after TTL.\n */\n scopeManager?: EnvironmentScopeManager;\n}\n\n/**\n * @deprecated Use `createDispatcherPlugin()` from `@objectstack/runtime` instead.\n * This class will be removed in v2. Prefer the plugin-based approach:\n * ```ts\n * import { createDispatcherPlugin } from '@objectstack/runtime';\n * kernel.use(createDispatcherPlugin({ prefix: '/api/v1' }));\n * ```\n */\nexport class HttpDispatcher {\n private kernel: any; // Casting to any to access dynamic props like services, graphql\n private defaultKernel: ObjectKernel;\n private envRegistry?: any; // EnvironmentDriverRegistry\n private defaultProject?: { environmentId: string; orgId?: string };\n private kernelManager?: KernelManager;\n private scopeManager?: EnvironmentScopeManager;\n /**\n * When `true`, scoped data-plane routes enforce a\n * `sys_environment_member` lookup and return 403 for non-members.\n * Defaults to `true` when a environmentId is resolvable — legacy callers\n * can opt out via the third constructor argument (see\n * `DispatcherConfig.enforceProjectMembership`).\n */\n private enforceMembership: boolean;\n /**\n * In-memory cache of positive membership checks, keyed by\n * `${environmentId}:${userId}`. Entries expire 60 seconds after insertion\n * — a short TTL is acceptable because a user whose access was just\n * revoked sees stale access for at most one minute.\n */\n private membershipCache: Map<string, number> = new Map();\n private static readonly MEMBERSHIP_CACHE_TTL_MS = 60_000;\n /** Well-known system project id — bypassed for any authenticated user. */\n private static readonly SYSTEM_ENVIRONMENT_ID = '00000000-0000-0000-0000-000000000001';\n /** Well-known platform org id — members bypass project membership. */\n private static readonly PLATFORM_ORG_ID = '00000000-0000-0000-0000-000000000000';\n\n constructor(kernel: ObjectKernel, envRegistry?: any, options?: HttpDispatcherOptions) {\n this.kernel = kernel;\n this.defaultKernel = kernel;\n const resolveService = (name: string): any => {\n try { return (kernel as any).getService?.(name); } catch { return undefined; }\n };\n this.envRegistry = envRegistry ?? resolveService('env-registry');\n this.enforceMembership = options?.enforceProjectMembership ?? true;\n this.kernelManager = options?.kernelManager ?? resolveService('kernel-manager');\n this.scopeManager = options?.scopeManager ?? resolveService('scope-manager');\n // Single-project default is resolved lazily on first request — the\n // plugin that registers it (`createSingleEnvironmentPlugin`) may run\n // its `init()` after the HttpDispatcher is constructed.\n }\n\n private resolveDefaultProject(): { environmentId: string; orgId?: string } | undefined {\n if (this.defaultProject) return this.defaultProject;\n try {\n const v = (this.kernel as any).getService?.('default-project');\n if (v?.environmentId) {\n this.defaultProject = v;\n return v;\n }\n } catch {\n // service not registered — single-environment plugin not in stack\n }\n return undefined;\n }\n\n private success(data: any, meta?: any) {\n return {\n status: 200,\n body: { success: true, data, meta }\n };\n }\n\n private error(message: string, code: number = 500, details?: any) {\n return {\n status: code,\n body: { success: false, error: { message, code, details } }\n };\n }\n\n /**\n * 404 Route Not Found — no route is registered for this path.\n */\n private routeNotFound(route: string) {\n return {\n status: 404,\n body: {\n success: false,\n error: {\n code: 404,\n message: `Route Not Found: ${route}`,\n type: 'ROUTE_NOT_FOUND' as const,\n route,\n hint: 'No route is registered for this path. Check the API discovery endpoint for available routes.',\n },\n },\n };\n }\n\n /**\n * Direct data service dispatch — replaces broker.call('data.*').\n * Tries protocol service first (supports expand/populate), falls back to ObjectQL.\n *\n * @param dataDriver - Optional environment-scoped driver to use instead of kernel default\n * @param scopeId - Optional project ID for scoped service resolution (SharedProjectPlugin mode)\n */\n private async callData(\n action: string,\n params: any,\n dataDriver?: any,\n scopeId?: string,\n executionContext?: ExecutionContext,\n ): Promise<any> {\n const protocol = await this.resolveService('protocol', scopeId);\n const qlService = dataDriver ?? await this.getObjectQLService(scopeId);\n const ql = qlService ?? await this.resolveService('objectql', scopeId);\n const qlOpts = executionContext ? { context: executionContext } : undefined;\n const findOpts = (extra?: any) => {\n const base = qlOpts ? { ...qlOpts } : {};\n return extra ? { ...base, ...extra } : (qlOpts ? base : undefined);\n };\n\n if (action === 'create') {\n if (ql) {\n const res = await ql.insert(params.object, params.data, qlOpts);\n const record = { ...params.data, ...res };\n return { object: params.object, id: record.id, record };\n }\n throw { statusCode: 503, message: 'Data service not available' };\n }\n\n if (action === 'get') {\n if (protocol && typeof protocol.getData === 'function') {\n return await protocol.getData({ object: params.object, id: params.id, expand: params.expand, select: params.select, context: executionContext });\n }\n if (ql) {\n let all = await ql.find(params.object, findOpts({ where: { id: params.id }, limit: 1 }));\n if (all && (all as any).value) all = (all as any).value;\n if (!all) all = [];\n const match = (all as any[]).find((i: any) => i.id === params.id);\n return match ? { object: params.object, id: params.id, record: match } : null;\n }\n throw { statusCode: 503, message: 'Data service not available' };\n }\n\n if (action === 'update') {\n if (ql && params.id) {\n let all = await ql.find(params.object, findOpts({ where: { id: params.id }, limit: 1 }));\n if (all && (all as any).value) all = (all as any).value;\n if (!all) all = [];\n const existing = (all as any[]).find((i: any) => i.id === params.id);\n if (!existing) throw new Error('[ObjectStack] Not Found');\n await ql.update(params.object, params.data, findOpts({ where: { id: params.id } }));\n return { object: params.object, id: params.id, record: { ...existing, ...params.data } };\n }\n throw { statusCode: 503, message: 'Data service not available' };\n }\n\n if (action === 'delete') {\n if (ql) {\n await ql.delete(params.object, findOpts({ where: { id: params.id } }));\n return { object: params.object, id: params.id, deleted: true };\n }\n throw { statusCode: 503, message: 'Data service not available' };\n }\n\n if (action === 'query' || action === 'find') {\n if (protocol && typeof protocol.findData === 'function') {\n // Build query: use explicit params.query if provided, otherwise extract query fields from params\n const query = params.query || (() => {\n const { object, ...rest } = params;\n return rest;\n })();\n return await protocol.findData({ object: params.object, query, context: executionContext });\n }\n if (ql) {\n let all = await ql.find(params.object, qlOpts);\n if (!Array.isArray(all) && all && (all as any).value) all = (all as any).value;\n if (!all) all = [];\n return { object: params.object, records: all, total: all.length };\n }\n throw { statusCode: 503, message: 'Data service not available' };\n }\n\n if (action === 'batch') {\n // Batch operations — not yet supported via direct service dispatch\n return { object: params.object, results: [] };\n }\n\n throw { statusCode: 400, message: `Unknown data action: ${action}` };\n }\n\n /**\n * Parse a project UUID out of a scoped URL path such as\n * `/api/v1/environments/abc-123/data/task` or `/projects/abc-123/meta`.\n * Returns `undefined` when the path does not match the scoped pattern.\n */\n /**\n * Parse an environment UUID out of a scoped URL path such as\n * `/api/v1/environments/abc-123/data/task` or `/environments/abc-123/meta`.\n * Returns `undefined` when the path does not match the scoped pattern.\n */\n private extractEnvironmentIdFromPath(path: string): string | undefined {\n if (!path) return undefined;\n const m = path.match(/\\/environments\\/([^/?#]+)/);\n if (!m) return undefined;\n const candidate = m[1];\n // Guard against matching control-plane routes like /cloud/environments.\n // `/environments/<id>` directly nested under the API prefix wins;\n // `/cloud/environments/<id>` is a CRUD endpoint on the control plane.\n if (path.includes('/cloud/environments/')) return undefined;\n return candidate;\n }\n\n /**\n * Resolve environment context for incoming request.\n *\n * Precedence:\n * 0. URL path matches `/environments/:environmentId/...` OR request.params.environmentId set by router\n * → envRegistry.resolveById(id)\n * 1. request.headers.host → envRegistry.resolveByHostname(host)\n * 2. request.headers['x-environment-id'] → envRegistry.resolveById(id)\n * 3. session.activeEnvironmentId → envRegistry.resolveById(id)\n * 4. session.activeOrganizationId → find default project → envRegistry.resolveById(id)\n * 5. single-environment default (registered by `createSingleEnvironmentPlugin`)\n * → envRegistry.resolveById(defaultProject.environmentId). Lets bare\n * `/api/v1/data/...` URLs resolve to the lone project in\n * `cloudUrl: 'local'` deployments.\n *\n * Skip for paths: /auth, /cloud, /health, /discovery (NOT /meta when scoped,\n * so project-scoped meta routes can resolve their project).\n */\n private async resolveEnvironmentContext(context: HttpProtocolContext, path: string): Promise<void> {\n // Skip environment resolution for control-plane routes only.\n // NOTE: /meta is intentionally not in this list — a scoped\n // /projects/:id/meta path still needs the project resolved so the\n // protocol can scope its answer.\n // NOTE: /auth was removed — per-project AuthPlugin needs the\n // hostname-resolved environmentId so the dispatcher kernel-swap routes\n // to the project's auth manager (not the host's).\n const skipPaths = ['/cloud', '/health', '/discovery'];\n if (skipPaths.some(p => path.startsWith(p))) {\n return;\n }\n\n // If no environment registry, skip\n if (!this.envRegistry) {\n return;\n }\n\n // Headers may arrive as a Fetch API `Headers` instance (Hono's\n // `c.req.raw`) — where `.host` / `['x-environment-id']` both return\n // undefined — or as a plain object (Vercel's incoming message\n // shape). Normalise to a single `.get(name)` accessor so both\n // layouts resolve correctly.\n const headers = context.request?.headers;\n const getHeader = (name: string): string | undefined => {\n if (!headers) return undefined;\n const h: any = headers;\n if (typeof h.get === 'function') {\n const v = h.get(name);\n return v == null ? undefined : String(v);\n }\n const lower = name.toLowerCase();\n for (const k of Object.keys(h)) {\n if (k.toLowerCase() === lower) {\n const v = h[k];\n return Array.isArray(v) ? v[0] : (v == null ? undefined : String(v));\n }\n }\n return undefined;\n };\n\n try {\n // 0. Try URL-param / path-embedded environmentId (highest precedence).\n const urlEnvironmentId = this.extractEnvironmentIdFromPath(path)\n ?? context.request?.params?.environmentId;\n if (urlEnvironmentId) {\n const driver = await this.envRegistry.resolveById(urlEnvironmentId);\n if (driver) {\n context.environmentId = urlEnvironmentId;\n context.dataDriver = driver;\n return;\n }\n }\n\n // 1. Try hostname resolution\n const host = getHeader('host');\n if (host) {\n // Strip port if present (e.g., \"localhost:3000\" → \"localhost\")\n const hostname = host.split(':')[0];\n const result = await this.envRegistry.resolveByHostname(hostname);\n if (result) {\n context.environmentId = result.environmentId;\n context.dataDriver = result.driver;\n return;\n }\n }\n\n // 2. Try X-Environment-Id header\n const envIdHeader = getHeader('x-environment-id');\n if (envIdHeader) {\n const driver = await this.envRegistry.resolveById(envIdHeader);\n if (driver) {\n context.environmentId = envIdHeader;\n context.dataDriver = driver;\n return;\n }\n }\n\n // 3. Try session.activeEnvironmentId\n try {\n const authService: any = await this.getService(CoreServiceName.enum.auth);\n const sessionData = await authService?.api?.getSession?.({\n headers: context.request?.headers,\n });\n\n const activeEnvironmentId = sessionData?.session?.activeEnvironmentId ?? sessionData?.session?.activeEnvironmentId;\n if (activeEnvironmentId) {\n const driver = await this.envRegistry.resolveById(activeEnvironmentId);\n if (driver) {\n context.environmentId = activeEnvironmentId;\n context.dataDriver = driver;\n return;\n }\n }\n\n // 4. Try default environment for organization\n const activeOrganizationId = sessionData?.session?.activeOrganizationId;\n if (activeOrganizationId) {\n // Query control plane for default environment\n const qlService = await this.getObjectQLService();\n const ql = qlService ?? await this.resolveService('objectql');\n if (ql) {\n let rows = await ql.find('sys_environment', {\n where: {\n organization_id: activeOrganizationId,\n is_default: true\n },\n limit: 1\n } as any);\n if (rows && (rows as any).value) rows = (rows as any).value;\n if (Array.isArray(rows) && rows[0]) {\n const defaultEnv = rows[0];\n const driver = await this.envRegistry.resolveById(defaultEnv.id);\n if (driver) {\n context.environmentId = defaultEnv.id;\n context.dataDriver = driver;\n return;\n }\n }\n }\n }\n } catch (sessionError) {\n // Session resolution failed, continue without environment context\n console.debug('[HttpDispatcher] Session resolution failed:', sessionError);\n }\n\n // 5. Single-project default fallback. Registered by\n // `createSingleEnvironmentPlugin()` in `cloudUrl: 'local'` boot\n // shapes (apps/objectos default). Lets bare URLs like\n // `/api/v1/data/account` resolve to the lone project.\n if (this.defaultProject?.environmentId || this.resolveDefaultProject()) {\n const def = this.defaultProject!;\n const driver = await this.envRegistry.resolveById(def.environmentId);\n if (driver) {\n context.environmentId = def.environmentId;\n context.dataDriver = driver;\n return;\n }\n }\n } catch (error) {\n console.error('[HttpDispatcher] Environment resolution failed:', error);\n }\n }\n\n /**\n * Check whether the authenticated user is a member of\n * `context.environmentId`. Runs after {@link resolveEnvironmentContext}\n * and is a no-op when:\n *\n * - Membership enforcement is disabled via the constructor.\n * - The route is control-plane (`/auth/*`, `/cloud/*`, `/health`,\n * `/discovery`) — already skipped upstream.\n * - No `environmentId` was resolved (e.g. unscoped legacy routes).\n * - The project is the well-known system project (bypassed so any\n * authenticated user can read platform metadata).\n * - The user's active organization is the platform org (staff).\n *\n * Positive results are cached for 60 seconds to avoid hitting the\n * control-plane on every request. A failed check returns a 403\n * response object that callers should surface directly — no further\n * dispatch happens.\n */\n private async enforceProjectMembership(\n context: HttpProtocolContext,\n path: string,\n ): Promise<{ status: number; body: any } | null> {\n if (!this.enforceMembership) return null;\n\n // Control-plane paths — never gated by project membership.\n const skipPaths = ['/auth', '/cloud', '/health', '/discovery'];\n if (skipPaths.some(p => path.startsWith(p))) return null;\n\n const environmentId = context.environmentId;\n if (!environmentId) return null; // Unscoped legacy routes fall through.\n\n // System project is always reachable by any authenticated user.\n if (environmentId === HttpDispatcher.SYSTEM_ENVIRONMENT_ID) return null;\n\n // Read the session. If auth is not wired up, fail open — tests\n // and single-tenant setups run without auth.\n let userId: string | undefined;\n let activeOrganizationId: string | undefined;\n try {\n const authService: any = await this.resolveService(CoreServiceName.enum.auth);\n const sessionData = await authService?.api?.getSession?.({\n headers: context.request?.headers,\n });\n userId = sessionData?.user?.id ?? sessionData?.session?.userId;\n activeOrganizationId = sessionData?.session?.activeOrganizationId;\n } catch {\n // Auth resolution failed — do not block the request on RBAC.\n return null;\n }\n\n if (!userId) return null; // Anonymous requests — upstream auth will decide.\n\n // Platform-org members bypass project membership.\n if (activeOrganizationId === HttpDispatcher.PLATFORM_ORG_ID) return null;\n\n // Check cache.\n const cacheKey = `${environmentId}:${userId}`;\n const cached = this.membershipCache.get(cacheKey);\n const now = Date.now();\n if (cached && now - cached < HttpDispatcher.MEMBERSHIP_CACHE_TTL_MS) {\n return null; // Recently verified as a member.\n }\n if (cached) {\n this.membershipCache.delete(cacheKey); // expired\n }\n\n // Query sys_environment_member (control plane).\n try {\n const qlService = await this.getObjectQLService();\n const ql = qlService ?? await this.resolveService('objectql');\n if (!ql) return null; // No QL — cannot enforce; fail open.\n\n let rows = await ql.find('sys_environment_member', {\n where: { environment_id: environmentId, user_id: userId },\n limit: 1,\n } as any);\n if (rows && (rows as any).value) rows = (rows as any).value;\n const isMember = Array.isArray(rows) && rows.length > 0;\n\n if (isMember) {\n this.membershipCache.set(cacheKey, now);\n return null;\n }\n\n return this.error(\n `Forbidden: user ${userId} is not a member of project ${environmentId}`,\n 403,\n { environmentId, userId, type: 'PROJECT_MEMBERSHIP_REQUIRED' },\n );\n } catch (err) {\n // Control-plane lookup failure — log and fail open rather than\n // break the request. Tightening this is deferred to Phase 4.\n console.debug('[HttpDispatcher] Membership check failed:', err);\n return null;\n }\n }\n\n /**\n * Generates the discovery JSON response for the API root.\n *\n * Uses the same async `resolveService()` fallback chain that request\n * handlers use, so the reported service status is always consistent\n * with the actual runtime availability.\n */\n async getDiscoveryInfo(prefix: string) {\n // Resolve all services through the same async fallback chain\n // that request handlers (handleI18n, handleAuth, …) use.\n const [\n authSvc, graphqlSvc, searchSvc, realtimeSvc, filesSvc,\n analyticsSvc, workflowSvc, aiSvc, notificationSvc, i18nSvc,\n uiSvc, automationSvc, cacheSvc, queueSvc, jobSvc,\n ] = await Promise.all([\n this.resolveService(CoreServiceName.enum.auth),\n this.resolveService(CoreServiceName.enum.graphql),\n this.resolveService(CoreServiceName.enum.search),\n this.resolveService(CoreServiceName.enum.realtime),\n this.resolveService(CoreServiceName.enum['file-storage']),\n this.resolveService(CoreServiceName.enum.analytics),\n this.resolveService(CoreServiceName.enum.workflow),\n this.resolveService(CoreServiceName.enum.ai),\n this.resolveService(CoreServiceName.enum.notification),\n this.resolveService(CoreServiceName.enum.i18n),\n this.resolveService(CoreServiceName.enum.ui),\n this.resolveService(CoreServiceName.enum.automation),\n this.resolveService(CoreServiceName.enum.cache),\n this.resolveService(CoreServiceName.enum.queue),\n this.resolveService(CoreServiceName.enum.job),\n ]);\n\n const hasAuth = !!authSvc;\n const hasGraphQL = !!(graphqlSvc || this.kernel.graphql);\n const hasSearch = !!searchSvc;\n const hasWebSockets = !!realtimeSvc;\n const hasFiles = !!filesSvc;\n const hasAnalytics = !!analyticsSvc;\n const hasWorkflow = !!workflowSvc;\n const hasAi = !!aiSvc;\n const hasNotification = !!notificationSvc;\n const hasI18n = !!i18nSvc;\n const hasUi = !!uiSvc;\n const hasAutomation = !!automationSvc;\n const hasCache = !!cacheSvc;\n const hasQueue = !!queueSvc;\n const hasJob = !!jobSvc;\n\n // Routes are only exposed when a plugin provides the service\n const routes = {\n data: `${prefix}/data`,\n metadata: `${prefix}/meta`,\n packages: `${prefix}/packages`,\n auth: hasAuth ? `${prefix}/auth` : undefined,\n ui: hasUi ? `${prefix}/ui` : undefined,\n graphql: hasGraphQL ? `${prefix}/graphql` : undefined,\n storage: hasFiles ? `${prefix}/storage` : undefined,\n analytics: hasAnalytics ? `${prefix}/analytics` : undefined,\n automation: hasAutomation ? `${prefix}/automation` : undefined,\n workflow: hasWorkflow ? `${prefix}/workflow` : undefined,\n realtime: hasWebSockets ? `${prefix}/realtime` : undefined,\n notifications: hasNotification ? `${prefix}/notifications` : undefined,\n ai: hasAi ? `${prefix}/ai` : undefined,\n i18n: hasI18n ? `${prefix}/i18n` : undefined,\n };\n\n // Build per-service status map\n // handlerReady: true means the dispatcher has a real, bound handler for this route.\n // handlerReady: false means the route is present in the discovery table but may not\n // yet have a concrete implementation or may be served by a stub.\n const svcAvailable = (route?: string, provider?: string) => ({\n enabled: true, status: 'available' as const, handlerReady: true, route, provider,\n });\n const svcUnavailable = (name: string) => ({\n enabled: false, status: 'unavailable' as const, handlerReady: false,\n message: `Install a ${name} plugin to enable`,\n });\n\n // Derive locale info from actual i18n service when available\n let locale = { default: 'en', supported: ['en'], timezone: 'UTC' };\n if (hasI18n && i18nSvc) {\n const defaultLocale = typeof i18nSvc.getDefaultLocale === 'function'\n ? i18nSvc.getDefaultLocale() : 'en';\n const locales = typeof i18nSvc.getLocales === 'function'\n ? i18nSvc.getLocales() : [];\n locale = {\n default: defaultLocale,\n supported: locales.length > 0 ? locales : [defaultLocale],\n timezone: 'UTC',\n };\n }\n\n return {\n name: 'ObjectOS',\n version: '1.0.0',\n environment: getEnv('NODE_ENV', 'development'),\n routes,\n endpoints: routes, // Alias for backward compatibility with some clients\n features: {\n graphql: hasGraphQL,\n search: hasSearch,\n websockets: hasWebSockets,\n files: hasFiles,\n analytics: hasAnalytics,\n ai: hasAi,\n workflow: hasWorkflow,\n notifications: hasNotification,\n i18n: hasI18n,\n },\n services: {\n // Kernel-provided (always available via protocol implementation)\n metadata: { enabled: true, status: 'degraded' as const, handlerReady: true, route: routes.metadata, provider: 'kernel', message: 'In-memory registry; DB persistence pending' },\n data: svcAvailable(routes.data, 'kernel'),\n // Plugin-provided — only available when a plugin registers the service\n auth: hasAuth ? svcAvailable(routes.auth) : svcUnavailable('auth'),\n automation: hasAutomation ? svcAvailable(routes.automation) : svcUnavailable('automation'),\n analytics: hasAnalytics ? svcAvailable(routes.analytics) : svcUnavailable('analytics'),\n cache: hasCache ? svcAvailable() : svcUnavailable('cache'),\n queue: hasQueue ? svcAvailable() : svcUnavailable('queue'),\n job: hasJob ? svcAvailable() : svcUnavailable('job'),\n ui: hasUi ? svcAvailable(routes.ui) : svcUnavailable('ui'),\n workflow: hasWorkflow ? svcAvailable(routes.workflow) : svcUnavailable('workflow'),\n realtime: hasWebSockets ? svcAvailable(routes.realtime) : svcUnavailable('realtime'),\n notification: hasNotification ? svcAvailable(routes.notifications) : svcUnavailable('notification'),\n ai: hasAi ? svcAvailable(routes.ai) : svcUnavailable('ai'),\n i18n: hasI18n ? svcAvailable(routes.i18n) : svcUnavailable('i18n'),\n graphql: hasGraphQL ? svcAvailable(routes.graphql) : svcUnavailable('graphql'),\n 'file-storage': hasFiles ? svcAvailable(routes.storage) : svcUnavailable('file-storage'),\n search: hasSearch ? svcAvailable() : svcUnavailable('search'),\n },\n locale,\n };\n }\n\n /**\n * Handles GraphQL requests\n */\n async handleGraphQL(body: { query: string; variables?: any }, context: HttpProtocolContext) {\n if (!body || !body.query) {\n throw { statusCode: 400, message: 'Missing query in request body' };\n }\n \n if (typeof this.kernel.graphql !== 'function') {\n throw { statusCode: 501, message: 'GraphQL service not available' };\n }\n\n return this.kernel.graphql(body.query, body.variables, { \n request: context.request \n });\n }\n\n /**\n * Handles Auth requests\n * path: sub-path after /auth/\n */\n async handleAuth(path: string, method: string, body: any, context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n // 1. Try generic Auth Service\n const authService = await this.getService(CoreServiceName.enum.auth);\n if (authService && typeof authService.handler === 'function') {\n const response = await authService.handler(context.request, context.response);\n return { handled: true, result: response };\n }\n\n // 2. Mock fallback for MSW/test environments when no auth service is registered\n const normalizedPath = path.replace(/^\\/+/, '');\n return this.mockAuthFallback(normalizedPath, method, body);\n }\n\n /**\n * Provides mock auth responses for core better-auth endpoints when\n * AuthPlugin is not loaded (e.g. MSW/browser-only environments).\n * This ensures registration/sign-in flows do not 404 in mock mode.\n */\n private mockAuthFallback(path: string, method: string, body: any): HttpDispatcherResult {\n const m = method.toUpperCase();\n const MOCK_SESSION_EXPIRY_MS = 86_400_000; // 24 hours\n\n // POST sign-up/email\n if ((path === 'sign-up/email' || path === 'register') && m === 'POST') {\n const id = `mock_${randomUUID()}`;\n return {\n handled: true,\n response: {\n status: 200,\n body: {\n user: { id, name: body?.name || 'Mock User', email: body?.email || 'mock@test.local', emailVerified: false, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() },\n session: { id: `session_${id}`, userId: id, token: `mock_token_${id}`, expiresAt: new Date(Date.now() + MOCK_SESSION_EXPIRY_MS).toISOString() },\n },\n },\n };\n }\n\n // POST sign-in/email or login\n if ((path === 'sign-in/email' || path === 'login') && m === 'POST') {\n const id = `mock_${randomUUID()}`;\n return {\n handled: true,\n response: {\n status: 200,\n body: {\n user: { id, name: 'Mock User', email: body?.email || 'mock@test.local', emailVerified: true, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() },\n session: { id: `session_${id}`, userId: id, token: `mock_token_${id}`, expiresAt: new Date(Date.now() + MOCK_SESSION_EXPIRY_MS).toISOString() },\n },\n },\n };\n }\n\n // GET get-session\n if (path === 'get-session' && m === 'GET') {\n return {\n handled: true,\n response: { status: 200, body: { session: null, user: null } },\n };\n }\n\n // POST sign-out\n if (path === 'sign-out' && m === 'POST') {\n return {\n handled: true,\n response: { status: 200, body: { success: true } },\n };\n }\n\n return { handled: false };\n }\n\n /**\n * Handles Metadata requests\n * Standard: /metadata/:type/:name\n * Fallback for backward compat: /metadata (all objects), /metadata/:objectName (get object)\n */\n async handleMetadata(path: string, _context: HttpProtocolContext, method?: string, body?: any, query?: any): Promise<HttpDispatcherResult> {\n const parts = path.replace(/^\\/+/, '').split('/').filter(Boolean);\n \n // GET /metadata/types\n if (parts[0] === 'types') {\n // PRIORITY 1: Try protocol service — it returns BOTH legacy\n // `types: string[]` AND the richer `entries` array (with\n // JSON Schemas, allowOrgOverride flags, domain, etc) needed by\n // the metadata admin UI. It internally also merges\n // MetadataService runtime types, so this path is strictly richer.\n const protocol = await this.resolveService('protocol');\n if (protocol && typeof protocol.getMetaTypes === 'function') {\n try {\n const result = await protocol.getMetaTypes({});\n return { handled: true, response: this.success(result) };\n } catch (e: any) {\n console.warn('[HttpDispatcher] protocol.getMetaTypes() failed:', e?.message);\n }\n }\n // PRIORITY 2: MetadataService fallback (types only, no entries)\n const metadataService = await this.resolveService('metadata', _context.environmentId);\n if (metadataService && typeof (metadataService as any).getRegisteredTypes === 'function') {\n try {\n const types = await (metadataService as any).getRegisteredTypes();\n return { handled: true, response: this.success({ types }) };\n } catch (e: any) {\n console.warn('[HttpDispatcher] MetadataService.getRegisteredTypes() failed:', e.message);\n }\n }\n // Last resort: hardcoded defaults\n return { handled: true, response: this.success({ types: ['object', 'app', 'plugin'] }) };\n }\n\n // GET /metadata/objects/:name/state/:field?from=:state\n // ADR-0020 D3.3 introspection: the legal next states declared by the\n // object's `state_machine` validation rule for `:field`. Lets UIs /\n // AI authors ask \"from here, where can this record go?\" instead of\n // hard-coding the transition table. Returns `next: null` when no FSM\n // governs the field, `next: []` for a declared dead-end state.\n if (parts.length === 4 && (parts[0] === 'objects' || parts[0] === 'object') && parts[2] === 'state' && (!method || method === 'GET')) {\n const name = parts[1];\n const field = parts[3];\n const from = query?.from !== undefined ? String(query.from) : undefined;\n const qlService = await this.getObjectQLService();\n const schema = qlService?.registry?.getObject(name);\n if (!schema) return { handled: true, response: this.error('Object not found', 404) };\n // Dynamic import (matches the runtime convention for @objectstack/objectql)\n // so the dispatcher module graph doesn't statically pull in the objectql barrel.\n const { legalNextStates } = await import('@objectstack/objectql');\n const next = from === undefined ? null : legalNextStates(schema, field, from);\n return { handled: true, response: this.success({ object: name, field, from: from ?? null, next }) };\n }\n\n // GET /metadata/:type/:name(/:subname...)/published → get published version\n // Supports compound names like `lead/views/all_leads/published`.\n if (parts.length >= 3 && parts[parts.length - 1] === 'published' && (!method || method === 'GET')) {\n const type = parts[0];\n const name = parts.slice(1, -1).join('/');\n const metadataService = await this.getService(CoreServiceName.enum.metadata);\n if (metadataService && typeof (metadataService as any).getPublished === 'function') {\n const data = await (metadataService as any).getPublished(type, name);\n if (data === undefined) return { handled: true, response: this.error('Not found', 404) };\n return { handled: true, response: this.success(data) };\n }\n // Fallback — try MetadataService via resolveService\n const metaSvc = await this.resolveService('metadata', _context.environmentId);\n if (metaSvc && typeof (metaSvc as any).getPublished === 'function') {\n try {\n const fallbackData = await (metaSvc as any).getPublished(type, name);\n if (fallbackData !== undefined) return { handled: true, response: this.success(fallbackData) };\n } catch { /* fall through */ }\n }\n return { handled: true, response: this.error('Not found', 404) };\n }\n\n // /metadata/:type/:name where :name may itself contain slashes\n // (e.g. /metadata/lead/views/all_leads → type='lead', name='views/all_leads').\n // Compound names are how the client expresses sub-resources of a type\n // (a view of an object, a flow under an automation, etc.) and the\n // metadata service treats the full string as the lookup key.\n if (parts.length >= 2) {\n const type = parts[0];\n const name = parts.slice(1).join('/');\n // Extract optional package filter from query string\n const packageId = query?.package || undefined;\n\n // PUT /metadata/:type/:name (Save)\n if (method === 'PUT' && body) {\n // Try to get the protocol service directly\n const protocol = await this.resolveService('protocol');\n\n if (protocol && typeof protocol.saveMetaItem === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const result = await protocol.saveMetaItem({ type, name, item: body, organizationId, ...(packageId ? { packageId } : {}) });\n return { handled: true, response: this.success(result) };\n } catch (e: any) {\n return { handled: true, response: this.error(e.message, 400) };\n }\n }\n\n // Fallback: try MetadataService directly\n const metaSvc = await this.resolveService('metadata', _context.environmentId);\n if (metaSvc && typeof (metaSvc as any).saveItem === 'function') {\n try {\n const data = await (metaSvc as any).saveItem(type, name, body);\n return { handled: true, response: this.success(data) };\n } catch (e: any) {\n return { handled: true, response: this.error(e.message || 'Save not supported', 501) };\n }\n }\n return { handled: true, response: this.error('Save not supported', 501) };\n }\n\n try {\n // Try specific calls based on type\n if (type === 'objects' || type === 'object') {\n // Check whether the kernel is project-scoped. When it is,\n // the process-wide SchemaRegistry is unsafe to query\n // directly — it would return objects that other projects\n // wrote in this same process. Route through the Protocol\n // service (which filters sys_metadata by environment_id) in that\n // case, and fall back to the registry only for the\n // unscoped (single-kernel / control-plane) path.\n const protocol = await this.resolveService('protocol') as any;\n const scopedEnv = typeof protocol?.getProjectId === 'function'\n ? protocol.getProjectId()\n : protocol?.environmentId;\n const scoped = scopedEnv !== undefined;\n\n if (scoped && typeof protocol.getMetaItem === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const data = await protocol.getMetaItem({ type: 'object', name, organizationId });\n // Protocol returns `{ type, name, item }` — only\n // treat the lookup as a hit when item is present.\n if (data && (data.item ?? data)) {\n return { handled: true, response: this.success(data) };\n }\n } catch { /* fall through to registry / 404 */ }\n }\n\n const qlService = await this.getObjectQLService();\n if (qlService?.registry) {\n const data = qlService.registry.getObject(name);\n if (data) return { handled: true, response: this.success(data) };\n }\n\n // Last-ditch protocol attempt for unscoped kernels whose\n // registry missed (e.g. object persisted to DB but not\n // yet hydrated). Skip when we already tried above.\n if (!scoped && protocol && typeof protocol.getMetaItem === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const data = await protocol.getMetaItem({ type: 'object', name, organizationId });\n if (data && (data.item ?? data)) {\n return { handled: true, response: this.success(data) };\n }\n } catch { /* fall through to 404 */ }\n }\n return { handled: true, response: this.error('Not found', 404) };\n }\n\n // Normalize plural URL paths to singular registry type names\n const singularType = pluralToSingular(type);\n\n // Try Protocol Service First (Preferred)\n const protocol = await this.resolveService('protocol');\n if (protocol && typeof protocol.getMetaItem === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const data = await protocol.getMetaItem({ type: singularType, name, packageId, organizationId });\n return { handled: true, response: this.success(data) };\n } catch (e: any) {\n // Protocol might throw if not found or not supported\n }\n }\n\n // Try MetadataService for runtime-registered types\n const metaSvc = await this.resolveService('metadata', _context.environmentId);\n if (metaSvc && typeof (metaSvc as any).getItem === 'function') {\n try {\n const data = await (metaSvc as any).getItem(singularType, name);\n if (data) return { handled: true, response: this.success(data) };\n } catch { /* not found */ }\n }\n return { handled: true, response: this.error('Not found', 404) };\n } catch (e: any) {\n // Fallback: treat first part as object name if only 1 part (handled below)\n // But here we are deep in 2 parts. Must be an error.\n return { handled: true, response: this.error(e.message, 404) };\n }\n }\n \n // GET /metadata/_drafts?packageId=&type= (ADR-0033 pending-changes list)\n // Surfaces draft-state metadata the active-only `getMetaItems` list hides,\n // so the console can show what an AI authored but nobody published yet.\n // `_drafts` is intercepted before the generic `:type` handler below so it\n // is never mistaken for a metadata type name.\n if (parts.length === 1 && parts[0] === '_drafts' && (!method || method.toUpperCase() === 'GET')) {\n const protocol = await this.resolveService('protocol');\n if (protocol && typeof protocol.listDrafts === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const data = await protocol.listDrafts({\n packageId: query?.packageId || undefined,\n type: query?.type || undefined,\n organizationId,\n });\n return { handled: true, response: this.success(data) };\n } catch (e: any) {\n return { handled: true, response: this.error(e.message, 500) };\n }\n }\n return { handled: true, response: this.error('Draft listing not supported', 501) };\n }\n\n // GET /metadata/:type (List items of type) OR /metadata/:objectName (Legacy)\n if (parts.length === 1) {\n const typeOrName = parts[0];\n // Extract optional package filter from query string\n const packageId = query?.package || undefined;\n\n // Try protocol service first for any type\n const protocol = await this.resolveService('protocol');\n if (protocol && typeof protocol.getMetaItems === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const data = await protocol.getMetaItems({ type: typeOrName, packageId, organizationId });\n // Return any valid response from protocol (including empty items arrays)\n if (data && (data.items !== undefined || Array.isArray(data))) {\n return { handled: true, response: this.success(data) };\n }\n } catch {\n // Protocol doesn't know this type, fall through\n }\n }\n\n // Try MetadataService directly for runtime-registered metadata (agents, tools, etc.)\n const metadataService = await this.getService(CoreServiceName.enum.metadata);\n if (metadataService && typeof (metadataService as any).list === 'function') {\n try {\n let items = await (metadataService as any).list(typeOrName);\n // Respect package filter: MetadataService.list() returns ALL items,\n // so filter by _packageId when a specific package is requested.\n if (packageId && items && items.length > 0) {\n items = items.filter((item: any) => item?._packageId === packageId);\n }\n if (items && items.length > 0) {\n return { handled: true, response: this.success({ type: typeOrName, items }) };\n }\n } catch (e: any) {\n // MetadataService doesn't know this type or failed, continue to other fallbacks\n // Sanitize typeOrName to prevent log injection (CodeQL warning)\n const sanitizedType = String(typeOrName).replace(/[\\r\\n\\t]/g, '');\n console.debug(`[HttpDispatcher] MetadataService.list() failed for type:`, sanitizedType, 'error:', e.message);\n }\n }\n\n // Try ObjectQL registry directly for object/type lookups\n const qlService = await this.getObjectQLService();\n if (qlService?.registry) {\n if (typeOrName === 'objects') {\n const objs = qlService.registry.getAllObjects(packageId);\n return { handled: true, response: this.success({ type: 'object', items: objs }) };\n }\n // Try listing items of the given type\n const items = qlService.registry.listItems?.(typeOrName, packageId);\n if (items && items.length > 0) {\n return { handled: true, response: this.success({ type: typeOrName, items }) };\n }\n // Legacy: treat as object name\n const obj = qlService.registry.getObject(typeOrName);\n if (obj) return { handled: true, response: this.success(obj) };\n }\n return { handled: true, response: this.error('Not found', 404) };\n }\n\n // GET /metadata — return available metadata types\n if (parts.length === 0) {\n // Prefer protocol service for the rich `entries` array (with\n // JSON Schemas etc); fall back to MetadataService types-only.\n const protocol = await this.resolveService('protocol');\n if (protocol && typeof protocol.getMetaTypes === 'function') {\n try {\n const result = await protocol.getMetaTypes({});\n return { handled: true, response: this.success(result) };\n } catch { /* fall through */ }\n }\n const metadataService = await this.resolveService('metadata', _context.environmentId);\n if (metadataService && typeof (metadataService as any).getRegisteredTypes === 'function') {\n try {\n const types = await (metadataService as any).getRegisteredTypes();\n return { handled: true, response: this.success({ types }) };\n } catch { /* fall through */ }\n }\n return { handled: true, response: this.success({ types: ['object', 'app', 'plugin'] }) };\n }\n \n return { handled: false };\n }\n\n /**\n * Handles Data requests\n * path: sub-path after /data/ (e.g. \"contacts\", \"contacts/123\", \"contacts/query\")\n */\n async handleData(path: string, method: string, body: any, query: any, _context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n const parts = path.replace(/^\\/+/, '').split('/');\n const objectName = parts[0];\n\n if (!objectName) {\n return { handled: true, response: this.error('Object name required', 400) };\n }\n\n // Check if environment is resolved for data-plane requests\n if (!_context.dataDriver && this.envRegistry) {\n return {\n handled: true,\n response: this.error('Project not resolved. Please specify X-Environment-Id header or ensure hostname maps to a project.', 428)\n };\n }\n\n const m = method.toUpperCase();\n\n // 1. Custom Actions (query, batch)\n if (parts.length > 1) {\n const action = parts[1];\n\n // POST /data/:object/query\n if (action === 'query' && m === 'POST') {\n // Spec: returns FindDataResponse = { object, records, total?, hasMore? }\n const result = await this.callData('query', { object: objectName, ...body }, _context.dataDriver, _context.environmentId, _context.executionContext);\n return { handled: true, response: this.success(result) };\n }\n\n // GET /data/:object/:id\n if (parts.length === 2 && m === 'GET') {\n const id = parts[1];\n // Spec: Only select/expand are allowlisted query params for GET by ID.\n // All other query parameters are discarded to prevent parameter pollution.\n const { select, expand } = query || {};\n const allowedParams: Record<string, unknown> = {};\n if (select != null) allowedParams.select = select;\n if (expand != null) allowedParams.expand = expand;\n // Spec: returns GetDataResponse = { object, id, record }\n const result = await this.callData('get', { object: objectName, id, ...allowedParams }, _context.dataDriver, _context.environmentId, _context.executionContext);\n return { handled: true, response: this.success(result) };\n }\n\n // PATCH /data/:object/:id\n if (parts.length === 2 && m === 'PATCH') {\n const id = parts[1];\n // Spec: returns UpdateDataResponse = { object, id, record }\n const result = await this.callData('update', { object: objectName, id, data: body }, _context.dataDriver, _context.environmentId, _context.executionContext);\n return { handled: true, response: this.success(result) };\n }\n\n // DELETE /data/:object/:id\n if (parts.length === 2 && m === 'DELETE') {\n const id = parts[1];\n // Spec: returns DeleteDataResponse = { object, id, deleted }\n const result = await this.callData('delete', { object: objectName, id }, _context.dataDriver, _context.environmentId, _context.executionContext);\n return { handled: true, response: this.success(result) };\n }\n } else {\n // GET /data/:object (List)\n if (m === 'GET') {\n // ── Normalize HTTP transport params → Spec canonical (QueryAST) ──\n // HTTP GET query params use transport-level names (filter, sort, top,\n // skip, select, expand) which are normalized here to canonical\n // QueryAST field names (where, orderBy, limit, offset, fields,\n // expand) before forwarding to the data service layer.\n // The protocol.ts findData() method performs a deeper normalization\n // pass, but pre-normalizing here ensures the data service always receives\n // Spec-canonical keys.\n const normalized: Record<string, unknown> = { ...query };\n\n // filter/filters → where\n // Note: `filter` is the canonical HTTP *transport* parameter name\n // (see HttpFindQueryParamsSchema). It is normalized here to the\n // canonical *QueryAST* field name `where` before data dispatch.\n // `filters` (plural) is a deprecated alias for `filter`.\n if (normalized.filter != null || normalized.filters != null) {\n normalized.where = normalized.where ?? normalized.filter ?? normalized.filters;\n delete normalized.filter;\n delete normalized.filters;\n }\n // select → fields\n if (normalized.select != null && normalized.fields == null) {\n normalized.fields = normalized.select;\n delete normalized.select;\n }\n // sort → orderBy\n if (normalized.sort != null && normalized.orderBy == null) {\n normalized.orderBy = normalized.sort;\n delete normalized.sort;\n }\n // top → limit\n if (normalized.top != null && normalized.limit == null) {\n normalized.limit = normalized.top;\n delete normalized.top;\n }\n // skip → offset\n if (normalized.skip != null && normalized.offset == null) {\n normalized.offset = normalized.skip;\n delete normalized.skip;\n }\n\n // Spec: returns FindDataResponse = { object, records, total?, hasMore? }\n const result = await this.callData('query', { object: objectName, query: normalized }, _context.dataDriver, _context.environmentId, _context.executionContext);\n return { handled: true, response: this.success(result) };\n }\n\n // POST /data/:object (Create)\n if (m === 'POST') {\n // Spec: returns CreateDataResponse = { object, id, record }\n const result = await this.callData('create', { object: objectName, data: body }, _context.dataDriver, _context.environmentId, _context.executionContext);\n const res = this.success(result);\n res.status = 201;\n return { handled: true, response: res };\n }\n }\n\n return { handled: false };\n }\n\n /**\n * Handles Analytics requests\n * path: sub-path after /analytics/\n */\n async handleAnalytics(path: string, method: string, body: any, _context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n const analyticsService = await this.getService(CoreServiceName.enum.analytics);\n if (!analyticsService) return { handled: false }; // 404 handled by caller if unhandled\n\n const m = method.toUpperCase();\n const subPath = path.replace(/^\\/+/, '');\n\n // POST /analytics/query\n if (subPath === 'query' && m === 'POST') {\n const result = await analyticsService.query(body);\n return { handled: true, response: this.success(result) };\n }\n\n // GET /analytics/meta\n if (subPath === 'meta' && m === 'GET') {\n const result = await analyticsService.getMeta();\n return { handled: true, response: this.success(result) };\n }\n\n // POST /analytics/sql (Dry-run or debug)\n if (subPath === 'sql' && m === 'POST') {\n // Assuming service has generateSql method\n const result = await analyticsService.generateSql(body);\n return { handled: true, response: this.success(result) };\n }\n\n return { handled: false };\n }\n\n /**\n * Handles in-app notification requests (ADR-0030) — the\n * `/api/v1/notifications` surface backed by the messaging service's inbox\n * read API. Reads the L5 `sys_inbox_message` + `sys_notification_receipt`\n * join; mark-read upserts the receipt keyed `(notification_id, user_id,\n * channel:'inbox')`. The routes are `auth: true`, so an authenticated user\n * is required.\n *\n * Routes (path is the sub-path after `/notifications`):\n * GET '' → listInbox (query: read, type, limit)\n * POST /read → markRead (body: { ids: string[] })\n * POST /read/all → markAllRead\n */\n async handleNotification(path: string, method: string, body: any, query: any, context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n const service = await this.resolveService(CoreServiceName.enum.notification, context.environmentId) as any;\n if (!service || typeof service.listInbox !== 'function') return { handled: false };\n\n const userId: string | undefined = context.executionContext?.userId;\n if (!userId) {\n return { handled: true, response: this.error('Authentication required', 401) };\n }\n\n const m = method.toUpperCase();\n const subPath = path.replace(/^\\/+/, '').replace(/\\/+$/, '');\n\n // GET /notifications — list the user's inbox joined with read-state.\n if (subPath === '' && m === 'GET') {\n const read = query?.read === undefined ? undefined : String(query.read) === 'true';\n const limit = query?.limit ? Number(query.limit) : undefined;\n const type = query?.type ? String(query.type) : undefined;\n const result = await service.listInbox(userId, { read, type, limit });\n return { handled: true, response: this.success(result) };\n }\n\n // POST /notifications/read — mark specific notifications read.\n if (subPath === 'read' && m === 'POST') {\n const ids: string[] = Array.isArray(body?.ids) ? body.ids.map((x: unknown) => String(x)) : [];\n const result = await service.markRead(userId, ids);\n return { handled: true, response: this.success(result) };\n }\n\n // POST /notifications/read/all — mark all of the user's inbox read.\n if (subPath === 'read/all' && m === 'POST') {\n const result = await service.markAllRead(userId);\n return { handled: true, response: this.success(result) };\n }\n\n return { handled: false };\n }\n\n /**\n * Handles i18n requests\n * path: sub-path after /i18n/\n *\n * Routes:\n * GET /locales → getLocales\n * GET /translations/:locale → getTranslations (locale from path)\n * GET /translations?locale=xx → getTranslations (locale from query)\n * GET /labels/:object/:locale → getFieldLabels (both from path)\n * GET /labels/:object?locale=xx → getFieldLabels (locale from query)\n */\n async handleI18n(path: string, method: string, query: any, _context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n const i18nService = await this.getService(CoreServiceName.enum.i18n);\n if (!i18nService) return { handled: true, response: this.error('i18n service not available', 501) };\n\n const m = method.toUpperCase();\n const parts = path.replace(/^\\/+/, '').split('/').filter(Boolean);\n\n if (m !== 'GET') return { handled: false };\n\n // GET /i18n/locales\n if (parts[0] === 'locales' && parts.length === 1) {\n const locales = i18nService.getLocales();\n return { handled: true, response: this.success({ locales }) };\n }\n\n // GET /i18n/translations/:locale OR /i18n/translations?locale=xx\n if (parts[0] === 'translations') {\n const locale = parts[1] ? decodeURIComponent(parts[1]) : query?.locale;\n if (!locale) return { handled: true, response: this.error('Missing locale parameter', 400) };\n\n let translations = i18nService.getTranslations(locale);\n\n // Locale fallback: try resolving to an available locale when\n // the exact code yields empty translations (e.g. zh → zh-CN).\n if (Object.keys(translations).length === 0) {\n const availableLocales = typeof i18nService.getLocales === 'function'\n ? i18nService.getLocales() : [];\n const resolved = resolveLocale(locale, availableLocales);\n if (resolved && resolved !== locale) {\n translations = i18nService.getTranslations(resolved);\n return { handled: true, response: this.success({ locale: resolved, requestedLocale: locale, translations }) };\n }\n }\n\n return { handled: true, response: this.success({ locale, translations }) };\n }\n\n // GET /i18n/labels/:object/:locale OR /i18n/labels/:object?locale=xx\n if (parts[0] === 'labels' && parts.length >= 2) {\n const objectName = decodeURIComponent(parts[1]);\n let locale = parts[2] ? decodeURIComponent(parts[2]) : query?.locale;\n if (!locale) return { handled: true, response: this.error('Missing locale parameter', 400) };\n\n // Locale fallback for labels endpoint\n const availableLocales = typeof i18nService.getLocales === 'function'\n ? i18nService.getLocales() : [];\n const resolved = resolveLocale(locale, availableLocales);\n if (resolved) locale = resolved;\n\n if (typeof i18nService.getFieldLabels === 'function') {\n const labels = i18nService.getFieldLabels(objectName, locale);\n return { handled: true, response: this.success({ object: objectName, locale, labels }) };\n }\n // Fallback: derive field labels from full translation bundle\n const translations = i18nService.getTranslations(locale);\n const prefix = `o.${objectName}.fields.`;\n const labels: Record<string, string> = {};\n for (const [key, value] of Object.entries(translations)) {\n if (key.startsWith(prefix)) {\n labels[key.substring(prefix.length)] = value as string;\n }\n }\n return { handled: true, response: this.success({ object: objectName, locale, labels }) };\n }\n\n return { handled: false };\n }\n\n /**\n * Handles Package Management requests\n * \n * REST Endpoints:\n * - GET /packages → list all installed packages\n * - GET /packages/:id → get a specific package\n * - POST /packages → install a new package\n * - DELETE /packages/:id → uninstall a package\n * - PATCH /packages/:id/enable → enable a package\n * - PATCH /packages/:id/disable → disable a package\n * - POST /packages/:id/publish → publish a package (metadata snapshot)\n * - POST /packages/:id/revert → revert a package to last published state\n * \n * Uses ObjectQL SchemaRegistry directly (via the 'objectql' service).\n */\n async handlePackages(path: string, method: string, body: any, query: any, _context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n const m = method.toUpperCase();\n const parts = path.replace(/^\\/+/, '').split('/').filter(Boolean);\n\n // Try to get SchemaRegistry from the ObjectQL service\n const qlService = await this.getObjectQLService();\n const registry = qlService?.registry;\n\n // If no registry available, return 503\n if (!registry) {\n return { handled: true, response: this.error('Package service not available', 503) };\n }\n\n try {\n // GET /packages → list packages\n if (parts.length === 0 && m === 'GET') {\n let packages = registry.getAllPackages();\n // Apply optional filters\n if (query?.status) {\n packages = packages.filter((p: any) => p.status === query.status);\n }\n if (query?.type) {\n packages = packages.filter((p: any) => p.manifest?.type === query.type);\n }\n return { handled: true, response: this.success({ packages, total: packages.length }) };\n }\n\n // POST /packages → install package.\n // Route through the canonical `protocol.installPackage` primitive so\n // the install lands in BOTH the in-memory registry (what this list/detail\n // reads) AND the durable `sys_packages` table. Fall back to the bare\n // registry write only when the protocol service/method is unavailable.\n if (parts.length === 0 && m === 'POST') {\n const manifest = body.manifest || body;\n let pkg: any;\n const protocolSvc: any = await this.resolveService('protocol').catch(() => null);\n if (protocolSvc && typeof protocolSvc.installPackage === 'function') {\n const out = await protocolSvc.installPackage({ manifest, settings: body.settings });\n pkg = out?.package ?? out;\n } else {\n pkg = registry.installPackage(manifest, body.settings);\n }\n const res = this.success(pkg);\n res.status = 201;\n return { handled: true, response: res };\n }\n\n // PATCH /packages/:id/enable\n if (parts.length === 2 && parts[1] === 'enable' && m === 'PATCH') {\n const id = decodeURIComponent(parts[0]);\n const pkg = registry.enablePackage(id);\n if (!pkg) return { handled: true, response: this.error(`Package '${id}' not found`, 404) };\n try {\n setPackageDisabled(_context?.environmentId, id, false);\n } catch (err) {\n console.warn('[handlePackages] failed to persist enable state', { id, error: (err as Error)?.message });\n }\n return { handled: true, response: this.success(pkg) };\n }\n\n // PATCH /packages/:id/disable\n if (parts.length === 2 && parts[1] === 'disable' && m === 'PATCH') {\n const id = decodeURIComponent(parts[0]);\n const pkg = registry.disablePackage(id);\n if (!pkg) return { handled: true, response: this.error(`Package '${id}' not found`, 404) };\n try {\n setPackageDisabled(_context?.environmentId, id, true);\n } catch (err) {\n console.warn('[handlePackages] failed to persist disable state', { id, error: (err as Error)?.message });\n }\n return { handled: true, response: this.success(pkg) };\n }\n\n // POST /packages/:id/publish → publish package metadata\n if (parts.length === 2 && parts[1] === 'publish' && m === 'POST') {\n const id = decodeURIComponent(parts[0]);\n const metadataService = await this.getService(CoreServiceName.enum.metadata);\n if (metadataService && typeof (metadataService as any).publishPackage === 'function') {\n const result = await (metadataService as any).publishPackage(id, body || {});\n return { handled: true, response: this.success(result) };\n }\n return { handled: true, response: this.error('Metadata service not available', 503) };\n }\n\n // POST /packages/:id/publish-drafts → promote every pending DRAFT\n // bound to the package to active in one shot (\"publish whole app\",\n // ADR-0033). Routes through protocol.publishPackageDrafts (which\n // reuses the per-item publish primitive) — no metadata service\n // dependency, unlike /publish above.\n if (parts.length === 2 && parts[1] === 'publish-drafts' && m === 'POST') {\n const id = decodeURIComponent(parts[0]);\n const protocol = await this.resolveService('protocol');\n if (protocol && typeof (protocol as any).publishPackageDrafts === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const result = await (protocol as any).publishPackageDrafts({\n packageId: id,\n ...(organizationId ? { organizationId } : {}),\n ...(body?.actor ? { actor: body.actor } : {}),\n });\n return { handled: true, response: this.success(result) };\n } catch (e: any) {\n return { handled: true, response: this.error(e.message, e.statusCode || 500) };\n }\n }\n return { handled: true, response: this.error('Draft publishing not supported', 501) };\n }\n\n // POST /packages/:id/revert → revert package to last published state\n if (parts.length === 2 && parts[1] === 'revert' && m === 'POST') {\n const id = decodeURIComponent(parts[0]);\n const metadataService = await this.getService(CoreServiceName.enum.metadata);\n if (metadataService && typeof (metadataService as any).revertPackage === 'function') {\n await (metadataService as any).revertPackage(id);\n return { handled: true, response: this.success({ success: true }) };\n }\n return { handled: true, response: this.error('Metadata service not available', 503) };\n }\n\n // GET /packages/:id/export → assemble a portable manifest from\n // sys_metadata overlay rows bound to this package (offline export).\n if (parts.length === 2 && parts[1] === 'export' && m === 'GET') {\n const id = decodeURIComponent(parts[0]);\n const manifest = await this.assemblePackageManifest(id, registry, _context);\n if (!manifest) {\n return { handled: true, response: this.error(`Package '${id}' not found`, 404) };\n }\n return { handled: true, response: this.success(manifest) };\n }\n\n // GET /packages/:id → get package\n if (parts.length === 1 && m === 'GET') {\n const id = decodeURIComponent(parts[0]);\n const pkg = registry.getPackage(id);\n if (!pkg) return { handled: true, response: this.error(`Package '${id}' not found`, 404) };\n return { handled: true, response: this.success(pkg) };\n }\n\n // DELETE /packages/:id → uninstall package\n if (parts.length === 1 && m === 'DELETE') {\n const id = decodeURIComponent(parts[0]);\n const success = registry.uninstallPackage(id);\n if (!success) return { handled: true, response: this.error(`Package '${id}' not found`, 404) };\n return { handled: true, response: this.success({ success: true }) };\n }\n } catch (e: any) {\n return { handled: true, response: this.error(e.message, e.statusCode || 500) };\n }\n\n return { handled: false };\n }\n\n /**\n * Assemble a portable, offline-installable package manifest from the\n * `sys_metadata` overlay rows bound to `packageId`.\n *\n * The resulting shape mirrors what `marketplace-install-local` →\n * `manifestService.register()` → `engine.registerApp()` consumes:\n * `{ id, name, version, objects:[…], views:[…], flows:[…], … }`\n * where each category key is the PLURAL manifest name and its value is\n * an array of clean metadata bodies (provenance decorations stripped).\n *\n * Only the metadata categories that `registerApp` can actually consume\n * are exported. `datasources` and `emailTemplates` are intentionally\n * excluded (not registered by the import path). `tools` / `skills` ARE\n * round-tripped: they are registered by `registerApp` on import and\n * surfaced by `getMetaItems('tool' | 'skill')` on export.\n *\n * @returns the manifest object, or `null` if the package id is unknown\n * AND has no overlay-authored metadata.\n */\n private async assemblePackageManifest(\n packageId: string,\n registry: any,\n context: HttpProtocolContext,\n ): Promise<Record<string, any> | null> {\n const protocol = await this.resolveService('protocol');\n if (!protocol || typeof protocol.getMetaItems !== 'function') return null;\n\n const organizationId = await this.resolveActiveOrganizationId(context);\n\n // Provenance / overlay-bookkeeping keys that must never leak into a\n // portable manifest. Stripped at top level only — nested field bodies\n // are left untouched.\n const PROVENANCE_KEYS = new Set([\n '_packageId', '_packageVersionId', '_provenance', '_state',\n '_version', '_organizationId', '_source', '_id', '_rowId',\n ]);\n const clean = (item: any) => {\n if (!item || typeof item !== 'object') return item;\n const out: Record<string, any> = {};\n for (const [k, v] of Object.entries(item)) {\n if (k.startsWith('_') || PROVENANCE_KEYS.has(k)) continue;\n out[k] = v;\n }\n return out;\n };\n\n // Categories the local-install register path understands. Excludes\n // datasources / emailTemplates (not consumed by registerApp).\n const exportPluralKeys = Object.keys(PLURAL_TO_SINGULAR).filter(\n (k) => k !== 'datasources' && k !== 'emailTemplates',\n );\n\n const manifest: Record<string, any> = {};\n let total = 0;\n for (const plural of exportPluralKeys) {\n const singular = PLURAL_TO_SINGULAR[plural];\n let items: any[] = [];\n try {\n // getMetaItems applies the packageId filter at the\n // registry/overlay query level, so the returned items are\n // already scoped to this package — no client-side re-filter.\n const res = await protocol.getMetaItems({ type: singular, packageId, organizationId });\n items = Array.isArray(res?.items) ? res.items : [];\n } catch {\n // Unknown/unsupported type for this runtime — skip.\n continue;\n }\n if (items.length === 0) continue;\n manifest[plural] = items.map(clean);\n total += items.length;\n }\n\n const pkg = (() => {\n try { return registry?.getPackage?.(packageId); } catch { return undefined; }\n })();\n\n if (total === 0 && !pkg) return null;\n\n manifest.id = packageId;\n manifest.name = pkg?.manifest?.name ?? pkg?.name ?? packageId;\n manifest.version = pkg?.manifest?.version ?? pkg?.version ?? '1.0.0';\n if (pkg?.manifest?.label ?? pkg?.label) {\n manifest.label = pkg?.manifest?.label ?? pkg?.label;\n }\n return manifest;\n }\n\n /**\n * Cloud / Environment Control-Plane routes.\n *\n * - GET /cloud/drivers → list registered ObjectQL drivers (for env provisioning)\n * - GET /cloud/environments → list\n * - POST /cloud/environments → provision (driver: memory | turso | <any registered driver>)\n * - GET /cloud/environments/:id → detail (+ db, credential, membership)\n * - PATCH /cloud/environments/:id → update displayName / plan / status / isDefault / metadata\n * - DELETE /cloud/environments/:id[?force=1] → cascade-delete the project (cred/member/package install rows + physical DB)\n * - DELETE /cloud/organizations/:id → cascade-delete every project (and its DB) for the org, then drop the org\n * - POST /cloud/environments/:id/retry → re-run provisioning for a failed environment\n * - POST /cloud/environments/:id/activate → mark as active for session (stub)\n * - POST /cloud/environments/:id/credentials/rotate → rotate credential\n * - GET /cloud/environments/:id/members → list members\n * - GET /cloud/environments/:id/packages → list installed packages\n * - POST /cloud/environments/:id/packages → install package into env\n * - GET /cloud/environments/:id/packages/:pkgId → get installation detail\n * - PATCH /cloud/environments/:id/packages/:pkgId/enable → enable package\n * - PATCH /cloud/environments/:id/packages/:pkgId/disable → disable package\n * - DELETE /cloud/environments/:id/packages/:pkgId → uninstall (scope=platform forbidden)\n * - POST /cloud/environments/:id/packages/:pkgId/upgrade → upgrade to newer version\n *\n * Driver binding\n * --------------\n * Environments are not tied to any specific driver. At provisioning time the\n * caller passes `driver` (a short name such as `memory`, `turso`, or any\n * future `sql` / `postgres` driver). The dispatcher validates the name\n * against the kernel's registered driver services (`driver.<name>`) and\n * derives an appropriate placeholder `database_url` for the chosen driver.\n * If `driver` is omitted, the dispatcher auto-selects the first available\n * in preference order: turso → memory → any other registered driver.\n *\n * Backed by ObjectQL sys_environment / sys_environment_credential /\n * sys_environment_member tables (registered by\n * `@objectstack/service-tenant`'s `createTenantPlugin`).\n * Physical database addressing (database_url, database_driver, etc.)\n * is stored directly on the sys_environment row.\n */\n /**\n * Resolve the calling user id from the request session, if any.\n * Returns `undefined` for anonymous calls or when auth is not wired up.\n */\n private async resolveActiveOrganizationId(context: HttpProtocolContext): Promise<string | undefined> {\n try {\n const authService: any = await this.resolveService(CoreServiceName.enum.auth);\n const rawHeaders = context.request?.headers;\n let headers: any = rawHeaders;\n if (rawHeaders && typeof rawHeaders === 'object' && typeof (rawHeaders as any).get !== 'function') {\n try {\n const h = new Headers();\n for (const [k, v] of Object.entries(rawHeaders as Record<string, any>)) {\n if (v == null) continue;\n h.set(k, Array.isArray(v) ? v.join(', ') : String(v));\n }\n headers = h;\n } catch {\n headers = rawHeaders;\n }\n }\n const apiObj = authService?.auth?.api ?? authService?.api;\n const sessionData = await apiObj?.getSession?.call(apiObj, { headers });\n const oid = sessionData?.session?.activeOrganizationId;\n return typeof oid === 'string' && oid.length > 0 ? oid : undefined;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Handles Storage requests\n * path: sub-path after /storage/\n */\n async handleStorage(path: string, method: string, file: any, context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n const storageService = await this.getService(CoreServiceName.enum['file-storage']) || this.kernel.services?.['file-storage'];\n if (!storageService) {\n return { handled: true, response: this.error('File storage not configured', 501) };\n }\n \n const m = method.toUpperCase();\n const parts = path.replace(/^\\/+/, '').split('/');\n \n // POST /storage/upload\n if (parts[0] === 'upload' && m === 'POST') {\n if (!file) {\n return { handled: true, response: this.error('No file provided', 400) };\n }\n const result = await storageService.upload(file, { request: context.request });\n return { handled: true, response: this.success(result) };\n }\n \n // GET /storage/file/:id\n if (parts[0] === 'file' && parts[1] && m === 'GET') {\n const id = parts[1];\n const result = await storageService.download(id, { request: context.request });\n \n // Result can be URL (redirect), Stream/Blob, or metadata\n if (result.url && result.redirect) {\n // Must be handled by adapter to do actual redirect\n return { handled: true, result: { type: 'redirect', url: result.url } };\n }\n \n if (result.stream) {\n // Must be handled by adapter to pipe stream\n return { \n handled: true, \n result: { \n type: 'stream', \n stream: result.stream, \n headers: {\n 'Content-Type': result.mimeType || 'application/octet-stream',\n 'Content-Length': result.size\n }\n } \n };\n }\n \n return { handled: true, response: this.success(result) };\n }\n \n return { handled: false };\n }\n\n /**\n * Handles UI requests\n * path: sub-path after /ui/\n */\n async handleUi(path: string, query: any, _context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n const parts = path.replace(/^\\/+/, '').split('/').filter(Boolean);\n \n // GET /ui/view/:object (with optional type param)\n if (parts[0] === 'view' && parts[1]) {\n const objectName = parts[1];\n // Support both path param /view/obj/list AND query param /view/obj?type=list\n const type = parts[2] || query?.type || 'list';\n\n const protocol = await this.resolveService('protocol');\n \n if (protocol && typeof protocol.getUiView === 'function') {\n try {\n const result = await protocol.getUiView({ object: objectName, type });\n return { handled: true, response: this.success(result) };\n } catch (e: any) {\n return { handled: true, response: this.error(e.message, 500) };\n }\n } else {\n return { handled: true, response: this.error('Protocol service not available', 503) };\n }\n }\n\n return { handled: false };\n }\n\n /**\n * Handles Automation requests\n * path: sub-path after /automation/\n *\n * Routes:\n * GET / → listFlows\n * GET /actions → getActionDescriptors (ADR-0018; ?paradigm/?source/?category filters)\n * GET /connectors → getConnectorDescriptors (ADR-0022; ?type filter)\n * GET /:name → getFlow\n * POST / → createFlow (registerFlow)\n * PUT /:name → updateFlow\n * DELETE /:name → deleteFlow (unregisterFlow)\n * POST /:name/trigger → execute (legacy: trigger/:name also supported)\n * POST /:name/toggle → toggleFlow\n * GET /:name/runs → listRuns\n * GET /:name/runs/:runId → getRun\n * POST /:name/runs/:runId/resume → resume a paused run (screen input / ADR-0019)\n * GET /:name/runs/:runId/screen → the screen a paused run awaits\n */\n async handleAutomation(path: string, method: string, body: any, context: HttpProtocolContext, query?: any): Promise<HttpDispatcherResult> {\n const automationService = await this.getService(CoreServiceName.enum.automation);\n if (!automationService) return { handled: false };\n\n const m = method.toUpperCase();\n const parts = path.replace(/^\\/+/, '').split('/').filter(Boolean);\n\n // Legacy: POST /automation/trigger/:name\n if (parts[0] === 'trigger' && parts[1] && m === 'POST') {\n const triggerName = parts[1];\n if (typeof automationService.trigger === 'function') {\n const result = await automationService.trigger(triggerName, body, { request: context.request });\n return { handled: true, response: this.success(result) };\n }\n // Fallback to execute\n if (typeof automationService.execute === 'function') {\n const result = await automationService.execute(triggerName, body);\n return { handled: true, response: this.success(result) };\n }\n }\n\n // GET / → listFlows\n if (parts.length === 0 && m === 'GET') {\n if (typeof automationService.listFlows === 'function') {\n const names = await automationService.listFlows();\n return { handled: true, response: this.success({ flows: names, total: names.length, hasMore: false }) };\n }\n }\n\n // POST / → createFlow\n if (parts.length === 0 && m === 'POST') {\n if (typeof automationService.registerFlow === 'function') {\n automationService.registerFlow(body?.name, body);\n return { handled: true, response: this.success(body) };\n }\n }\n\n // GET /actions → list registered action descriptors (ADR-0018).\n // MUST precede the `/:name → getFlow` catch-all below, otherwise a\n // flow lookup for a flow literally named \"actions\" would shadow it.\n // Backs the designer palette + flow validation; the registry is open\n // and marketplace-extensible (built-in + plugin-contributed actions).\n if (parts[0] === 'actions' && parts.length === 1 && m === 'GET') {\n if (typeof automationService.getActionDescriptors === 'function') {\n let actions = automationService.getActionDescriptors() ?? [];\n // Optional filters mirror descriptor fields.\n if (query?.paradigm) {\n actions = actions.filter((a: any) => Array.isArray(a?.paradigms) && a.paradigms.includes(query.paradigm));\n }\n if (query?.source) {\n actions = actions.filter((a: any) => a?.source === query.source);\n }\n if (query?.category) {\n actions = actions.filter((a: any) => a?.category === query.category);\n }\n return { handled: true, response: this.success({ actions, total: actions.length }) };\n }\n // Service present but does not implement the optional method:\n // report an empty (but valid) registry rather than a 404.\n return { handled: true, response: this.success({ actions: [], total: 0 }) };\n }\n\n // GET /connectors → list registered connector descriptors (ADR-0022).\n // Like /actions, MUST precede the `/:name → getFlow` catch-all so a flow\n // named \"connectors\" cannot shadow it. Backs the designer's\n // `connector_action` connector/action/input pickers; the registry is\n // empty in baseline and populated by connector plugins (e.g.\n // @objectstack/connector-rest, @objectstack/connector-slack).\n if (parts[0] === 'connectors' && parts.length === 1 && m === 'GET') {\n if (typeof automationService.getConnectorDescriptors === 'function') {\n let connectors = automationService.getConnectorDescriptors() ?? [];\n // Optional filter mirrors the descriptor's connector type.\n if (query?.type) {\n connectors = connectors.filter((c: any) => c?.type === query.type);\n }\n return { handled: true, response: this.success({ connectors, total: connectors.length }) };\n }\n // Service present but does not implement the optional method:\n // report an empty (but valid) registry rather than a 404.\n return { handled: true, response: this.success({ connectors: [], total: 0 }) };\n }\n\n // Routes with :name\n if (parts.length >= 1) {\n const name = parts[0];\n\n // POST /:name/trigger → execute\n if (parts[1] === 'trigger' && m === 'POST') {\n if (typeof automationService.execute === 'function') {\n const ctxBody = body && typeof body === 'object' ? body : {};\n // Translate UI/SDK request shape `{recordId, objectName, params}`\n // into the canonical AutomationContext shape expected by the engine.\n // Key transformations:\n // - `recordId` is exposed in `params.recordId` AND aliased to\n // `<objectName>Id` (camelCase) so flow variables like `leadId`,\n // `caseId`, `opportunityId` resolve from a single REST contract.\n // - `objectName` is mapped to the canonical `object` field.\n // - The user identity from the auth context (if any) is forwarded\n // as `userId` so node executors / template interpolation can\n // expand `{$User.Id}`.\n const recordId = ctxBody.recordId;\n const objectName = ctxBody.objectName ?? ctxBody.object;\n const baseParams = (ctxBody.params && typeof ctxBody.params === 'object') ? { ...ctxBody.params } : {};\n // Back-compat: when callers POST a flat body (no `params` wrapper),\n // forward unknown top-level keys as flow params so the original\n // `{ foo: 'bar' }` payload is not silently dropped.\n if (!ctxBody.params) {\n const reserved = new Set(['recordId', 'objectName', 'object', 'event', 'params']);\n for (const [k, v] of Object.entries(ctxBody)) {\n if (reserved.has(k)) continue;\n if (baseParams[k] === undefined) baseParams[k] = v;\n }\n }\n if (recordId !== undefined && baseParams.recordId === undefined) {\n baseParams.recordId = recordId;\n }\n if (recordId !== undefined && objectName) {\n const alias = `${String(objectName).replace(/_([a-z])/g, (_: string, c: string) => c.toUpperCase())}Id`;\n if (baseParams[alias] === undefined) baseParams[alias] = recordId;\n }\n const automationContext: any = {\n params: baseParams,\n object: objectName,\n event: ctxBody.event ?? 'manual',\n };\n const userIdFromAuth = (context as any)?.user?.id ?? (context as any)?.userId;\n if (userIdFromAuth) automationContext.userId = userIdFromAuth;\n const result = await automationService.execute(name, automationContext);\n return { handled: true, response: this.success(result) };\n }\n }\n\n // POST /:name/toggle → toggleFlow\n if (parts[1] === 'toggle' && m === 'POST') {\n if (typeof automationService.toggleFlow === 'function') {\n await automationService.toggleFlow(name, body?.enabled ?? true);\n return { handled: true, response: this.success({ name, enabled: body?.enabled ?? true }) };\n }\n }\n\n // POST /:name/runs/:runId/resume → resume a paused run (screen-flow\n // runtime / ADR-0019). Body `{ inputs }` = a screen node's collected\n // values, applied as bare flow variables; `output`/`branchLabel` also\n // forwarded for approval-style resumes. Returns the next paused\n // `{ screen }` (multi-screen) or the completed result.\n if (parts[1] === 'runs' && parts[2] && parts[3] === 'resume' && m === 'POST') {\n if (typeof automationService.resume === 'function') {\n const b = (body && typeof body === 'object') ? body : {};\n const inputs = (b.inputs ?? b.variables);\n const signal: any = {};\n if (inputs && typeof inputs === 'object') signal.variables = inputs;\n if (b.output && typeof b.output === 'object') signal.output = b.output;\n if (typeof b.branchLabel === 'string') signal.branchLabel = b.branchLabel;\n const result = await automationService.resume(parts[2], signal);\n return { handled: true, response: this.success(result) };\n }\n return { handled: true, response: this.error('Resume not supported', 501) };\n }\n\n // GET /:name/runs/:runId/screen → the screen a paused run awaits\n // (refresh-safe re-fetch for the UI flow-runner).\n if (parts[1] === 'runs' && parts[2] && parts[3] === 'screen' && m === 'GET') {\n if (typeof automationService.getSuspendedScreen === 'function') {\n const screen = automationService.getSuspendedScreen(parts[2]);\n if (!screen) return { handled: true, response: this.error('No pending screen for run', 404) };\n return { handled: true, response: this.success({ runId: parts[2], screen }) };\n }\n return { handled: true, response: this.error('Screen lookup not supported', 501) };\n }\n\n // GET /:name/runs/:runId → getRun\n if (parts[1] === 'runs' && parts[2] && !parts[3] && m === 'GET') {\n if (typeof automationService.getRun === 'function') {\n const run = await automationService.getRun(parts[2]);\n if (!run) return { handled: true, response: this.error('Execution not found', 404) };\n return { handled: true, response: this.success(run) };\n }\n }\n\n // GET /:name/runs → listRuns\n if (parts[1] === 'runs' && !parts[2] && m === 'GET') {\n if (typeof automationService.listRuns === 'function') {\n const options = query ? { limit: query.limit ? Number(query.limit) : undefined, cursor: query.cursor } : undefined;\n const runs = await automationService.listRuns(name, options);\n return { handled: true, response: this.success({ runs, hasMore: false }) };\n }\n }\n\n // GET /:name → getFlow (no sub-path)\n if (parts.length === 1 && m === 'GET') {\n if (typeof automationService.getFlow === 'function') {\n const flow = await automationService.getFlow(name);\n if (!flow) return { handled: true, response: this.error('Flow not found', 404) };\n return { handled: true, response: this.success(flow) };\n }\n }\n\n // PUT /:name → updateFlow\n if (parts.length === 1 && m === 'PUT') {\n if (typeof automationService.registerFlow === 'function') {\n automationService.registerFlow(name, body?.definition ?? body);\n return { handled: true, response: this.success(body?.definition ?? body) };\n }\n }\n\n // DELETE /:name → deleteFlow\n if (parts.length === 1 && m === 'DELETE') {\n if (typeof automationService.unregisterFlow === 'function') {\n automationService.unregisterFlow(name);\n return { handled: true, response: this.success({ name, deleted: true }) };\n }\n }\n }\n \n return { handled: false };\n }\n\n private getServicesMap(): Record<string, any> {\n if (this.kernel.services instanceof Map) {\n return Object.fromEntries(this.kernel.services);\n }\n return this.kernel.services || {};\n }\n\n private async getService(name: CoreServiceName) {\n return this.resolveService(name);\n }\n\n /**\n * Resolve any service by name, supporting async factories.\n * Fallback chain: getServiceAsync(scopeId) → getServiceAsync → getService (sync) → context.getService → services map.\n * Only returns when a non-null service is found; otherwise falls through to the next step.\n *\n * When `scopeId` is provided, tries the SCOPED factory on `defaultKernel` first (SharedProjectPlugin\n * mode). Falls back to the current `kernel` for singleton / legacy services.\n */\n private async resolveService(name: string, scopeId?: string) {\n // Prefer scoped lookup on defaultKernel when scopeId is given (shared-kernel / multi-environment mode)\n if (scopeId && typeof this.defaultKernel.getServiceAsync === 'function') {\n try {\n const svc = await this.defaultKernel.getServiceAsync(name, scopeId);\n if (svc != null) return svc;\n } catch {\n // Not a scoped service — fall through to singleton resolution\n }\n }\n // Prefer async resolution to support factory-based services (e.g. auth, analytics, protocol)\n if (typeof this.kernel.getServiceAsync === 'function') {\n try {\n const svc = await this.kernel.getServiceAsync(name);\n if (svc != null) return svc;\n } catch {\n // Service not registered or async resolution failed — fall through\n }\n }\n if (typeof this.kernel.getService === 'function') {\n try {\n const svc = await this.kernel.getService(name);\n if (svc != null) return svc;\n } catch {\n // Service not registered or sync resolution threw \"is async\" — fall through\n }\n }\n if (this.kernel?.context?.getService) {\n try {\n const svc = await this.kernel.context.getService(name);\n if (svc != null) return svc;\n } catch {\n // Service not registered — fall through\n }\n }\n const services = this.getServicesMap();\n return services[name];\n }\n\n /**\n * Get the ObjectQL service which provides access to SchemaRegistry.\n * Tries multiple access patterns since kernel structure varies.\n */\n private async getObjectQLService(scopeId?: string): Promise<any> {\n // 1. Try via resolveService (handles scoped, async factories, sync, context, and map)\n try {\n const svc = await this.resolveService('objectql', scopeId);\n if (svc?.registry) return svc;\n } catch { /* service not available */ }\n return null;\n }\n\n /**\n * Handle action invocation routes (`/actions/...`).\n *\n * Dispatches a named, server-registered action handler (registered via\n * `engine.registerAction(objectName, actionName, handler)`) over HTTP.\n * Three URL shapes are accepted to keep the client contract flexible:\n *\n * - `POST /actions/:object/:action` — record-scoped action\n * - `POST /actions/:object/:action/:recordId` — record-scoped action with id in URL\n * - `POST /actions/global/:action` — wildcard (\"*\") action\n *\n * Body shape: `{ recordId?: string, params?: Record<string, unknown> }`.\n * The handler is invoked with an `ActionContext` of:\n * `{ record, user, engine, params }`\n * where `engine` exposes the slimmed CRUD surface used by CRM handlers\n * (`insert`, `update`, `delete`, `find`).\n */\n async handleActions(path: string, method: string, body: any, _context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n if (method.toUpperCase() !== 'POST') {\n return { handled: true, response: this.error('Method not allowed', 405) };\n }\n const parts = path.replace(/^\\/+|\\/+$/g, '').split('/').filter(Boolean);\n if (parts.length < 2) {\n return { handled: true, response: this.error('Path must be /actions/:object/:action', 400) };\n }\n const objectName = parts[0];\n const actionName = parts[1];\n const recordIdFromPath = parts[2];\n\n // Resolve project scope so the right project kernel's ObjectQL is\n // used. For bare URLs the URL prefix already stripped any `/projects/:id`\n // segment, so fall back to the single-environment default if unset.\n if (!_context.environmentId) {\n const def = this.resolveDefaultProject();\n if (def?.environmentId) _context.environmentId = def.environmentId;\n }\n\n // Replicate the kernel swap that `dispatcher.handle()` does for\n // data/meta/automation routes. Action routes are registered on the\n // raw HTTP server and skip the `handle()` chain, so without this\n // swap `getObjectQLService` would resolve the control-plane kernel\n // (where the CRM bundle's actions are NOT registered).\n let projectQl: any = null;\n if (this.kernelManager && _context.environmentId && _context.environmentId !== 'platform') {\n try {\n const projectKernel: any = await this.kernelManager.getOrCreate(_context.environmentId);\n if (projectKernel) {\n this.kernel = projectKernel;\n // Resolve the project kernel's own ObjectQL DIRECTLY so we\n // bypass the control-plane's scoped factory (which would\n // hand back a different instance with no registered\n // actions/hooks for this project's bundle).\n if (typeof projectKernel.getServiceAsync === 'function') {\n projectQl = await projectKernel.getServiceAsync('objectql').catch(() => null);\n }\n }\n } catch {\n // fall back to defaultKernel — getObjectQLService will report\n // \"Data engine not available\" if no engine is reachable.\n }\n }\n\n const ql: any = projectQl ?? await this.getObjectQLService(_context?.environmentId);\n if (!ql || typeof ql.executeAction !== 'function') {\n return { handled: true, response: this.error('Data engine not available', 503) };\n }\n\n // Resolve the handler — fall back to wildcard '*' if the object-specific key is missing.\n // Since engine.executeAction throws when the key is unknown, we probe via the internal\n // map by attempting the call inside a try/catch and rotating to '*'.\n const tryExecute = async (obj: string) => {\n return ql.executeAction(obj, actionName, actionContext);\n };\n\n const reqBody = body && typeof body === 'object' ? body : {};\n const recordId = recordIdFromPath ?? reqBody.recordId;\n const reqParams = (reqBody.params && typeof reqBody.params === 'object') ? reqBody.params : {};\n\n // Load the record (best-effort) so handlers can rely on `ctx.record`.\n let record: Record<string, unknown> = {};\n if (recordId && objectName !== 'global') {\n try {\n const got = await this.callData('get', { object: objectName, id: recordId }, _context.dataDriver, _context.environmentId, _context.executionContext);\n if (got?.record) record = got.record;\n } catch { /* record may not exist for new-record actions; pass empty */ }\n }\n if (record && (record as any).id == null && recordId) (record as any).id = recordId;\n\n // Slim engine facade matching the ActionContext.engine shape used by CRM handlers.\n const engineFacade = {\n async insert(object: string, data: Record<string, unknown>): Promise<{ id: string }> {\n const res = await ql.insert(object, data);\n const id = (res && (res as any).id) ?? (data as any).id;\n return { id };\n },\n async update(object: string, id: string, data: Record<string, unknown>): Promise<void> {\n await ql.update(object, data, { where: { id } });\n },\n async delete(object: string, id: string): Promise<void> {\n await ql.delete(object, { where: { id } });\n },\n async find(object: string, query: Record<string, unknown>): Promise<Array<Record<string, unknown>>> {\n const opts = query && Object.keys(query).length ? { where: query } : undefined;\n const rows = await ql.find(object, opts as any);\n return Array.isArray(rows) ? rows : ((rows as any)?.value ?? []);\n },\n };\n\n const userIdFromAuth = (_context as any)?.user?.id ?? (_context as any)?.userId ?? 'system';\n const userFromAuth = (_context as any)?.user ?? { id: userIdFromAuth, name: userIdFromAuth };\n\n const actionContext: any = {\n record,\n user: userFromAuth,\n engine: engineFacade,\n params: { ...reqParams, recordId, objectName },\n };\n\n try {\n // Try object-specific first; on \"not found\" error, fall back to wildcard.\n let result: any;\n try {\n result = await tryExecute(objectName);\n } catch (err: any) {\n const msg = String(err?.message ?? err ?? '');\n if (/not found/i.test(msg) && objectName !== '*') {\n result = await tryExecute('*');\n } else {\n throw err;\n }\n }\n return { handled: true, response: this.success({ success: true, data: result }) };\n } catch (err: any) {\n const msg = err?.message ?? String(err);\n return { handled: true, response: this.success({ success: false, error: msg }) };\n }\n }\n\n /**\n * Handle AI service routes (/ai/chat, /ai/models, /ai/conversations, etc.)\n * Resolves the AI service and its built-in route handlers, then dispatches.\n */\n async handleAI(subPath: string, method: string, body: any, query: any, context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n let aiService: any;\n try {\n aiService = await this.resolveService('ai');\n } catch {\n // AI service not registered\n }\n\n if (!aiService) {\n return {\n handled: true,\n response: {\n status: 404,\n body: { success: false, error: { message: 'AI service is not configured', code: 404 } },\n },\n };\n }\n\n // The AI service exposes route definitions via buildAIRoutes.\n // We match the request path against known AI route patterns.\n const fullPath = `/api/v1${subPath}`;\n\n // Build a simple param-extracting matcher for route patterns like /api/v1/ai/conversations/:id\n const matchRoute = (pattern: string, path: string): Record<string, string> | null => {\n const patternParts = pattern.split('/');\n const pathParts = path.split('/');\n if (patternParts.length !== pathParts.length) return null;\n const params: Record<string, string> = {};\n for (let i = 0; i < patternParts.length; i++) {\n if (patternParts[i].startsWith(':')) {\n params[patternParts[i].substring(1)] = pathParts[i];\n } else if (patternParts[i] !== pathParts[i]) {\n return null;\n }\n }\n return params;\n };\n\n // Try to get route definitions from the AI service's cached routes\n const routes = (this.kernel as any).__aiRoutes as Array<{\n method: string; path: string; handler: (req: any) => Promise<any>;\n }> | undefined;\n\n if (!routes) {\n return {\n handled: true,\n response: {\n status: 503,\n body: { success: false, error: { message: 'AI service routes not yet initialized', code: 503 } },\n },\n };\n }\n\n for (const route of routes) {\n if (route.method !== method) continue;\n const params = matchRoute(route.path, fullPath);\n if (params === null) continue;\n\n // Resolve `req.user` from the already-resolved ExecutionContext so\n // AI route handlers can attribute the call to the authenticated\n // actor (drives auto-titled conversations, permission-aware\n // tools, HITL conversation linkage, …). Falls back to undefined\n // for anonymous requests — the route's own `auth: true` guard\n // is enforced by upstream middleware.\n const ec: any = context.executionContext;\n const user = ec?.userId\n ? {\n userId: ec.userId,\n id: ec.userId,\n displayName: ec.userDisplayName ?? ec.userName ?? ec.userId,\n email: ec.userEmail,\n roles: Array.isArray(ec.roles) ? ec.roles : [],\n permissions: Array.isArray(ec.permissions) ? ec.permissions : [],\n organizationId: ec.tenantId,\n }\n : undefined;\n\n const result = await route.handler({\n body,\n params,\n query,\n headers: context.request?.headers,\n user,\n });\n\n if (result.stream && result.events) {\n // Return a streaming result for the adapter to handle\n return {\n handled: true,\n result: {\n type: 'stream',\n contentType: result.vercelDataStream\n ? 'text/plain; charset=utf-8'\n : 'text/event-stream',\n events: result.events,\n vercelDataStream: result.vercelDataStream,\n headers: {\n 'Content-Type': result.vercelDataStream\n ? 'text/plain; charset=utf-8'\n : 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n },\n },\n };\n }\n\n return {\n handled: true,\n response: {\n status: result.status,\n body: result.body,\n },\n };\n }\n\n return {\n handled: true,\n response: this.routeNotFound(subPath),\n };\n }\n\n /**\n * Main Dispatcher Entry Point\n * Routes the request to the appropriate handler based on path and precedence\n */\n async dispatch(method: string, path: string, body: any, query: any, context: HttpProtocolContext, prefix?: string): Promise<HttpDispatcherResult> {\n let cleanPath = path.replace(/\\/$/, ''); // Remove trailing slash if present, but strict on clean paths\n\n // ── Environment Resolution ──\n // Resolve environment context for data-plane requests before routing\n await this.resolveEnvironmentContext(context, cleanPath);\n\n // ── Multi-Kernel Routing (ADR-0003 cloud mode) ──\n // When a KernelManager is wired in, per-request routing targets the\n // project's dedicated kernel. Self-hosted / legacy deployments leave\n // `kernelManager` unset and continue using the constructor kernel.\n // Reserved virtual id 'platform' addresses the control plane through\n // the regular project URL family — never spin up a per-project kernel\n // for it (there is no projects row to look up).\n if (this.kernelManager && context.environmentId && context.environmentId !== 'platform') {\n this.kernel = await this.kernelManager.getOrCreate(context.environmentId);\n } else {\n this.kernel = this.defaultKernel;\n }\n\n // Touch scope for TTL/LRU tracking in shared-kernel mode\n if (this.scopeManager && context.environmentId && context.environmentId !== 'platform') {\n this.scopeManager.touch(context.environmentId);\n }\n\n // ── Identity Resolution (RBAC/RLS/FLS context) ──\n // Resolve once per request; SecurityPlugin middleware reads\n // ctx.userId/roles/permissions/tenantId via opCtx.context.\n try {\n context.executionContext = await resolveExecutionContext({\n getService: (n: string) => this.resolveService(n, context.environmentId),\n getQl: () => Promise.resolve(this.getObjectQLService(context.environmentId)),\n request: context.request,\n });\n } catch {\n // anonymous request — leave executionContext undefined\n }\n\n // ── Project Membership Enforcement ──\n // Once the environmentId is known, gate scoped data/meta/AI/automation\n // routes on `sys_environment_member`. Control-plane paths, the system\n // project, and platform-org members bypass this check.\n const forbidden = await this.enforceProjectMembership(context, cleanPath);\n if (forbidden) {\n return { handled: true, response: forbidden };\n }\n\n // Strip the `/environments/:environmentId` prefix so the protocol dispatchers\n // below (meta, data, ui, automation, …) see the same shape whether\n // the caller used host-based routing, `X-Environment-Id`, or a scoped URL.\n const scopedMatch = cleanPath.match(/^\\/projects\\/[^/]+(\\/.*)?$/);\n if (scopedMatch) {\n cleanPath = scopedMatch[1] ?? '';\n }\n\n // 0. Discovery Endpoint (GET /discovery or GET /)\n // Standard route: /discovery (protocol-compliant)\n // Legacy route: / (empty path, for backward compatibility — MSW strips base URL)\n try {\n if ((cleanPath === '/discovery' || cleanPath === '') && method === 'GET') {\n const info = await this.getDiscoveryInfo(prefix ?? '');\n return { \n handled: true, \n response: this.success(info) \n };\n }\n\n // 0b. Health Endpoint (GET /health)\n if (cleanPath === '/health' && method === 'GET') {\n return {\n handled: true,\n response: this.success({\n status: 'ok',\n timestamp: new Date().toISOString(),\n version: '1.0.0',\n uptime: typeof process !== 'undefined' ? process.uptime() : undefined,\n }),\n };\n }\n\n // 0c. Plan-A diagnostics removed; the seed-replay and oauth2/callback\n // probes were temporary debugging tools used during the SSO rollout.\n\n // 1. System Protocols (Prefix-based)\n if (cleanPath.startsWith('/auth')) {\n return this.handleAuth(cleanPath.substring(5), method, body, context);\n }\n \n if (cleanPath.startsWith('/meta')) {\n return this.handleMetadata(cleanPath.substring(5), context, method, body, query);\n }\n\n if (cleanPath.startsWith('/data')) {\n return this.handleData(cleanPath.substring(5), method, body, query, context);\n }\n \n if (cleanPath.startsWith('/graphql')) {\n if (method === 'POST') return this.handleGraphQL(body, context);\n // GraphQL usually GET for Playground is handled by middleware but we can return 405 or handle it\n }\n\n if (cleanPath.startsWith('/storage')) {\n return this.handleStorage(cleanPath.substring(8), method, body, context); // body here is file/stream for upload\n }\n \n if (cleanPath.startsWith('/ui')) {\n return this.handleUi(cleanPath.substring(3), query, context);\n }\n\n if (cleanPath.startsWith('/automation')) {\n return this.handleAutomation(cleanPath.substring(11), method, body, context, query);\n }\n\n if (cleanPath.startsWith('/actions')) {\n return this.handleActions(cleanPath.substring(8), method, body, context);\n }\n \n if (cleanPath.startsWith('/analytics')) {\n return this.handleAnalytics(cleanPath.substring(10), method, body, context);\n }\n\n // In-app notifications (ADR-0030) — inbox list + receipt mark-read,\n // backed by the messaging service registered under the `notification` slot.\n if (cleanPath.startsWith('/notifications')) {\n return this.handleNotification(cleanPath.substring(14), method, body, query, context);\n }\n\n if (cleanPath.startsWith('/packages')) {\n return this.handlePackages(cleanPath.substring(9), method, body, query, context);\n }\n\n if (cleanPath.startsWith('/i18n')) {\n return this.handleI18n(cleanPath.substring(5), method, query, context);\n }\n\n // AI Service — delegate to the registered AI route handlers\n if (cleanPath.startsWith('/ai')) {\n return this.handleAI(cleanPath, method, body, query, context);\n }\n\n // OpenAPI Specification\n if (cleanPath === '/openapi.json' && method === 'GET') {\n try {\n const metaSvc = await this.resolveService('metadata', context.environmentId);\n if (metaSvc && typeof (metaSvc as any).generateOpenApi === 'function') {\n const result = await (metaSvc as any).generateOpenApi({});\n return { handled: true, response: this.success(result) };\n }\n } catch (e) {\n // If not implemented, fall through or return 404\n }\n }\n\n // 2. Custom API Endpoints (Registry lookup)\n // Check if there is a custom endpoint defined for this path\n const result = await this.handleApiEndpoint(cleanPath, method, body, query, context);\n if (result.handled) return result;\n\n // 3. Fallback — return semantic 404 with diagnostic info\n return {\n handled: true,\n response: this.routeNotFound(cleanPath),\n };\n } catch (e) {\n if (isPermissionDeniedError(e)) {\n return {\n handled: true,\n response: this.error(e.message, 403, { code: 'PERMISSION_DENIED', ...(e.details ?? {}) }),\n };\n }\n throw e;\n }\n }\n\n /**\n * Handles Custom API Endpoints defined in metadata\n */\n async handleApiEndpoint(path: string, method: string, body: any, query: any, context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n try {\n // Attempt to find a matching endpoint in the registry\n const metaSvc = await this.resolveService('metadata', context.environmentId);\n if (!metaSvc || typeof (metaSvc as any).matchEndpoint !== 'function') {\n return { handled: false };\n }\n const endpoint = await (metaSvc as any).matchEndpoint({ path, method });\n \n if (endpoint) {\n // Execute the endpoint target logic\n if (endpoint.type === 'flow') {\n const automationSvc = await this.resolveService('automation');\n if (!automationSvc || typeof (automationSvc as any).runFlow !== 'function') {\n return { handled: true, response: this.error('Automation service not available', 503) };\n }\n const result = await (automationSvc as any).runFlow({ \n flowId: endpoint.target, \n inputs: { ...query, ...body, _request: context.request } \n });\n return { handled: true, response: this.success(result) };\n }\n \n if (endpoint.type === 'script') {\n const automationSvc = await this.resolveService('automation');\n if (!automationSvc || typeof (automationSvc as any).runScript !== 'function') {\n return { handled: true, response: this.error('Automation service not available', 503) };\n }\n const result = await (automationSvc as any).runScript({ \n scriptName: endpoint.target, \n context: { ...query, ...body, request: context.request } \n });\n return { handled: true, response: this.success(result) };\n }\n\n if (endpoint.type === 'object_operation') {\n // e.g. Proxy to an object action\n if (endpoint.objectParams) {\n const { object, operation } = endpoint.objectParams;\n // Map standard CRUD operations\n if (operation === 'find') {\n const result = await this.callData('query', { object, query });\n // Spec: FindDataResponse = { object, records, total?, hasMore? }\n return { handled: true, response: this.success(result.records, { total: result.total }) };\n }\n if (operation === 'get' && query.id) {\n const result = await this.callData('get', { object, id: query.id });\n return { handled: true, response: this.success(result) };\n }\n if (operation === 'create') {\n const result = await this.callData('create', { object, data: body });\n return { handled: true, response: this.success(result) };\n }\n }\n }\n\n if (endpoint.type === 'proxy') {\n return { \n handled: true, \n response: { \n status: 200, \n body: { proxy: true, target: endpoint.target, note: 'Proxy execution requires http-client service' } \n } \n };\n }\n }\n } catch (e) {\n // If matchEndpoint fails (e.g. not found), we just return not handled\n // so we can fallback to 404 or other handlers\n }\n\n return { handled: false };\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * resolveExecutionContext — REST entry-point identity resolver.\n *\n * Builds an {@link ExecutionContext} from an incoming HTTP request by combining:\n * - better-auth Bearer/Session cookies (`authService.api.getSession`)\n * - API Key headers (`X-API-Key` / `Authorization: ApiKey <token>`) — first\n * via better-auth's apiKey plugin if available, otherwise a direct lookup\n * against the `sys_api_key` system object.\n * - `sys_member` lookup for `(userId, activeOrganizationId)` to populate\n * organization-scoped roles, plus any extra permission sets bound through\n * the `sys_user_permission_set` / `sys_role_permission_set` link tables.\n *\n * The resolver is intentionally non-fatal: when auth is not wired up or any\n * of the dependent services are unavailable, it returns the partial context\n * that can be reconstructed (even an empty `{ isSystem: false, roles: [],\n * permissions: [] }`). Permission enforcement is the SecurityPlugin's job.\n */\n\nimport type { ExecutionContext } from '@objectstack/spec/kernel';\n\ninterface ResolveOptions {\n /** Function returning a service from the active kernel (or undefined). */\n getService: (name: string) => Promise<any> | any;\n /** Function returning the data engine (ObjectQL) for the active scope. */\n getQl: () => Promise<any> | any;\n /** The raw incoming HTTP request (Fetch Request, Node IncomingMessage, …). */\n request: any;\n}\n\nfunction readHeader(headers: any, name: string): string | undefined {\n if (!headers) return undefined;\n const lower = name.toLowerCase();\n if (typeof headers.get === 'function') {\n const v = headers.get(name) ?? headers.get(lower);\n return v == null ? undefined : String(v);\n }\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === lower) {\n const v = headers[key];\n return Array.isArray(v) ? v[0] : v == null ? undefined : String(v);\n }\n }\n return undefined;\n}\n\nfunction extractApiKey(headers: any): string | undefined {\n const x = readHeader(headers, 'x-api-key');\n if (x) return x.trim();\n const auth = readHeader(headers, 'authorization');\n if (!auth) return undefined;\n const m = auth.match(/^ApiKey\\s+(.+)$/i);\n return m ? m[1].trim() : undefined;\n}\n\n/**\n * Convert the dispatcher's plain `Record<string,string>` headers map into\n * a Web `Headers` instance so libraries like better-auth (which reads via\n * `headers.get('cookie')`) work uniformly.\n */\nfunction toHeaders(input: any): any {\n if (!input) return new Headers();\n if (typeof Headers !== 'undefined' && input instanceof Headers) return input;\n const h = new Headers();\n if (typeof input.entries === 'function') {\n for (const [k, v] of input.entries()) h.set(String(k), String(v));\n return h;\n }\n for (const k of Object.keys(input)) {\n const v = (input as any)[k];\n if (v == null) continue;\n h.set(String(k), Array.isArray(v) ? v.join(',') : String(v));\n }\n return h;\n}\n\nfunction safeJsonParse<T>(s: string, fallback: T): T {\n try { return JSON.parse(s) as T; } catch { return fallback; }\n}\n\nasync function tryFind(ql: any, object: string, where: any, limit = 100): Promise<any[]> {\n if (!ql || typeof ql.find !== 'function') return [];\n try {\n let rows = await ql.find(object, { where, limit, context: { isSystem: true } } as any);\n if (rows && (rows as any).value) rows = (rows as any).value;\n return Array.isArray(rows) ? rows : [];\n } catch {\n return [];\n }\n}\n\n/**\n * Resolve the {@link ExecutionContext} for an inbound request.\n *\n * Always resolves — never throws. Anonymous requests yield\n * `{ isSystem: false, roles: [], permissions: [] }`.\n */\nexport async function resolveExecutionContext(opts: ResolveOptions): Promise<ExecutionContext> {\n const headers = opts.request?.headers;\n const ctx: ExecutionContext = {\n roles: [],\n permissions: [],\n systemPermissions: [],\n isSystem: false,\n };\n\n let userId: string | undefined;\n let tenantId: string | undefined;\n\n // 1. API Key path — takes precedence over session, since callers explicitly\n // opt in to API-key auth via the header.\n const apiKey = extractApiKey(headers);\n if (apiKey) {\n try {\n const authService: any = await opts.getService('auth');\n // better-auth apiKey plugin (if enabled) exposes a verify endpoint.\n const verify = authService?.api?.verifyApiKey ?? authService?.api?.apiKey?.verify;\n if (typeof verify === 'function') {\n const res = await verify({ body: { key: apiKey } });\n const payload = res?.key ?? res;\n if (payload?.userId) userId = payload.userId;\n if (payload?.organizationId) tenantId = payload.organizationId;\n if (Array.isArray(payload?.permissions)) {\n ctx.permissions!.push(...payload.permissions);\n }\n if (Array.isArray(payload?.scopes)) {\n ctx.permissions!.push(...payload.scopes);\n }\n }\n } catch {\n // ignore — fall through to direct lookup\n }\n\n if (!userId) {\n // Direct lookup against sys_api_key — supports keys provisioned outside\n // of better-auth (legacy or self-managed).\n const ql = await opts.getQl();\n const rows = await tryFind(ql, 'sys_api_key', { key: apiKey, active: true }, 1);\n const row = rows[0];\n if (row) {\n userId = row.user_id ?? row.userId;\n tenantId = row.organization_id ?? row.organizationId;\n if (Array.isArray(row.scopes)) ctx.permissions!.push(...row.scopes);\n }\n }\n }\n\n // 2. Session / Bearer path — fall back when API key did not resolve a user.\n if (!userId) {\n try {\n const authService: any = await opts.getService('auth');\n // The auth service surfaces its better-auth API either as `.api`\n // (legacy direct mount) or via `await getApi()` (lazy plugin).\n // Try both so we don't silently degrade to anonymous when the\n // shape differs across plugin versions.\n let api: any = authService?.api;\n if (!api && typeof authService?.getApi === 'function') {\n api = await authService.getApi();\n }\n const headersInstance = toHeaders(headers);\n const sessionData = await api?.getSession?.({ headers: headersInstance });\n userId = sessionData?.user?.id ?? sessionData?.session?.userId;\n tenantId = tenantId ?? sessionData?.session?.activeOrganizationId;\n ctx.accessToken = sessionData?.session?.token ?? ctx.accessToken;\n } catch {\n // no auth configured — return anonymous context\n }\n }\n\n if (userId) ctx.userId = userId;\n if (tenantId) ctx.tenantId = tenantId;\n\n if (!userId) return ctx;\n\n // 3. Resolve organization-scoped roles via sys_member, then merge any\n // permission sets bound via the link tables. All lookups go through\n // ObjectQL with `isSystem: true` to avoid recursion through the\n // SecurityPlugin middleware.\n const ql = await opts.getQl();\n if (!ql) return ctx;\n\n const memberWhere: any = tenantId\n ? { user_id: userId, organization_id: tenantId }\n : { user_id: userId };\n const members = await tryFind(ql, 'sys_member', memberWhere, 50);\n for (const m of members) {\n if (m.role && typeof m.role === 'string') {\n // better-auth stores comma-separated roles for multi-role membership.\n for (const r of m.role.split(',').map((s: string) => s.trim()).filter(Boolean)) {\n if (!ctx.roles!.includes(r)) ctx.roles!.push(r);\n }\n }\n }\n\n // 3a. Resolve fellow-organization user IDs so RLS can scope identity\n // tables (`sys_user`) to collaborators in the active org via\n // `id IN (current_user.org_user_ids)`. Without this, the default\n // `id = current_user.id` policy on sys_user makes @-mention pickers,\n // owner/assignee lookups and reviewer selectors all return just the\n // current user. Hard-capped at 1000 members per request — large\n // enterprises should plug in a cache or directory adapter.\n if (tenantId) {\n const orgMembers = await tryFind(\n ql,\n 'sys_member',\n { organization_id: tenantId },\n 1000,\n );\n const orgUserIds = Array.from(\n new Set(\n orgMembers\n .map((m) => m.user_id ?? m.userId)\n .filter((v): v is string => typeof v === 'string' && v.length > 0),\n ),\n );\n // Always include self even if the sys_member lookup misfires (e.g.\n // API key auth where the user is recognised but not in sys_member).\n if (!orgUserIds.includes(userId)) orgUserIds.push(userId);\n (ctx as any).org_user_ids = orgUserIds;\n } else {\n // No active org → at minimum the user can see themselves.\n (ctx as any).org_user_ids = [userId];\n }\n\n // Resolve user-scoped permission sets.\n const upsRows = await tryFind(\n ql,\n 'sys_user_permission_set',\n tenantId\n ? { user_id: userId, organization_id: tenantId }\n : { user_id: userId },\n 100,\n );\n const psIds = new Set<string>(\n upsRows.map((r) => r.permission_set_id ?? r.permissionSetId).filter(Boolean),\n );\n\n // Resolve role-bound permission sets.\n if (ctx.roles!.length > 0) {\n const roleRows = await tryFind(ql, 'sys_role', { name: { $in: ctx.roles } }, 100);\n const roleIds = roleRows.map((r) => r.id).filter(Boolean);\n if (roleIds.length > 0) {\n const rpsRows = await tryFind(\n ql,\n 'sys_role_permission_set',\n { role_id: { $in: roleIds } },\n 500,\n );\n for (const r of rpsRows) {\n const id = r.permission_set_id ?? r.permissionSetId;\n if (id) psIds.add(id);\n }\n }\n }\n\n if (psIds.size > 0) {\n // Surface permission set names through ctx.permissions so downstream\n // SecurityPlugin can look them up. We store the canonical `name` field.\n const psRows = await tryFind(\n ql,\n 'sys_permission_set',\n { id: { $in: Array.from(psIds) } },\n 500,\n );\n const tabRank: Record<string, number> = {\n hidden: 0,\n default_off: 1,\n default_on: 2,\n visible: 3,\n };\n const mergedTabs: Record<string, 'visible' | 'hidden' | 'default_on' | 'default_off'> = {};\n for (const ps of psRows) {\n if (ps.name && !ctx.permissions!.includes(ps.name)) {\n ctx.permissions!.push(ps.name);\n }\n // System permissions may be stored as JSON string in DB rows.\n const sysPerms = typeof ps.system_permissions === 'string'\n ? safeJsonParse(ps.system_permissions, [])\n : (ps.system_permissions ?? ps.systemPermissions);\n if (Array.isArray(sysPerms)) {\n for (const p of sysPerms) {\n if (typeof p === 'string' && !ctx.systemPermissions!.includes(p)) {\n ctx.systemPermissions!.push(p);\n }\n }\n }\n const tabs = typeof ps.tab_permissions === 'string'\n ? safeJsonParse(ps.tab_permissions, {})\n : (ps.tab_permissions ?? ps.tabPermissions);\n if (tabs && typeof tabs === 'object') {\n for (const [app, val] of Object.entries(tabs as Record<string, unknown>)) {\n if (typeof val !== 'string' || !(val in tabRank)) continue;\n const cur = mergedTabs[app];\n if (!cur || tabRank[val] > tabRank[cur]) {\n mergedTabs[app] = val as 'visible' | 'hidden' | 'default_on' | 'default_off';\n }\n }\n }\n }\n if (Object.keys(mergedTabs).length > 0) {\n ctx.tabPermissions = mergedTabs;\n }\n }\n\n return ctx;\n}\n\n/**\n * Typed sentinel error thrown by SecurityPlugin (and re-thrown here) when an\n * operation is denied. The dispatcher catches it and translates to HTTP 403.\n *\n * Kept structurally identical to {@link `@objectstack/plugin-security`}'s\n * `PermissionDeniedError` so `isPermissionDeniedError` matches whichever\n * class instance crosses the boundary, regardless of which package owns\n * the actual class identity at runtime. We do not add a hard dependency\n * on `plugin-security` here to keep the runtime usable in stack\n * compositions without security enforcement.\n */\nexport class PermissionDeniedError extends Error {\n readonly code = 'PERMISSION_DENIED';\n readonly statusCode = 403;\n readonly details?: Record<string, unknown>;\n constructor(message: string, details?: Record<string, unknown>) {\n super(message);\n this.name = 'PermissionDeniedError';\n this.details = details;\n }\n}\n\nexport function isPermissionDeniedError(e: unknown): e is PermissionDeniedError {\n if (!e || typeof e !== 'object') return false;\n const anyE = e as any;\n return (\n anyE.name === 'PermissionDeniedError' ||\n anyE.code === 'PERMISSION_DENIED' ||\n (typeof anyE.message === 'string' && anyE.message.startsWith('[Security] Access denied'))\n );\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Security response headers builder.\n *\n * Returns the conservative defaults every production API server should\n * send on every response. Designed to be merged with route-specific\n * headers by the dispatcher (`sendResult`) so all adapters (Hono,\n * Fastify, Express, Next.js, …) get them uniformly without each one\n * re-implementing helmet.\n *\n * What we DO opinionate:\n * - Content-Security-Policy (api-default: deny everything but self)\n * - Strict-Transport-Security (HSTS, prod-only — TLS is the caller's\n * responsibility; we just emit the header)\n * - X-Content-Type-Options: nosniff\n * - X-Frame-Options: DENY (anti clickjacking)\n * - Referrer-Policy: no-referrer\n * - Permissions-Policy: geolocation=(), camera=(), microphone=()\n * - Cross-Origin-Resource-Policy: same-origin\n *\n * What we DON'T opinionate:\n * - X-XSS-Protection (deprecated)\n * - CORS — that's an app concern, configure separately\n * - CSP for HTML pages — set a different CSP at the SPA host\n *\n * Every header can be overridden or disabled by config.\n */\n\nexport interface SecurityHeadersOptions {\n /**\n * Enable HSTS. Set to `true` in production behind TLS. When `false`\n * the Strict-Transport-Security header is omitted.\n * @default false\n */\n hsts?: boolean | {\n /** Max-age in seconds. @default 15552000 (180 days) */\n maxAge?: number;\n includeSubDomains?: boolean;\n preload?: boolean;\n };\n /**\n * Override the Content-Security-Policy header. Pass `false` to omit.\n * @default \"default-src 'none'; frame-ancestors 'none'\"\n */\n contentSecurityPolicy?: string | false;\n /**\n * Override X-Frame-Options. @default 'DENY'\n */\n frameOptions?: 'DENY' | 'SAMEORIGIN' | false;\n /**\n * Override Referrer-Policy. @default 'no-referrer'\n */\n referrerPolicy?: string | false;\n /**\n * Override Permissions-Policy. Pass `false` to omit.\n * @default 'geolocation=(), camera=(), microphone=(), payment=()'\n */\n permissionsPolicy?: string | false;\n /**\n * Override Cross-Origin-Resource-Policy. @default 'same-origin'\n */\n corp?: 'same-origin' | 'same-site' | 'cross-origin' | false;\n /**\n * Free-form extra headers merged last.\n */\n extra?: Record<string, string>;\n}\n\n/**\n * Build a header map ready to be `Object.assign`'d into a response.\n * Idempotent and synchronous — safe to call per-request.\n */\nexport function buildSecurityHeaders(opts: SecurityHeadersOptions = {}): Record<string, string> {\n const h: Record<string, string> = {};\n\n if (opts.contentSecurityPolicy !== false) {\n h['Content-Security-Policy'] =\n opts.contentSecurityPolicy ?? \"default-src 'none'; frame-ancestors 'none'\";\n }\n\n if (opts.hsts) {\n const cfg = typeof opts.hsts === 'object' ? opts.hsts : {};\n const maxAge = cfg.maxAge ?? 15_552_000;\n const parts = [`max-age=${maxAge}`];\n if (cfg.includeSubDomains ?? true) parts.push('includeSubDomains');\n if (cfg.preload) parts.push('preload');\n h['Strict-Transport-Security'] = parts.join('; ');\n }\n\n h['X-Content-Type-Options'] = 'nosniff';\n\n if (opts.frameOptions !== false) {\n h['X-Frame-Options'] = opts.frameOptions ?? 'DENY';\n }\n\n if (opts.referrerPolicy !== false) {\n h['Referrer-Policy'] = opts.referrerPolicy ?? 'no-referrer';\n }\n\n if (opts.permissionsPolicy !== false) {\n h['Permissions-Policy'] =\n opts.permissionsPolicy ?? 'geolocation=(), camera=(), microphone=(), payment=()';\n }\n\n if (opts.corp !== false) {\n h['Cross-Origin-Resource-Policy'] = opts.corp ?? 'same-origin';\n }\n\n if (opts.extra) {\n Object.assign(h, opts.extra);\n }\n\n return h;\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * In-memory token-bucket rate limiter.\n *\n * Designed to be adapter-agnostic — the dispatcher calls `consume(key)`\n * with a request fingerprint (IP, IP+route bucket, or user id) and\n * short-circuits with 429 if the bucket is empty.\n *\n * For production multi-instance deploys, swap the in-memory store via\n * `RateLimitStore`. The shape is intentionally narrow so a Redis-backed\n * implementation is straightforward.\n */\n\nexport interface RateLimitDecision {\n allowed: boolean;\n /** Remaining tokens in the bucket after this consume. */\n remaining: number;\n /** Wall-clock ms until next token is available (when not allowed). */\n retryAfterMs: number;\n /** UNIX ms when the limit window resets. */\n resetAt: number;\n}\n\nexport interface RateLimitBucketConfig {\n /** Max tokens (bucket capacity). */\n capacity: number;\n /** Tokens added per second. */\n refillPerSec: number;\n /** Optional cost override for the consume operation. @default 1 */\n defaultCost?: number;\n}\n\ninterface BucketState {\n tokens: number;\n /** Last refill timestamp (ms). */\n lastRefill: number;\n}\n\n/**\n * Storage interface — swap for Redis/Memcached in clustered deploys.\n * Implementations MUST be safe under concurrent access.\n */\nexport interface RateLimitStore {\n get(key: string): BucketState | undefined;\n set(key: string, state: BucketState): void;\n /** Cleanup hint — implementations may evict idle entries. */\n prune?(olderThanMs: number): void;\n}\n\nclass MemoryStore implements RateLimitStore {\n private buckets = new Map<string, BucketState>();\n private maxEntries: number;\n\n constructor(maxEntries = 100_000) {\n this.maxEntries = maxEntries;\n }\n\n get(key: string): BucketState | undefined {\n return this.buckets.get(key);\n }\n\n set(key: string, state: BucketState): void {\n // Crude LRU eviction — drop the oldest 10% when we hit the cap.\n // Good enough for an in-memory store; replace with Redis if you\n // need precision under load.\n if (this.buckets.size >= this.maxEntries) {\n const dropCount = Math.max(1, Math.floor(this.maxEntries / 10));\n const iter = this.buckets.keys();\n for (let i = 0; i < dropCount; i++) {\n const k = iter.next().value;\n if (!k) break;\n this.buckets.delete(k);\n }\n }\n this.buckets.set(key, state);\n }\n\n prune(olderThanMs: number): void {\n const cutoff = Date.now() - olderThanMs;\n for (const [k, v] of this.buckets) {\n if (v.lastRefill < cutoff) this.buckets.delete(k);\n }\n }\n}\n\nexport class RateLimiter {\n private config: RateLimitBucketConfig;\n private store: RateLimitStore;\n private now: () => number;\n\n constructor(config: RateLimitBucketConfig, opts: { store?: RateLimitStore; now?: () => number } = {}) {\n if (config.capacity <= 0) throw new Error('RateLimiter: capacity must be > 0');\n if (config.refillPerSec <= 0) throw new Error('RateLimiter: refillPerSec must be > 0');\n this.config = config;\n this.store = opts.store ?? new MemoryStore();\n // Injectable clock keeps tests deterministic.\n this.now = opts.now ?? Date.now;\n }\n\n /**\n * Attempt to consume `cost` tokens for `key`. Returns a decision\n * describing whether the request should proceed and, if not, how\n * long the caller should wait before retrying.\n */\n consume(key: string, cost = this.config.defaultCost ?? 1): RateLimitDecision {\n const now = this.now();\n const { capacity, refillPerSec } = this.config;\n\n let state = this.store.get(key);\n if (!state) {\n state = { tokens: capacity, lastRefill: now };\n } else {\n const elapsedSec = (now - state.lastRefill) / 1000;\n if (elapsedSec > 0) {\n state = {\n tokens: Math.min(capacity, state.tokens + elapsedSec * refillPerSec),\n lastRefill: now,\n };\n }\n }\n\n if (state.tokens >= cost) {\n state.tokens -= cost;\n this.store.set(key, state);\n return {\n allowed: true,\n remaining: Math.floor(state.tokens),\n retryAfterMs: 0,\n resetAt: now + Math.ceil(((capacity - state.tokens) / refillPerSec) * 1000),\n };\n }\n\n const tokensNeeded = cost - state.tokens;\n const retryAfterMs = Math.ceil((tokensNeeded / refillPerSec) * 1000);\n this.store.set(key, state);\n return {\n allowed: false,\n remaining: Math.floor(state.tokens),\n retryAfterMs,\n resetAt: now + retryAfterMs,\n };\n }\n\n /** Force-reset a key (e.g. after a successful auth flow). */\n reset(key: string): void {\n this.store.set(key, { tokens: this.config.capacity, lastRefill: this.now() });\n }\n}\n\n/**\n * Curated default buckets for the three traffic classes ObjectStack\n * dispatches. Conservative — tune via `DispatcherPluginConfig.rateLimit`\n * for your deployment.\n *\n * - auth: 10 req / minute / IP — guards /auth/* against credential\n * stuffing and password-spray.\n * - write: 60 req / minute / IP — POST/PUT/PATCH/DELETE.\n * - read: 600 req / minute / IP — GET, including discovery and\n * metadata.\n *\n * \"Per-IP\" is just the suggested key shape; the dispatcher constructs\n * the key from `${ip}:${bucket}` so a single noisy IP can saturate\n * one bucket without blocking the others.\n */\nexport interface RateLimitDefaults {\n auth: RateLimitBucketConfig;\n write: RateLimitBucketConfig;\n read: RateLimitBucketConfig;\n}\n\nexport const DEFAULT_RATE_LIMITS: RateLimitDefaults = {\n auth: { capacity: 10, refillPerSec: 10 / 60 },\n write: { capacity: 60, refillPerSec: 60 / 60 },\n read: { capacity: 600, refillPerSec: 600 / 60 },\n};\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Request correlation primitives.\n *\n * Two concerns:\n *\n * 1. **Request IDs.** Every request gets a stable id that is echoed back\n * via `X-Request-Id`, threaded into log records, and (where the host\n * asks for it) made available to handlers via `req.requestId`. The id\n * comes from the incoming `X-Request-Id` header when present and\n * well-formed, otherwise we mint a fresh one.\n *\n * 2. **W3C Trace Context.** When clients pass `traceparent` per\n * <https://www.w3.org/TR/trace-context/>, we surface the parsed\n * `traceId` / `spanId` / `sampled` triple so the host can attach it\n * to its OTel SDK / logger.\n *\n * Both helpers are pure functions — no I/O, no side effects, no\n * dependencies — so they are safe to call on the hot path and trivial to\n * test.\n */\n\nconst MAX_REQUEST_ID_LENGTH = 200;\n\n/**\n * Allowed characters in a request id: alphanumerics plus `-_.:`.\n * Rejects whitespace, control chars, anything that could interfere\n * with header serialization or log parsing.\n */\nconst REQUEST_ID_PATTERN = /^[A-Za-z0-9._:-]+$/;\n\n/**\n * Extract a request id from incoming headers, validating shape. If\n * the header is missing or malformed, returns `undefined` and the\n * caller should mint one via {@link generateRequestId}.\n *\n * Header lookup is case-insensitive — adapters normalize differently.\n */\nexport function extractRequestId(headers: unknown): string | undefined {\n if (!headers || typeof headers !== 'object') return undefined;\n for (const [k, v] of Object.entries(headers as Record<string, unknown>)) {\n if (k.toLowerCase() !== 'x-request-id') continue;\n const raw = Array.isArray(v) ? v[0] : v;\n if (typeof raw !== 'string') return undefined;\n const trimmed = raw.trim();\n if (!trimmed || trimmed.length > MAX_REQUEST_ID_LENGTH) return undefined;\n if (!REQUEST_ID_PATTERN.test(trimmed)) return undefined;\n return trimmed;\n }\n return undefined;\n}\n\n/**\n * Mint a fresh request id. Uses `crypto.randomUUID()` when available\n * (Node 16+, modern browsers, edge runtimes); falls back to a\n * timestamp+random suffix otherwise so the function is universally\n * callable.\n *\n * Format is `req_<hex>`; the prefix makes it obvious in logs that the\n * id was minted by this layer (vs. propagated from a client).\n */\nexport function generateRequestId(): string {\n const g: { randomUUID?: () => string } | undefined =\n (globalThis as unknown as { crypto?: { randomUUID?: () => string } }).crypto;\n if (g && typeof g.randomUUID === 'function') {\n return `req_${g.randomUUID().replace(/-/g, '')}`;\n }\n const t = Date.now().toString(36);\n const r = Math.random().toString(36).slice(2, 12);\n return `req_${t}${r}`;\n}\n\n/**\n * Return the incoming request id if valid, otherwise mint one.\n */\nexport function resolveRequestId(\n headers: unknown,\n generate: () => string = generateRequestId,\n): string {\n return extractRequestId(headers) ?? generate();\n}\n\n/**\n * Parsed W3C Trace Context. `sampled` reflects the lowest flag bit.\n */\nexport interface TraceContext {\n traceId: string;\n spanId: string;\n sampled: boolean;\n}\n\nconst TRACEPARENT_PATTERN = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;\n\n/**\n * Parse a `traceparent` header value into its W3C fields. Returns\n * `undefined` for malformed input, the all-zero trace/span ids\n * (spec-mandated invalid), or unknown versions.\n */\nexport function parseTraceparent(value: unknown): TraceContext | undefined {\n if (typeof value !== 'string') return undefined;\n const m = TRACEPARENT_PATTERN.exec(value.trim().toLowerCase());\n if (!m) return undefined;\n const [, version, traceId, spanId, flags] = m;\n if (version !== '00') return undefined;\n if (/^0+$/.test(traceId) || /^0+$/.test(spanId)) return undefined;\n const sampled = (parseInt(flags, 16) & 0x01) === 0x01;\n return { traceId, spanId, sampled };\n}\n\n/**\n * Build the response header equivalent so downstream services\n * continue the trace.\n */\nexport function formatTraceparent(ctx: TraceContext): string {\n const flag = ctx.sampled ? '01' : '00';\n return `00-${ctx.traceId}-${ctx.spanId}-${flag}`;\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Backwards-compat shim. The canonical home for `MetricsRegistry`,\n * `NoopMetricsRegistry`, `InMemoryMetricsRegistry`, `MetricSample`, and\n * the `RUNTIME_METRICS` constants moved to `@objectstack/observability`\n * so deployment-target-neutral code (cloud, self-hosted, ...) can\n * import them without pulling in the whole runtime.\n *\n * Existing imports from `@objectstack/runtime`-internal paths continue\n * to work transparently via this re-export.\n */\nexport {\n NoopMetricsRegistry,\n InMemoryMetricsRegistry,\n RUNTIME_METRICS,\n type MetricsRegistry,\n type MetricSample,\n} from '@objectstack/observability';\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Backwards-compat shim. See `metrics.ts` for the rationale — the\n * canonical home is `@objectstack/observability`.\n */\nexport {\n NoopErrorReporter,\n InMemoryErrorReporter,\n type ErrorReporter,\n type CapturedError,\n} from '@objectstack/observability';\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport {\n NoopMetricsRegistry,\n NoopErrorReporter,\n resolveRequestId,\n RUNTIME_METRICS,\n type MetricsRegistry,\n type ErrorReporter,\n} from './index.js';\n\n/**\n * Options for {@link instrumentRouteHandler}. All fields optional; the\n * defaults make the wrapper a no-op (zero overhead, no behavior change).\n *\n * Hosts plug their own implementations to bridge to Prometheus / OTel /\n * Sentry / Datadog without the framework taking a hard dependency on\n * any of them.\n */\nexport interface InstrumentOptions {\n metrics?: MetricsRegistry;\n errorReporter?: ErrorReporter;\n /** Override the default `req_<uuid>` generator. */\n generateRequestId?: () => string;\n /** Response header that echoes the request id (default `X-Request-Id`). */\n requestIdHeader?: string;\n /**\n * Wall clock for tests. Defaults to `Date.now`; only `now()` is\n * called, so any monotonic source works.\n */\n now?: () => number;\n}\n\n/**\n * Wrap an HTTP route handler with the runtime's standard observability\n * lifecycle:\n *\n * 1. Resolve a request id from incoming `X-Request-Id` (or mint one).\n * 2. Set the request id on `req.requestId` and response header.\n * 3. Time the handler.\n * 4. Emit `http_requests_total{method,route,status}` counter and\n * `http_request_duration_ms{method,route}` histogram.\n * 5. On thrown errors, emit `http_request_errors_total` and call\n * `errorReporter.captureException` for 5xx.\n * 6. When the handler catches its own error and calls\n * `errorResponseBase` (which leaves a side-channel\n * `res.__obsRecordedError`), still call the error reporter.\n *\n * The wrapper does not catch the error — it re-throws so the host\n * server still gets a chance to render its own 500 page if needed.\n */\nexport function instrumentRouteHandler(\n method: string,\n route: string,\n handler: (req: any, res: any) => unknown,\n opts: InstrumentOptions = {},\n): (req: any, res: any) => Promise<void> {\n const metrics = opts.metrics ?? new NoopMetricsRegistry();\n const errorReporter = opts.errorReporter ?? new NoopErrorReporter();\n const generateRequestId = opts.generateRequestId;\n const requestIdHeader = opts.requestIdHeader ?? 'X-Request-Id';\n const now = opts.now ?? Date.now;\n\n return async (req: any, res: any) => {\n const requestId = resolveRequestId(req?.headers, generateRequestId);\n try {\n (req as any).requestId = requestId;\n } catch {\n // frozen req object — fine, the header is the source of truth\n }\n if (typeof res?.header === 'function') {\n try {\n res.header(requestIdHeader, requestId);\n } catch {\n // adapter rejects header injection here — fine\n }\n }\n\n // Capture the final status. We start at 200 (the adapter default\n // when no status() is called) and override on status() calls via\n // a tiny proxy.\n let status = 200;\n const origStatus =\n typeof res?.status === 'function' ? res.status.bind(res) : undefined;\n if (origStatus) {\n res.status = (code: number) => {\n status = code;\n return origStatus(code);\n };\n }\n\n const startedAt = now();\n let threw = false;\n try {\n await handler(req, res);\n } catch (err: any) {\n threw = true;\n status = err?.statusCode ?? 500;\n metrics.counter(RUNTIME_METRICS.httpRequestErrorsTotal, { method, route });\n if (status >= 500) {\n safeReport(errorReporter, err, { requestId, method, route });\n }\n throw err;\n } finally {\n const elapsed = now() - startedAt;\n metrics.counter(RUNTIME_METRICS.httpRequestsTotal, {\n method,\n route,\n status: String(status),\n });\n metrics.histogram(\n RUNTIME_METRICS.httpRequestDurationMs,\n elapsed,\n { method, route },\n );\n // Side-channel: handler caught the error and called\n // errorResponseBase, which recorded the original error on\n // `res.__obsRecordedError`. Pick it up so 5xx still\n // reaches the reporter even though we did not see the throw.\n if (!threw && status >= 500) {\n const recorded = (res as any)?.__obsRecordedError;\n if (recorded !== undefined) {\n safeReport(errorReporter, recorded, { requestId, method, route });\n }\n }\n }\n };\n}\n\nfunction safeReport(\n reporter: ErrorReporter,\n err: unknown,\n ctx: Record<string, unknown>,\n): void {\n try {\n reporter.captureException(err, ctx);\n } catch {\n // never let reporter failures mask the original error\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Plugin, PluginContext } from '@objectstack/core';\nimport {\n OBSERVABILITY_METRICS_SERVICE,\n OBSERVABILITY_ERRORS_SERVICE,\n} from '@objectstack/observability';\nimport {\n NoopMetricsRegistry,\n NoopErrorReporter,\n type MetricsRegistry,\n type ErrorReporter,\n} from './index.js';\n\n/**\n * Canonical service names other plugins look up to find the host's\n * configured observability backends. Re-exported from\n * `@objectstack/observability` so callers can grab them alongside the\n * plugin without straddling two packages.\n */\nexport { OBSERVABILITY_METRICS_SERVICE, OBSERVABILITY_ERRORS_SERVICE };\n\n/**\n * Options for {@link ObservabilityServicePlugin}.\n *\n * Either or both backends can be omitted; the omitted one resolves to\n * the corresponding no-op exporter so consumers can always rely on the\n * service being present.\n */\nexport interface ObservabilityServicePluginOptions {\n /** Metrics backend (e.g. `ConsoleMetricsRegistry`, `OtlpHttpMetricsRegistry`). */\n metrics?: MetricsRegistry;\n /** Error reporter backend (e.g. Sentry adapter). */\n errors?: ErrorReporter;\n}\n\n/**\n * `ObservabilityServicePlugin` — registers the host's\n * {@link MetricsRegistry} and {@link ErrorReporter} in the kernel\n * service registry under the canonical names so any other plugin can\n * look them up without each host having to thread observability config\n * through every plugin constructor.\n *\n * Resolution chain other plugins should follow:\n *\n * 1. Explicit option on the plugin's own options object (escape\n * hatch for tests / explicit wiring).\n * 2. `ctx.getService(OBSERVABILITY_METRICS_SERVICE)`.\n * 3. `NoopMetricsRegistry()` — never null.\n *\n * Register this plugin **before** any plugin that wants to consume the\n * services (cache, storage, dispatcher), otherwise the consumer's\n * `init` will fall through to the no-op default.\n *\n * @example\n * ```ts\n * import { ObjectKernel } from '@objectstack/core';\n * import {\n * ObservabilityServicePlugin,\n * CacheServicePlugin,\n * } from '@objectstack/runtime';\n * import { ConsoleMetricsRegistry } from '@objectstack/observability';\n *\n * const kernel = new ObjectKernel();\n * kernel.use(new ObservabilityServicePlugin({\n * metrics: new ConsoleMetricsRegistry(),\n * }));\n * kernel.use(new CacheServicePlugin()); // picks metrics up automatically\n * ```\n */\nexport class ObservabilityServicePlugin implements Plugin {\n name = 'com.objectstack.observability.service';\n version = '1.0.0';\n type = 'standard';\n\n private readonly options: ObservabilityServicePluginOptions;\n\n constructor(options: ObservabilityServicePluginOptions = {}) {\n this.options = options;\n }\n\n async init(ctx: PluginContext): Promise<void> {\n const metrics = this.options.metrics ?? new NoopMetricsRegistry();\n const errors = this.options.errors ?? new NoopErrorReporter();\n ctx.registerService(OBSERVABILITY_METRICS_SERVICE, metrics);\n ctx.registerService(OBSERVABILITY_ERRORS_SERVICE, errors);\n ctx.logger.info(\n `ObservabilityServicePlugin: registered metrics=${(metrics as any).constructor?.name ?? 'unknown'} errors=${(errors as any).constructor?.name ?? 'unknown'}`,\n );\n }\n}\n\n/**\n * Helper used by consumer plugins to resolve a metrics backend with\n * the canonical fallback chain. Never throws; always returns a usable\n * `MetricsRegistry`.\n *\n * @param ctx the consuming plugin's `PluginContext`\n * @param override explicit option set on the consuming plugin (wins)\n */\nexport function resolveMetrics(\n ctx: PluginContext,\n override?: MetricsRegistry,\n): MetricsRegistry {\n if (override) return override;\n try {\n const m = ctx.getService<MetricsRegistry | undefined>(OBSERVABILITY_METRICS_SERVICE);\n if (m) return m;\n } catch {\n // Service not registered — fall through to the noop default.\n }\n return new NoopMetricsRegistry();\n}\n\n/**\n * Sibling of {@link resolveMetrics} for {@link ErrorReporter}.\n */\nexport function resolveErrorReporter(\n ctx: PluginContext,\n override?: ErrorReporter,\n): ErrorReporter {\n if (override) return override;\n try {\n const e = ctx.getService<ErrorReporter | undefined>(OBSERVABILITY_ERRORS_SERVICE);\n if (e) return e;\n } catch {\n // Service not registered — fall through to the noop default.\n }\n return new NoopErrorReporter();\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { Plugin, PluginContext, IHttpServer } from '@objectstack/core';\nimport { HttpDispatcher, HttpDispatcherResult } from './http-dispatcher.js';\nimport {\n buildSecurityHeaders,\n type SecurityHeadersOptions,\n} from './security/index.js';\nimport {\n NoopMetricsRegistry,\n NoopErrorReporter,\n instrumentRouteHandler,\n type MetricsRegistry,\n type ErrorReporter,\n} from './observability/index.js';\n\nexport interface DispatcherPluginConfig {\n /**\n * API path prefix for all endpoints.\n * @default '/api/v1'\n */\n prefix?: string;\n\n /**\n * Project-scoping configuration. Must match the REST API\n * `enableProjectScoping` / `projectResolution` fields so AI / automation\n * routes stay in lockstep with /data and /meta.\n *\n * When `enableProjectScoping` is true and `projectResolution` is:\n * - `required` — only `/environments/:environmentId/...` variants are registered.\n * - `optional` / `auto` — both unscoped and scoped variants are registered\n * (the scoped handler forwards `req.params.environmentId` into context).\n */\n scoping?: {\n enableProjectScoping?: boolean;\n projectResolution?: 'required' | 'optional' | 'auto';\n };\n\n /**\n * Enforce per-project membership (`sys_environment_member`) on scoped\n * data-plane routes. Returns 403 for non-members unless they are\n * staff (platform org) or the project is the well-known system\n * project.\n *\n * Defaults to `true` when `scoping.enableProjectScoping` is enabled;\n * explicitly set to `false` for tests and single-tenant deployments\n * where membership has not been seeded.\n */\n enforceProjectMembership?: boolean;\n\n /**\n * Security response headers. When provided, every response routed\n * through this plugin gets the headers merged in (route-specific\n * headers still win on conflict).\n *\n * Pass `false` to disable. Pass `true` (or omit) to enable with\n * conservative API-server defaults (CSP=deny-all, XCTO=nosniff,\n * X-Frame-Options=DENY, etc.). Pass an object to customize — see\n * {@link SecurityHeadersOptions}.\n *\n * @default true\n */\n securityHeaders?: boolean | SecurityHeadersOptions;\n\n /**\n * Observability wiring. All fields optional; defaults are noop\n * (zero overhead, no behavior change).\n *\n * - `metrics`: registry receiving `http_requests_total`,\n * `http_request_duration_ms`, `http_request_errors_total` for\n * every route this plugin mounts. Plug in `prom-client` /\n * `@opentelemetry/api-metrics` / your own adapter.\n *\n * - `errorReporter`: invoked on 5xx responses with the thrown\n * error and `{ requestId, method, route }`. Plug in Sentry /\n * Datadog / Rollbar.\n *\n * - `generateRequestId`: customize the format of minted request\n * ids (default: `req_<uuid>` via `crypto.randomUUID`). The\n * incoming `X-Request-Id` header is honored when present and\n * well-formed, regardless of this setting.\n *\n * - `requestIdHeader`: response header name to echo the id back\n * on. Defaults to `X-Request-Id`.\n */\n observability?: {\n metrics?: MetricsRegistry;\n errorReporter?: ErrorReporter;\n generateRequestId?: () => string;\n requestIdHeader?: string;\n };\n}\n\n/**\n * Route definition emitted by service plugins (e.g. AIServicePlugin) via hooks.\n * Minimal interface — matches the shape produced by `buildAIRoutes()`.\n */\ninterface RouteDefinition {\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE';\n path: string;\n description: string;\n handler: (req: any) => Promise<any>;\n}\n\n/**\n * Register a single RouteDefinition on the HTTP server.\n * Returns true if the route was successfully registered.\n */\nfunction mountRouteOnServer(\n route: RouteDefinition,\n server: IHttpServer,\n routePath: string,\n securityHeaders?: Record<string, string>,\n resolveUser?: (headers: Record<string, any>) => Promise<any | undefined>,\n): boolean {\n const handler = async (req: any, res: any) => {\n try {\n // Resolve the authenticated user from request headers (cookie /\n // bearer) so route handlers can attribute the request to an\n // actor — wires up `req.user` for AI routes, action endpoints,\n // anything that needs identity-aware execution.\n let user: any;\n if (resolveUser) {\n try {\n user = await resolveUser(req.headers ?? {});\n } catch {\n /* fall through anonymous — route's `auth: true` guard runs separately */\n }\n }\n\n const result = await route.handler({\n body: req.body,\n params: req.params,\n query: req.query,\n headers: req.headers,\n user,\n });\n\n if (result.stream && result.events) {\n // SSE streaming response\n res.status(result.status);\n\n if (securityHeaders) {\n for (const [k, v] of Object.entries(securityHeaders)) {\n res.header(k, v);\n }\n }\n\n // Apply headers from the route result if available\n if (result.headers) {\n for (const [k, v] of Object.entries(result.headers)) {\n res.header(k, String(v));\n }\n } else {\n res.header('Content-Type', 'text/event-stream');\n res.header('Cache-Control', 'no-cache');\n res.header('Connection', 'keep-alive');\n }\n\n // Write the stream — events are pre-encoded SSE strings\n if (typeof res.write === 'function' && typeof res.end === 'function') {\n for await (const event of result.events) {\n res.write(typeof event === 'string' ? event : `data: ${JSON.stringify(event)}\\n\\n`);\n }\n res.end();\n } else {\n // Fallback: collect events into array\n const events = [];\n for await (const event of result.events) {\n events.push(event);\n }\n res.json({ events });\n }\n } else {\n res.status(result.status);\n if (securityHeaders) {\n for (const [k, v] of Object.entries(securityHeaders)) {\n res.header(k, v);\n }\n }\n if (result.body !== undefined) {\n res.json(result.body);\n } else {\n res.end();\n }\n }\n } catch (err: any) {\n errorResponseBase(err, res, securityHeaders);\n }\n };\n\n const m = route.method.toLowerCase();\n if (m === 'get' && typeof server.get === 'function') {\n server.get(routePath, handler);\n return true;\n } else if (m === 'post' && typeof server.post === 'function') {\n server.post(routePath, handler);\n return true;\n } else if (m === 'delete' && typeof server.delete === 'function') {\n server.delete(routePath, handler);\n return true;\n } else if (m === 'patch' && typeof server.patch === 'function') {\n server.patch(routePath, handler);\n return true;\n }\n return false;\n}\n\n/**\n * Send an HttpDispatcherResult through IHttpResponse.\n * Differentiates between handled, unhandled (404), and special results.\n *\n * @param securityHeaders headers to merge into every response (under\n * the route-specific headers so the dispatcher can override on a\n * per-route basis when truly needed).\n */\nfunction sendResultBase(\n result: HttpDispatcherResult,\n res: any,\n securityHeaders?: Record<string, string>,\n): void {\n const applySecurityHeaders = () => {\n if (!securityHeaders) return;\n for (const [k, v] of Object.entries(securityHeaders)) {\n // Don't clobber route-set headers — `res.header` semantics\n // vary by adapter, so we set unconditionally and rely on the\n // call ordering (security headers first, route headers\n // overwrite below).\n res.header(k, v);\n }\n };\n\n if (result.handled) {\n if (result.response) {\n res.status(result.response.status);\n applySecurityHeaders();\n if (result.response.headers) {\n for (const [k, v] of Object.entries(result.response.headers)) {\n res.header(k, v);\n }\n }\n res.json(result.response.body);\n return;\n }\n if (result.result) {\n // Special results from the dispatcher's `result.result` channel.\n // Currently the only shape we handle here is the SSE/streaming\n // descriptor returned by AI routes:\n // { status, stream: true, events: AsyncIterable<string>,\n // headers?: Record<string, string>, contentType?: string }\n // Anything else falls through to JSON so older callers keep\n // working.\n const r = result.result as any;\n const isStream = r && typeof r === 'object' && (r.type === 'stream' || r.stream === true) && r.events;\n if (isStream && typeof res.write === 'function' && typeof res.end === 'function') {\n res.status(typeof r.status === 'number' ? r.status : 200);\n applySecurityHeaders();\n if (r.headers && typeof r.headers === 'object') {\n for (const [k, v] of Object.entries(r.headers)) {\n res.header(k, String(v));\n }\n } else {\n res.header('Content-Type', r.contentType || 'text/event-stream');\n res.header('Cache-Control', 'no-cache');\n res.header('Connection', 'keep-alive');\n }\n // Flip the adapter's `isStreaming` flag synchronously so the\n // outer handler can return before the AsyncIterable is fully\n // drained. Without this empty write, the Hono adapter would\n // see no streaming activity by the time the route handler\n // resolves and would close the body, truncating the SSE.\n res.write('');\n // Drain the events in the background; the adapter's\n // ReadableStream stays open until res.end() fires.\n (async () => {\n try {\n for await (const event of r.events as AsyncIterable<unknown>) {\n if (event == null) continue;\n res.write(typeof event === 'string' ? event : `data: ${JSON.stringify(event)}\\n\\n`);\n }\n } catch (streamErr) {\n try {\n res.write(`event: error\\ndata: ${JSON.stringify({ message: streamErr instanceof Error ? streamErr.message : String(streamErr) })}\\n\\n`);\n } catch { /* connection already gone */ }\n } finally {\n try { res.end(); } catch { /* idem */ }\n }\n })();\n return;\n }\n res.status(200);\n applySecurityHeaders();\n res.json(result.result);\n return;\n }\n }\n // Semantic 404: no route matched — include diagnostic info\n res.status(404);\n applySecurityHeaders();\n res.json({\n success: false,\n error: {\n message: 'Not Found',\n code: 404,\n type: 'ROUTE_NOT_FOUND',\n hint: 'No handler matched this request. Check the API discovery endpoint for available routes.',\n },\n });\n}\n\nfunction errorResponseBase(err: any, res: any, securityHeaders?: Record<string, string>): void {\n const code = err.statusCode || 500;\n res.status(code);\n if (securityHeaders) {\n for (const [k, v] of Object.entries(securityHeaders)) {\n res.header(k, v);\n }\n }\n // Side-channel: remember the original error so the observability\n // wrapper can hand it to errorReporter on 5xx. Handlers catch the\n // error and call us here instead of re-throwing, so this is the\n // only place we still have it.\n if (code >= 500) {\n try {\n (res as any).__obsRecordedError = err;\n } catch {\n // res is a frozen / proxy object — skip\n }\n }\n res.json({\n success: false,\n error: { message: err.message || 'Internal Server Error', code },\n });\n}\n\n/**\n * Dispatcher Plugin\n *\n * Bridges legacy HttpDispatcher handlers to the IHttpServer route-registration model.\n * Registers routes for domains NOT covered by @objectstack/rest:\n * - /.well-known/objectstack (discovery)\n * - /auth (authentication)\n * - /graphql (GraphQL)\n * - /analytics (BI queries)\n * - /packages (package management)\n * - /i18n (internationalization — locales, translations, field labels)\n * - /storage (file storage)\n * - /automation (CRUD + triggers + runs)\n *\n * Usage:\n * ```ts\n * import { createDispatcherPlugin } from '@objectstack/runtime';\n * runtime.use(createDispatcherPlugin({ prefix: '/api/v1' }));\n * ```\n */\nexport function createDispatcherPlugin(config: DispatcherPluginConfig = {}): Plugin {\n return {\n name: 'com.objectstack.runtime.dispatcher',\n version: '1.0.0',\n\n init: async (_ctx: PluginContext) => {\n // Consumer-only plugin — no services registered\n },\n\n start: async (ctx: PluginContext) => {\n let server: IHttpServer | undefined;\n try {\n server = ctx.getService<IHttpServer>('http.server');\n } catch {\n // No HTTP server available — skip silently\n return;\n }\n if (!server) return;\n\n const kernel = ctx.getKernel();\n // Default: enable membership enforcement iff environment-scoping is on.\n // Tests / single-tenant deploys can opt out via the explicit flag.\n const enforceMembership =\n config.enforceProjectMembership ?? (config.scoping?.enableProjectScoping ?? false);\n const dispatcher = new HttpDispatcher(kernel, undefined, {\n enforceProjectMembership: enforceMembership,\n });\n const prefix = config.prefix || '/api/v1';\n\n // ── Security: resolve once at startup; applied on every response.\n // Defaults to ON because every production API server should be\n // sending these headers. Opt out with `securityHeaders: false`\n // (only sensible for tests or when an upstream reverse proxy is\n // already setting them).\n const securityHeaders: Record<string, string> | undefined =\n config.securityHeaders === false\n ? undefined\n : buildSecurityHeaders(\n typeof config.securityHeaders === 'object'\n ? config.securityHeaders\n : {},\n );\n\n // Locally-shadowed wrappers — every `sendResult(...)` /\n // `errorResponse(...)` call below picks these up via lexical\n // scope, so the 50+ route handlers don't need to thread the\n // security headers through manually.\n const sendResult = (result: HttpDispatcherResult, res: any) =>\n sendResultBase(result, res, securityHeaders);\n const errorResponse = (err: any, res: any) =>\n errorResponseBase(err, res, securityHeaders);\n\n // ── Observability ──────────────────────────────────────────\n // Noop defaults; production hosts inject real adapters.\n const metrics: MetricsRegistry =\n config.observability?.metrics ?? new NoopMetricsRegistry();\n const errorReporter: ErrorReporter =\n config.observability?.errorReporter ?? new NoopErrorReporter();\n const generateRequestId = config.observability?.generateRequestId;\n const requestIdHeader =\n config.observability?.requestIdHeader ?? 'X-Request-Id';\n\n /**\n * Wrap the IHttpServer so every route registration is\n * automatically instrumented. We only override the three\n * verb methods the dispatcher uses; everything else passes\n * through unchanged.\n */\n const rawServer = server;\n server = new Proxy(rawServer, {\n get(target, prop, receiver) {\n if (prop === 'get' || prop === 'post' || prop === 'delete') {\n const method = String(prop).toUpperCase();\n const original = (target as any)[prop];\n if (typeof original !== 'function') return original;\n return (route: string, handler: any) => {\n return original.call(\n target,\n route,\n instrumentRouteHandler(method, route, handler, {\n metrics,\n errorReporter,\n generateRequestId,\n requestIdHeader,\n }),\n );\n };\n }\n return Reflect.get(target, prop, receiver);\n },\n }) as IHttpServer;\n\n // ── Discovery (.well-known) ─────────────────────────────────\n server.get('/.well-known/objectstack', async (_req: any, res: any) => {\n if (securityHeaders) {\n for (const [k, v] of Object.entries(securityHeaders)) {\n res.header(k, v);\n }\n }\n res.json({ data: await dispatcher.getDiscoveryInfo(prefix) });\n });\n\n // ── Discovery (versioned API path) ──────────────────────────\n server.get(`${prefix}/discovery`, async (_req: any, res: any) => {\n if (securityHeaders) {\n for (const [k, v] of Object.entries(securityHeaders)) {\n res.header(k, v);\n }\n }\n res.json({ data: await dispatcher.getDiscoveryInfo(prefix) });\n });\n\n // ── Health ──────────────────────────────────────────────────\n server.get(`${prefix}/health`, async (_req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', '/health', undefined, {}, { request: _req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ── Auth ────────────────────────────────────────────────────\n // NOTE: /auth/* wildcard is mounted by AuthProxyPlugin (cloud)\n // or AuthPlugin (single-tenant) directly on the raw Hono app —\n // those handlers can return native Web `Response` objects which\n // is what better-auth produces. The dispatcher cannot represent\n // a streaming Response cleanly through `IHttpServer.send`, so\n // we deliberately do NOT register a dispatcher wildcard here.\n //\n // Legacy explicit /auth/login retained for self-hosted clients\n // that still POST there; superseded by the wildcard above for\n // the better-auth surface (sign-up/email, sign-in/email, …).\n server.post(`${prefix}/auth/login`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handleAuth('login', 'POST', req.body, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ── GraphQL ─────────────────────────────────────────────────\n server.post(`${prefix}/graphql`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handleGraphQL(req.body, { request: req });\n if (securityHeaders) {\n for (const [k, v] of Object.entries(securityHeaders)) {\n res.header(k, v);\n }\n }\n res.json(result);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ── Analytics ───────────────────────────────────────────────\n // Route via dispatch() (not handleAnalytics directly) so the host\n // dispatcher's project-aware kernel swap runs first — the per-project\n // kernel owns the `analytics` service (registered by ObjectQLPlugin).\n server.post(`${prefix}/analytics/query`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', '/analytics/query', req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.get(`${prefix}/analytics/meta`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', '/analytics/meta', undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.post(`${prefix}/analytics/sql`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', '/analytics/sql', req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ── Packages ────────────────────────────────────────────────\n server.get(`${prefix}/packages`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages('', 'GET', {}, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.post(`${prefix}/packages`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages('', 'POST', req.body, {}, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.get(`${prefix}/packages/:id/export`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}/export`, 'GET', {}, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.get(`${prefix}/packages/:id`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}`, 'GET', {}, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.delete(`${prefix}/packages/:id`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}`, 'DELETE', {}, {}, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.patch(`${prefix}/packages/:id/enable`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}/enable`, 'PATCH', {}, {}, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.patch(`${prefix}/packages/:id/disable`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}/disable`, 'PATCH', {}, {}, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.post(`${prefix}/packages/:id/publish`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}/publish`, 'POST', req.body, {}, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ADR-0033 — publish every pending draft bound to a package (\"publish\n // whole app\"). Distinct from /publish (which needs the metadata\n // service): this promotes sys_metadata draft rows via the protocol.\n server.post(`${prefix}/packages/:id/publish-drafts`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}/publish-drafts`, 'POST', req.body, {}, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.post(`${prefix}/packages/:id/revert`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handlePackages(`/${req.params.id}/revert`, 'POST', req.body, {}, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ── Storage ─────────────────────────────────────────────────\n server.post(`${prefix}/storage/upload`, async (req: any, res: any) => {\n try {\n // For file uploads the body *is* the file (parsed by adapter)\n const result = await dispatcher.handleStorage('upload', 'POST', req.body, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.get(`${prefix}/storage/file/:id`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.handleStorage(`file/${req.params.id}`, 'GET', undefined, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ── i18n ────────────────────────────────────────────────────\n // Route via dispatch() (not handleI18n directly) so the host\n // dispatcher's project-aware kernel swap runs first. Without this,\n // i18n requests hit the host kernel's in-memory fallback (which\n // is always empty) instead of the per-project I18nServicePlugin\n // populated by ArtifactKernelFactory with the artifact's\n // translation bundles.\n server.get(`${prefix}/i18n/locales`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', '/i18n/locales', undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.get(`${prefix}/i18n/translations/:locale`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', `/i18n/translations/${req.params.locale}`, undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server.get(`${prefix}/i18n/labels/:object/:locale`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', `/i18n/labels/${req.params.object}/${req.params.locale}`, undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // ── Automation ──────────────────────────────────────────────\n // Registered at both `${prefix}/automation/...` and\n // `${prefix}/environments/:environmentId/automation/...` when project\n // scoping is enabled. Always dispatched through\n // `dispatcher.dispatch()` so the multi-kernel host can swap\n // to the per-project kernel before resolving the\n // `automation` service (which lives on the project kernel,\n // not the host kernel, in ObjectOS multi-tenant mode).\n const registerAutomationRoutes = (base: string) => {\n server!.get(`${base}/automation`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', '/automation', undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.post(`${base}/automation`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', '/automation', req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.get(`${base}/automation/:name`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', `/automation/${req.params.name}`, undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.put(`${base}/automation/:name`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('PUT', `/automation/${req.params.name}`, req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.delete(`${base}/automation/:name`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('DELETE', `/automation/${req.params.name}`, undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.post(`${base}/automation/trigger/:name`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', `/automation/trigger/${req.params.name}`, req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.post(`${base}/automation/:name/trigger`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', `/automation/${req.params.name}/trigger`, req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.post(`${base}/automation/:name/toggle`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', `/automation/${req.params.name}/toggle`, req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.get(`${base}/automation/:name/runs`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', `/automation/${req.params.name}/runs`, undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.get(`${base}/automation/:name/runs/:runId`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', `/automation/${req.params.name}/runs/${req.params.runId}`, undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n // Screen-flow runtime (ADR-0019): resume a paused run with a\n // screen node's collected input, and re-fetch its pending screen.\n server!.post(`${base}/automation/:name/runs/:runId/resume`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', `/automation/${req.params.name}/runs/${req.params.runId}/resume`, req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n\n server!.get(`${base}/automation/:name/runs/:runId/screen`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('GET', `/automation/${req.params.name}/runs/${req.params.runId}/screen`, undefined, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n };\n\n // ── AI / Assistants ─────────────────────────────────────────\n // The AI service plugin registers a large, dynamic surface\n // (chat, models, conversations, tools, agents, assistants)\n // whose exact routes are built at start() time from the\n // service's tool / agent registries. To support multi-tenant\n // hosts where the AI service lives on per-project kernels,\n // mount a method-wildcard catch-all that always dispatches\n // through `dispatcher.dispatch()` — that triggers the kernel\n // swap and then routes via `handleAI`, which looks up the\n // AI service on the current (project) kernel.\n const registerAIRoutes = (base: string) => {\n const wildcards: Array<['get'|'post'|'delete'|'put', string]> = [\n ['get', `${base}/ai/*`],\n ['post', `${base}/ai/*`],\n ['delete', `${base}/ai/*`],\n ['put', `${base}/ai/*`],\n ];\n for (const [method, pattern] of wildcards) {\n (server as any) => {\n try {\n // Reconstruct the AI subpath without the prefix\n // so dispatch() routes via the /ai branch.\n const fullPath: string = req.path ?? '';\n const idx = fullPath.lastIndexOf('/ai');\n const aiSubPath = idx >= 0 ? fullPath.slice(idx) : '/ai';\n const result = await dispatcher.dispatch(method.toUpperCase(), aiSubPath, req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n }\n };\n\n // ── Actions (server-registered handlers, e.g. CRM convertLead) ───\n // Bridges UI `script` / `modal` actions to ObjectQL handlers\n // registered via `engine.registerAction(object, action, fn)`.\n const registerActionRoutes = (base: string) => {\n server!.post(`${base}/actions/:object/:action`, async (req: any, res: any) => {\n try {\n const ctx: any = { request: req };\n if (req.params?.environmentId) ctx.environmentId = req.params.environmentId;\n const result = await dispatcher.handleActions(`/${req.params.object}/${req.params.action}`, 'POST', req.body, ctx);\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n server!.post(`${base}/actions/:object/:action/:recordId`, async (req: any, res: any) => {\n try {\n const ctx: any = { request: req };\n if (req.params?.environmentId) ctx.environmentId = req.params.environmentId;\n const result = await dispatcher.handleActions(`/${req.params.object}/${req.params.action}/${req.params.recordId}`, 'POST', req.body, ctx);\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n };\n\n const enableProjectScoping = config.scoping?.enableProjectScoping ?? false;\n const projectResolution = config.scoping?.projectResolution ?? 'auto';\n\n if (enableProjectScoping && projectResolution === 'required') {\n registerAutomationRoutes(`${prefix}/environments/:environmentId`);\n registerActionRoutes(`${prefix}/environments/:environmentId`);\n registerAIRoutes(`${prefix}/environments/:environmentId`);\n } else {\n registerAutomationRoutes(prefix);\n registerActionRoutes(prefix);\n registerAIRoutes(prefix);\n if (enableProjectScoping) {\n registerAutomationRoutes(`${prefix}/environments/:environmentId`);\n registerActionRoutes(`${prefix}/environments/:environmentId`);\n registerAIRoutes(`${prefix}/environments/:environmentId`);\n }\n }\n\n ctx.logger.info('Dispatcher bridge routes registered', { prefix, enableProjectScoping, projectResolution });\n\n // Resolve the authenticated user from a request's headers by\n // delegating to the AuthService's `getSession` API (better-auth\n // compatible). Returns a slim user shape that route handlers\n // can rely on without touching the underlying auth provider.\n //\n // Defensive: any failure → undefined (anonymous). The route's\n // `auth: true` guard still runs separately so unauthenticated\n // hits to protected routes are rejected upstream.\n const resolveRequestUser = async (headers: Record<string, any>): Promise<any | undefined> => {\n try {\n const authService: any = ctx.getService('auth');\n if (!authService) return undefined;\n let api: any = authService.api;\n if (!api && typeof authService.getApi === 'function') {\n api = await authService.getApi();\n }\n if (!api?.getSession) return undefined;\n const headersInstance = headers instanceof Headers\n ? headers\n : new Headers(headers as Record<string, string>);\n const sessionData = await api.getSession({ headers: headersInstance });\n const userId: string | undefined = sessionData?.user?.id ?? sessionData?.session?.userId;\n if (!userId) return undefined;\n return {\n userId,\n id: userId,\n displayName: sessionData?.user?.name ?? sessionData?.user?.email ?? userId,\n email: sessionData?.user?.email,\n roles: [],\n permissions: [],\n organizationId: sessionData?.session?.activeOrganizationId,\n };\n } catch {\n return undefined;\n }\n };\n\n // ── Dynamic service routes (AI, etc.) ───────────────────\n // Listen for route definitions emitted by service plugins.\n // The AIServicePlugin emits 'ai:routes' with RouteDefinition[].\n //\n // When environment-scoping is enabled, each AI route is mounted on\n // BOTH `${prefix}${path}` and `${prefix}/environments/:environmentId${path}`\n // (or only the scoped variant when `projectResolution === 'required'`).\n const toScopedPath = (routePath: string): string => {\n // routePath may already include /api/v1; splice /environments/:environmentId\n // after the `${prefix}` portion to produce the scoped variant.\n if (routePath.startsWith(prefix)) {\n const tail = routePath.slice(prefix.length);\n return `${prefix}/environments/:environmentId${tail}`;\n }\n return `/environments/:environmentId${routePath}`;\n };\n\n const mountAiRoute = (route: RouteDefinition) => {\n if (!server) return 0;\n const routePath = route.path.startsWith('/api/v1')\n ? route.path\n : `${prefix}${route.path}`;\n\n let count = 0;\n if (enableProjectScoping && projectResolution === 'required') {\n if (mountRouteOnServer(route, server, toScopedPath(routePath), securityHeaders, resolveRequestUser)) count++;\n } else {\n if (mountRouteOnServer(route, server, routePath, securityHeaders, resolveRequestUser)) count++;\n if (enableProjectScoping) {\n if (mountRouteOnServer(route, server, toScopedPath(routePath), securityHeaders, resolveRequestUser)) count++;\n }\n }\n return count;\n };\n\n ctx.hook('ai:routes', async (routes: RouteDefinition[]) => {\n if (!server) return;\n let total = 0;\n for (const route of routes) {\n total += mountAiRoute(route);\n }\n ctx.logger.info(`[Dispatcher] Registered ${total} AI route mount(s) from ${routes.length} definition(s)`);\n });\n\n // ── Fallback: recover routes cached before hook was registered ──\n // If AIServicePlugin.start() ran before DispatcherPlugin.start()\n // (possible when plugin start order differs from registration order),\n // the 'ai:routes' trigger fires with no listener. The AIServicePlugin\n // caches the routes on the kernel as __aiRoutes (see AIServicePlugin.start())\n // as an internal cross-plugin protocol so we can recover them here.\n // TODO: replace with a formal kernel.getCachedRoutes('ai') API in a future release.\n const cachedRoutes = (kernel as any).__aiRoutes as RouteDefinition[] | undefined;\n if (cachedRoutes && Array.isArray(cachedRoutes) && cachedRoutes.length > 0) {\n let registered = 0;\n for (const route of cachedRoutes) {\n registered += mountAiRoute(route);\n }\n if (registered > 0) {\n ctx.logger.info(`[Dispatcher] Recovered ${registered} cached AI route mount(s) (hook timing fallback)`);\n }\n }\n },\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { Plugin, PluginContext } from '@objectstack/core';\n\n/**\n * The well-known UUID for the built-in system project.\n * Kept in lockstep with `ProjectProvisioningService.provisionSystemEnvironment`.\n */\nexport const SYSTEM_ENVIRONMENT_ID = '00000000-0000-0000-0000-000000000001';\n\n/**\n * Minimal surface of `ProjectProvisioningService` consumed by the plugin.\n * Typed locally so the runtime package does not gain a hard dependency on\n * `@objectstack/service-tenant` — the service is discovered at runtime via\n * the kernel service registry.\n */\ninterface ProvisioningLike {\n provisionSystemEnvironment(): Promise<{\n project: { id: string; isSystem?: boolean };\n warnings?: string[];\n }>;\n}\n\nexport interface SystemEnvironmentPluginConfig {\n /**\n * Service name that resolves to a `ProjectProvisioningService`-shaped\n * object. Defaults to `tenant.provisioning` (convention used by\n * `@objectstack/service-tenant`).\n */\n serviceName?: string;\n\n /**\n * When true, plugin treats a missing provisioning service as an error.\n * Defaults to false — bootstrap is opt-in and must no-op gracefully when\n * the tenant package is not part of the stack.\n */\n strict?: boolean;\n}\n\n/**\n * System Project Bootstrap Plugin\n *\n * Ensures the built-in system project (well-known UUID\n * {@link SYSTEM_ENVIRONMENT_ID}) exists on the control plane the first time the\n * runtime starts. Calls are idempotent — `provisionSystemEnvironment()` returns\n * the existing row when the project has already been created.\n *\n * Register AFTER the tenant service is available so the provisioning service\n * can be resolved from the kernel.\n *\n * @example\n * ```ts\n * kernel.use(tenantPlugin);\n * kernel.use(createSystemEnvironmentPlugin());\n * ```\n */\nexport function createSystemEnvironmentPlugin(config: SystemEnvironmentPluginConfig = {}): Plugin {\n const serviceName = config.serviceName ?? 'tenant.provisioning';\n\n return {\n name: 'com.objectstack.runtime.system-environment',\n version: '1.0.0',\n\n init: async (_ctx: PluginContext) => {\n // Consumer-only plugin; nothing to register at init-time.\n },\n\n start: async (ctx: PluginContext) => {\n let service: ProvisioningLike | undefined;\n try {\n service = ctx.getService<ProvisioningLike>(serviceName);\n } catch {\n // Service registry throws when the key is not found.\n service = undefined;\n }\n\n if (!service || typeof service.provisionSystemEnvironment !== 'function') {\n if (config.strict) {\n throw new Error(\n `[SystemEnvironmentPlugin] Provisioning service '${serviceName}' not found — cannot bootstrap system project.`,\n );\n }\n ctx.logger.debug(\n `[SystemEnvironmentPlugin] Provisioning service '${serviceName}' unavailable — system project bootstrap skipped.`,\n );\n return;\n }\n\n try {\n const result = await service.provisionSystemEnvironment();\n const warnings = result.warnings ?? [];\n ctx.logger.info('[SystemEnvironmentPlugin] System project ready', {\n environmentId: result.project.id,\n isSystem: result.project.isSystem,\n warnings,\n });\n } catch (err: any) {\n if (config.strict) throw err;\n ctx.logger.warn('[SystemEnvironmentPlugin] Failed to provision system project', {\n error: err?.message ?? String(err),\n });\n }\n },\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { IHttpServer, RouteHandler, Middleware } from '@objectstack/core';\n\n/**\n * HttpServer - Unified HTTP Server Abstraction\n * \n * Provides a framework-agnostic HTTP server interface that wraps\n * underlying server implementations (Hono, Express, Fastify, etc.)\n * \n * This class serves as an adapter between the IHttpServer interface\n * and concrete server implementations, allowing plugins to register\n * routes and middleware without depending on specific frameworks.\n * \n * Features:\n * - Unified route registration API\n * - Middleware management with ordering\n * - Request/response lifecycle hooks\n * - Framework-agnostic abstractions\n */\nexport class HttpServer implements IHttpServer {\n protected server: IHttpServer;\n protected routes: Map<string, RouteHandler>;\n protected middlewares: Middleware[];\n \n /**\n * Create an HTTP server wrapper\n * @param server - The underlying server implementation (Hono, Express, etc.)\n */\n constructor(server: IHttpServer) {\n this.server = server;\n this.routes = new Map();\n this.middlewares = [];\n }\n \n /**\n * Register a GET route handler\n * @param path - Route path (e.g., '/api/users/:id')\n * @param handler - Route handler function\n */\n get(path: string, handler: RouteHandler): void {\n const key = `GET:${path}`;\n this.routes.set(key, handler);\n this.server.get(path, handler);\n }\n \n /**\n * Register a POST route handler\n * @param path - Route path\n * @param handler - Route handler function\n */\n post(path: string, handler: RouteHandler): void {\n const key = `POST:${path}`;\n this.routes.set(key, handler);\n this.server.post(path, handler);\n }\n \n /**\n * Register a PUT route handler\n * @param path - Route path\n * @param handler - Route handler function\n */\n put(path: string, handler: RouteHandler): void {\n const key = `PUT:${path}`;\n this.routes.set(key, handler);\n this.server.put(path, handler);\n }\n \n /**\n * Register a DELETE route handler\n * @param path - Route path\n * @param handler - Route handler function\n */\n delete(path: string, handler: RouteHandler): void {\n const key = `DELETE:${path}`;\n this.routes.set(key, handler);\n this.server.delete(path, handler);\n }\n \n /**\n * Register a PATCH route handler\n * @param path - Route path\n * @param handler - Route handler function\n */\n patch(path: string, handler: RouteHandler): void {\n const key = `PATCH:${path}`;\n this.routes.set(key, handler);\n this.server.patch(path, handler);\n }\n \n /**\n * Register middleware\n * @param path - Optional path to apply middleware to (if omitted, applies globally)\n * @param handler - Middleware function\n */\n use(path: string | Middleware, handler?: Middleware): void {\n if (typeof path === 'function') {\n // Global middleware\n this.middlewares.push(path);\n this.server.use(path);\n } else if (handler) {\n // Path-specific middleware\n this.middlewares.push(handler);\n this.server.use(path, handler);\n }\n }\n \n /**\n * Start the HTTP server\n * @param port - Port number to listen on\n * @returns Promise that resolves when server is ready\n */\n async listen(port: number): Promise<void> {\n await this.server.listen(port);\n }\n \n /**\n * Stop the HTTP server\n * @returns Promise that resolves when server is stopped\n */\n async close(): Promise<void> {\n if (this.server.close) {\n await this.server.close();\n }\n }\n \n /**\n * Get registered routes\n * @returns Map of route keys to handlers\n */\n getRoutes(): Map<string, RouteHandler> {\n return new Map(this.routes);\n }\n \n /**\n * Get registered middlewares\n * @returns Array of middleware functions\n */\n getMiddlewares(): Middleware[] {\n return [...this.middlewares];\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { Middleware, IHttpRequest, IHttpResponse } from '@objectstack/core';\nimport { MiddlewareConfig, MiddlewareType } from '@objectstack/spec/system';\n\n/**\n * Middleware Entry\n * Internal representation of registered middleware\n */\ninterface MiddlewareEntry {\n name: string;\n type: MiddlewareType;\n middleware: Middleware;\n order: number;\n enabled: boolean;\n paths?: {\n include?: string[];\n exclude?: string[];\n };\n}\n\n/**\n * MiddlewareManager\n * \n * Manages middleware registration, ordering, and execution.\n * Provides fine-grained control over middleware chains with:\n * - Execution order management\n * - Path-based filtering\n * - Enable/disable individual middleware\n * - Middleware categorization by type\n * \n * @example\n * const manager = new MiddlewareManager();\n * \n * // Register middleware with configuration\n * manager.register({\n * name: 'auth',\n * type: 'authentication',\n * order: 10,\n * paths: { exclude: ['/health', '/metrics'] }\n * }, authMiddleware);\n * \n * // Get sorted middleware chain\n * const chain = manager.getMiddlewareChain();\n * chain.forEach(mw => server.use(mw));\n */\nexport class MiddlewareManager {\n private middlewares: Map<string, MiddlewareEntry>;\n \n constructor() {\n this.middlewares = new Map();\n }\n \n /**\n * Register middleware with configuration\n * @param config - Middleware configuration\n * @param middleware - Middleware function\n */\n register(config: MiddlewareConfig, middleware: Middleware): void {\n const entry: MiddlewareEntry = {\n name: config.name,\n type: config.type,\n middleware,\n order: config.order ?? 100,\n enabled: config.enabled ?? true,\n paths: config.paths,\n };\n \n this.middlewares.set(config.name, entry);\n }\n \n /**\n * Unregister middleware by name\n * @param name - Middleware name\n */\n unregister(name: string): void {\n this.middlewares.delete(name);\n }\n \n /**\n * Enable middleware by name\n * @param name - Middleware name\n */\n enable(name: string): void {\n const entry = this.middlewares.get(name);\n if (entry) {\n entry.enabled = true;\n }\n }\n \n /**\n * Disable middleware by name\n * @param name - Middleware name\n */\n disable(name: string): void {\n const entry = this.middlewares.get(name);\n if (entry) {\n entry.enabled = false;\n }\n }\n \n /**\n * Get middleware entry by name\n * @param name - Middleware name\n */\n get(name: string): MiddlewareEntry | undefined {\n return this.middlewares.get(name);\n }\n \n /**\n * Get all middleware entries\n */\n getAll(): MiddlewareEntry[] {\n return Array.from(this.middlewares.values());\n }\n \n /**\n * Get middleware by type\n * @param type - Middleware type\n */\n getByType(type: MiddlewareType): MiddlewareEntry[] {\n return this.getAll().filter(entry => entry.type === type);\n }\n \n /**\n * Get middleware chain sorted by order\n * Returns only enabled middleware\n */\n getMiddlewareChain(): Middleware[] {\n return this.getAll()\n .filter(entry => entry.enabled)\n .sort((a, b) => a.order - b.order)\n .map(entry => entry.middleware);\n }\n \n /**\n * Get middleware chain with path filtering\n * @param path - Request path to match against\n */\n getMiddlewareChainForPath(path: string): Middleware[] {\n return this.getAll()\n .filter(entry => {\n if (!entry.enabled) return false;\n \n // Check path filters\n if (entry.paths) {\n // Check exclude patterns\n if (entry.paths.exclude) {\n const excluded = entry.paths.exclude.some(pattern => \n this.matchPath(path, pattern)\n );\n if (excluded) return false;\n }\n \n // Check include patterns (if specified)\n if (entry.paths.include) {\n const included = entry.paths.include.some(pattern => \n this.matchPath(path, pattern)\n );\n if (!included) return false;\n }\n }\n \n return true;\n })\n .sort((a, b) => a.order - b.order)\n .map(entry => entry.middleware);\n }\n \n /**\n * Match path against pattern (simple glob matching)\n * @param path - Request path\n * @param pattern - Pattern to match (supports * wildcard)\n */\n private matchPath(path: string, pattern: string): boolean {\n // Convert glob pattern to regex\n const regexPattern = pattern\n .replace(/\\*/g, '.*')\n .replace(/\\?/g, '.');\n \n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(path);\n }\n \n /**\n * Clear all middleware\n */\n clear(): void {\n this.middlewares.clear();\n }\n \n /**\n * Get middleware count\n */\n count(): number {\n return this.middlewares.size;\n }\n \n /**\n * Create a composite middleware from the chain\n * This can be used to apply all middleware at once\n */\n createCompositeMiddleware(): Middleware {\n const chain = this.getMiddlewareChain();\n \n return async (req: IHttpRequest, res: IHttpResponse, next: () => void | Promise<void>) => {\n let index = 0;\n \n const executeNext = async (): Promise<void> => {\n if (index >= chain.length) {\n await next();\n return;\n }\n \n const middleware = chain[index++];\n await middleware(req, res, executeNext);\n };\n \n await executeNext();\n };\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectKernel } from '@objectstack/core';\n\n/**\n * Factory contract for instantiating a per-project {@link ObjectKernel}.\n *\n * Given a `environmentId`, the factory is expected to:\n * 1. Read control-plane metadata (`sys_environment` + credentials + subscribed packages).\n * 2. Construct a fresh `ObjectKernel` with project-scoped driver + plugins + Apps.\n * 3. Return a **bootstrapped** kernel ready to serve requests.\n */\nexport interface EnvironmentKernelFactory {\n create(environmentId: string): Promise<ObjectKernel>;\n}\n\ninterface CachedEntry {\n kernel: ObjectKernel;\n createdAt: number;\n lastAccess: number;\n /**\n * Wall-clock ms of the most recent freshness probe (see\n * `freshnessProbe`). Throttles upstream probe rate to at most\n * `staleCheckIntervalMs` per env.\n */\n lastStaleCheckAt: number;\n}\n\nexport interface KernelManagerConfig {\n factory: EnvironmentKernelFactory;\n /** Maximum number of kernels to keep resident. Defaults to 32. */\n maxSize?: number;\n /**\n * Time-to-live (ms). Kernels idle longer than this are evicted on next\n * access. `0` disables TTL expiry. Defaults to 15 minutes.\n */\n ttlMs?: number;\n /**\n * Optional logger (duck-typed). Falls back to `console` when omitted.\n */\n logger?: { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n /**\n * Optional upstream-change detector. When set, every cache hit older\n * than `staleCheckIntervalMs` triggers this probe before returning the\n * cached kernel. Returning `true` evicts the kernel and forces a\n * rebuild, so changes to the control-plane state that don't reach\n * this process via push (marketplace installs, artifact republish,\n * etc.) become visible without waiting for the LRU TTL to expire.\n *\n * The probe should be cheap (single small GET). Errors thrown here\n * are caught and treated as \"still fresh\" so a brief upstream\n * outage doesn't churn every cached kernel — the worst case is\n * stale-by-`ttlMs`, which is what we had before adding the probe.\n *\n * `builtAtMs` is the kernel's `createdAt` time so the probe can\n * compare against an upstream \"last changed at\" timestamp.\n */\n freshnessProbe?: (environmentId: string, builtAtMs: number) => Promise<boolean>;\n /**\n * Minimum gap between successive freshness probes for the same env.\n * Defaults to 10 seconds — enough to avoid hammering the control\n * plane on tight render loops while still keeping the user's\n * post-install refresh perceived as immediate.\n */\n staleCheckIntervalMs?: number;\n}\n\n/**\n * LRU + TTL cache of per-project {@link ObjectKernel} instances.\n *\n * Implements ADR-0003 multi-kernel scheduling: each project gets an\n * isolated kernel (App/plugin/metadata namespaces) that is lazily built\n * on first request and evicted under memory / idle pressure. Concurrent\n * `getOrCreate()` calls for the same environmentId share a single in-flight\n * factory invocation (singleflight).\n */\nexport class KernelManager {\n private readonly factory: EnvironmentKernelFactory;\n private readonly maxSize: number;\n private readonly ttlMs: number;\n private readonly logger: NonNullable<KernelManagerConfig['logger']>;\n private readonly cache = new Map<string, CachedEntry>();\n private readonly pending = new Map<string, Promise<ObjectKernel>>();\n private readonly freshnessProbe?: KernelManagerConfig['freshnessProbe'];\n private readonly staleCheckIntervalMs: number;\n\n constructor(config: KernelManagerConfig) {\n this.factory = config.factory;\n this.maxSize = config.maxSize ?? 32;\n this.ttlMs = config.ttlMs ?? 15 * 60 * 1000;\n this.logger = config.logger ?? console;\n this.freshnessProbe = config.freshnessProbe;\n this.staleCheckIntervalMs = config.staleCheckIntervalMs ?? 10_000;\n }\n\n /** Returns the currently cached environmentIds (ordered by insertion). */\n keys(): string[] {\n return Array.from(this.cache.keys());\n }\n\n /** Cache size for diagnostics. */\n get size(): number {\n return this.cache.size;\n }\n\n /**\n * Resolve or construct the kernel for `environmentId`.\n *\n * - Cache hit (fresh): bumps `lastAccess` and returns immediately.\n * - Cache hit (TTL expired): evicts then falls through to factory.\n * - Cache miss: dedupes concurrent callers through `pending`.\n */\n async getOrCreate(environmentId: string): Promise<ObjectKernel> {\n const existing = this.cache.get(environmentId);\n if (existing) {\n if (this.ttlMs > 0 && Date.now() - existing.lastAccess > this.ttlMs) {\n await this.evict(environmentId);\n } else {\n // Throttled upstream freshness check. Probe errors are swallowed\n // so a brief control-plane outage doesn't churn the cache; the\n // worst case is stale-by-ttlMs, our prior behaviour.\n if (this.freshnessProbe) {\n const now = Date.now();\n if (now - existing.lastStaleCheckAt >= this.staleCheckIntervalMs) {\n existing.lastStaleCheckAt = now;\n let stale = false;\n try {\n stale = await this.freshnessProbe(environmentId, existing.createdAt);\n } catch (err) {\n this.logger.warn?.('[KernelManager] freshness probe failed', { environmentId, err });\n }\n if (stale) {\n this.logger.info?.('[KernelManager] kernel evicted by freshness probe', { environmentId });\n await this.evict(environmentId);\n // fall through to rebuild\n } else {\n existing.lastAccess = Date.now();\n return existing.kernel;\n }\n } else {\n existing.lastAccess = Date.now();\n return existing.kernel;\n }\n } else {\n existing.lastAccess = Date.now();\n return existing.kernel;\n }\n }\n }\n\n const inflight = this.pending.get(environmentId);\n if (inflight) return inflight;\n\n const promise = (async () => {\n const kernel = await this.factory.create(environmentId);\n const now = Date.now();\n this.cache.set(environmentId, { kernel, createdAt: now, lastAccess: now, lastStaleCheckAt: now });\n await this.enforceMaxSize();\n return kernel;\n })();\n\n this.pending.set(environmentId, promise);\n try {\n return await promise;\n } finally {\n this.pending.delete(environmentId);\n }\n }\n\n /**\n * Evict the kernel for `environmentId` and invoke `kernel.shutdown()`.\n * No-op when the entry is absent.\n */\n async evict(environmentId: string): Promise<void> {\n const entry = this.cache.get(environmentId);\n if (!entry) return;\n this.cache.delete(environmentId);\n try {\n await entry.kernel.shutdown();\n } catch (err) {\n this.logger.error?.('[KernelManager] shutdown failed', { environmentId, err });\n }\n }\n\n /** Evict all resident kernels. Used on runtime shutdown. */\n async evictAll(): Promise<void> {\n const ids = Array.from(this.cache.keys());\n await Promise.all(ids.map((id) => this.evict(id)));\n }\n\n private async enforceMaxSize(): Promise<void> {\n while (this.cache.size > this.maxSize) {\n // Find least-recently-accessed entry.\n let oldestKey: string | undefined;\n let oldestAccess = Infinity;\n for (const [key, entry] of this.cache) {\n if (entry.lastAccess < oldestAccess) {\n oldestAccess = entry.lastAccess;\n oldestKey = key;\n }\n }\n if (!oldestKey) return;\n await this.evict(oldestKey);\n }\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Artifact API client.\n *\n * HTTP client that talks to the ObjectStack control plane (e.g.\n * `apps/cloud`) to resolve hostnames to projects and to download a\n * project's compiled artifact.\n *\n * The control plane is expected to expose two endpoints:\n *\n * GET {controlPlaneUrl}/api/v1/cloud/resolve-hostname?host={hostname}\n * → { environmentId: string, organizationId?: string, runtime?: EnvironmentRuntimeConfig }\n *\n * GET {controlPlaneUrl}/api/v1/cloud/environments/:environmentId/artifact\n * → EnvironmentArtifactResponse (EnvironmentArtifact + optional `runtime` block)\n *\n * Both endpoints accept an optional `Authorization: Bearer <apiKey>`.\n *\n * Responses are cached in-memory with a TTL so each kernel-manager\n * miss does not produce an extra HTTP round trip. Concurrent callers\n * for the same key share a single in-flight promise (singleflight).\n */\n\nimport type { EnvironmentArtifact } from '@objectstack/spec/cloud';\n\n/**\n * Per-project runtime config injected by the control plane alongside\n * the artifact. Carries the physical database URL the runtime should\n * connect to (this is *not* part of the developer-authored compiled\n * artifact — the control plane mints it when serving the API).\n */\nexport interface EnvironmentRuntimeConfig {\n organizationId?: string;\n hostname?: string;\n /** Driver type — e.g. `sqlite`, `postgres`, `turso`, `memory`. */\n databaseDriver: string;\n /** Driver-specific connection URL. */\n databaseUrl: string;\n /** Optional auth token (e.g. for libSQL/Turso). */\n databaseAuthToken?: string;\n /**\n * Project-level metadata captured by the control plane at create time\n * (e.g. `ownerSeed`, `orgSeed`). Forwarded to the runtime so cold-boot\n * seed replay can mirror the cloud org + owner into the project DB\n * before the user's first SSO callback arrives.\n */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Hostname resolution response.\n */\nexport interface ResolvedHostname {\n environmentId: string;\n organizationId?: string;\n /** Optional runtime config — when present, callers can skip the artifact fetch's runtime block. */\n runtime?: EnvironmentRuntimeConfig;\n}\n\n/**\n * Artifact response wrapping the spec's `EnvironmentArtifact` envelope plus\n * an optional `runtime` block carrying the project's database\n * connection details.\n */\nexport interface EnvironmentArtifactResponse extends EnvironmentArtifact {\n runtime?: EnvironmentRuntimeConfig;\n}\n\nexport interface ArtifactApiClientConfig {\n /** Control-plane base URL (no trailing slash). */\n controlPlaneUrl: string;\n /** Optional bearer token. */\n apiKey?: string;\n /** Cache TTL in ms. Default: 5 min. */\n cacheTtlMs?: number;\n /** Timeout for control-plane HTTP calls in ms. Default: 10s. */\n requestTimeoutMs?: number;\n /** Optional fetch override (testing). */\n fetch?: typeof fetch;\n /** Optional logger. */\n logger?: { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n}\n\ninterface CacheEntry<T> {\n value: T;\n expiresAt: number;\n}\n\nexport class ArtifactApiClient {\n private readonly base: string;\n private readonly apiKey?: string;\n private readonly cacheTtlMs: number;\n private readonly requestTimeoutMs: number;\n private readonly fetchImpl: typeof fetch;\n private readonly logger: NonNullable<ArtifactApiClientConfig['logger']>;\n\n private readonly hostnameCache = new Map<string, CacheEntry<ResolvedHostname>>();\n private readonly artifactCache = new Map<string, CacheEntry<EnvironmentArtifactResponse>>();\n private readonly pendingHostname = new Map<string, Promise<ResolvedHostname | null>>();\n private readonly pendingArtifact = new Map<string, Promise<EnvironmentArtifactResponse | null>>();\n\n constructor(config: ArtifactApiClientConfig) {\n if (!config.controlPlaneUrl) {\n throw new Error('[ArtifactApiClient] controlPlaneUrl is required');\n }\n this.base = config.controlPlaneUrl.replace(/\\/+$/, '');\n this.apiKey = config.apiKey;\n this.cacheTtlMs = config.cacheTtlMs ?? 5 * 60 * 1000;\n this.requestTimeoutMs = config.requestTimeoutMs ?? 10_000;\n this.fetchImpl = config.fetch ?? globalThis.fetch;\n this.logger = config.logger ?? console;\n if (typeof this.fetchImpl !== 'function') {\n throw new Error('[ArtifactApiClient] global fetch is not available — provide config.fetch');\n }\n }\n\n /**\n * Resolve a hostname to its project. Returns `null` on 404 or\n * malformed responses. Errors (network / 5xx) are thrown so\n * upstream callers can retry.\n */\n async resolveHostname(host: string): Promise<ResolvedHostname | null> {\n const cached = this.hostnameCache.get(host);\n if (cached && cached.expiresAt > Date.now()) return cached.value;\n\n const inflight = this.pendingHostname.get(host);\n if (inflight) return inflight;\n\n const promise = (async () => {\n try {\n const url = `${this.base}/api/v1/cloud/resolve-hostname?host=${encodeURIComponent(host)}`;\n const res = await this.request(url);\n if (res === null) return null;\n const body = res.success === false ? null : (res.data ?? res);\n if (!body || typeof body.environmentId !== 'string' || !body.environmentId) return null;\n const value: ResolvedHostname = {\n environmentId: body.environmentId,\n organizationId: body.organizationId,\n runtime: body.runtime,\n };\n this.hostnameCache.set(host, { value, expiresAt: Date.now() + this.cacheTtlMs });\n return value;\n } finally {\n this.pendingHostname.delete(host);\n }\n })();\n this.pendingHostname.set(host, promise);\n return promise;\n }\n\n /**\n * Fetch the compiled artifact for a project.\n *\n * When `opts.commit` is set, requests that specific revision via the\n * existing `?commit=` query param. Different commits are cached\n * independently (the cache key includes the commit id) so the preview\n * runtime can hold multiple versions in memory simultaneously.\n */\n async fetchArtifact(environmentId: string, opts?: { commit?: string }): Promise<EnvironmentArtifactResponse | null> {\n const commit = opts?.commit?.trim() || '';\n const cacheKey = commit ? `${environmentId}@${commit}` : environmentId;\n const cached = this.artifactCache.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) return cached.value;\n\n const inflight = this.pendingArtifact.get(cacheKey);\n if (inflight) return inflight;\n\n const promise = (async () => {\n try {\n const qs = commit ? `?commit=${encodeURIComponent(commit)}` : '';\n const url = `${this.base}/api/v1/cloud/environments/${encodeURIComponent(environmentId)}/artifact${qs}`;\n const res = await this.request(url);\n if (res === null) return null;\n const body = res.success === false ? null : (res.data ?? res);\n if (!body || typeof body !== 'object') return null;\n if (!body.metadata) {\n this.logger.warn?.('[ArtifactApiClient] artifact response missing `metadata`', { environmentId, commit });\n return null;\n }\n const value = body as EnvironmentArtifactResponse;\n this.artifactCache.set(cacheKey, { value, expiresAt: Date.now() + this.cacheTtlMs });\n return value;\n } finally {\n this.pendingArtifact.delete(cacheKey);\n }\n })();\n this.pendingArtifact.set(cacheKey, promise);\n return promise;\n }\n\n /**\n * Resolve an 8-hex project short id (first 8 hex chars of the UUID,\n * dashes stripped) to the full environmentId. Used by the preview\n * runtime, which encodes project ids in subdomains.\n *\n * Returns `null` on 404 or ambiguity (the control plane returns 409\n * if the prefix matches more than one project).\n */\n async lookupProjectByShortId(shortId: string): Promise<{ environmentId: string; organizationId?: string } | null> {\n const short = String(shortId ?? '').trim().toLowerCase();\n if (!/^[0-9a-f]{8,}$/.test(short)) return null;\n const url = `${this.base}/api/v1/cloud/environments-by-short-id/${encodeURIComponent(short)}`;\n const res = await this.request(url);\n if (res === null) return null;\n const body = res.success === false ? null : (res.data ?? res);\n if (!body || typeof body.environmentId !== 'string' || !body.environmentId) return null;\n return { environmentId: body.environmentId, organizationId: body.organizationId };\n }\n\n /**\n * Fetch the head commit of a branch. Returns the commit id (and the\n * matching revision row's `published_at` for cache-validity checks).\n * Reuses the existing `GET /cloud/environments/:id/branches` endpoint.\n */\n async fetchBranchHead(\n environmentId: string,\n branchName: string,\n ): Promise<{ commitId: string; publishedAt?: string | null } | null> {\n const url = `${this.base}/api/v1/cloud/environments/${encodeURIComponent(environmentId)}/branches`;\n const res = await this.request(url);\n if (res === null) return null;\n const body = res.success === false ? null : (res.data ?? res);\n const branches = Array.isArray(body?.branches) ? body.branches : [];\n const target = String(branchName ?? '').trim().toLowerCase();\n const found = branches.find((b: any) => String(b?.branch ?? '').toLowerCase() === target);\n if (!found?.headCommitId) return null;\n return { commitId: String(found.headCommitId), publishedAt: found.headPublishedAt ?? null };\n }\n\n /**\n * Cheap freshness probe — returns the env's `last_published_at`\n * (and best-effort current commit) without rebuilding the artifact.\n * Used by `KernelManager` on cache hits to detect when a per-env\n * kernel has been invalidated by an upstream change (marketplace\n * install/uninstall, artifact publish) so it can be rebuilt\n * without waiting for the 15-minute LRU TTL to expire.\n *\n * Returns `null` on definitive 404 / unknown env. Errors propagate\n * (caller decides whether to treat unreachable cloud as fresh or\n * stale — typically fresh, so a brief outage doesn't churn every\n * cached kernel).\n */\n async getFreshness(environmentId: string): Promise<{\n environmentId: string;\n lastPublishedAt: string | null;\n commitId: string | null;\n } | null> {\n const url = `${this.base}/api/v1/cloud/environments/${encodeURIComponent(environmentId)}/freshness`;\n const res = await this.request(url);\n if (res === null) return null;\n const body = res.success === false ? null : (res.data ?? res);\n if (!body || typeof body !== 'object') return null;\n const envId = typeof body.environmentId === 'string' ? body.environmentId : environmentId;\n const lastPublishedAt = typeof body.lastPublishedAt === 'string' ? body.lastPublishedAt : null;\n const commitId = typeof body.commitId === 'string' ? body.commitId : null;\n return { environmentId: envId, lastPublishedAt, commitId };\n }\n\n /** Drop cached entries for a project (and any matching hostname). */\n invalidate(environmentId: string): void {\n // Cache keys are `${environmentId}` for HEAD or `${environmentId}@${commit}`\n // for pinned reads (preview runtime). Drop both shapes.\n this.artifactCache.delete(environmentId);\n const prefix = `${environmentId}@`;\n for (const key of Array.from(this.artifactCache.keys())) {\n if (key.startsWith(prefix)) this.artifactCache.delete(key);\n }\n for (const [host, entry] of this.hostnameCache) {\n if (entry.value.environmentId === environmentId) this.hostnameCache.delete(host);\n }\n }\n\n /** Drop everything. Used on shutdown / hot-reload. */\n clear(): void {\n this.hostnameCache.clear();\n this.artifactCache.clear();\n }\n\n private async request(url: string): Promise<any> {\n const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;\n const timer = controller ? setTimeout(() => controller.abort(), this.requestTimeoutMs) : null;\n try {\n const res = await this.fetchImpl(url, {\n method: 'GET',\n headers: this.buildHeaders(),\n signal: controller?.signal,\n });\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`[ArtifactApiClient] ${url} → HTTP ${res.status}`);\n }\n return await res.json();\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'accept': 'application/json',\n 'user-agent': 'objectos-runtime',\n };\n if (this.apiKey) headers['authorization'] = `Bearer ${this.apiKey}`;\n return headers;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * EnvironmentDriverRegistry implementation that talks to the control plane\n * over HTTP via {@link ArtifactApiClient}.\n *\n * Mirrors {@link DefaultEnvironmentDriverRegistry} from `environment-registry.ts`\n * but does **not** read from a local control-plane database. Hostname →\n * environmentId resolution and per-project runtime config (database URL /\n * driver) come from the control plane API.\n *\n * The cached `project` payload exposed by `peekById()` is shaped to look\n * like a `sys_environment` row so callers downstream (notably\n * `ArtifactKernelFactory`) can read `id`, `organization_id`,\n * `database_url` and `database_driver` without branching.\n */\n\nimport type * as Contracts from '@objectstack/spec/contracts';\nimport { resolve as resolvePathNode } from 'node:path';\nimport type { EnvironmentDriverRegistry } from './environment-registry.js';\nimport type { ArtifactApiClient, EnvironmentRuntimeConfig } from './artifact-api-client.js';\n\ntype IDataDriver = Contracts.IDataDriver;\n\ninterface CacheEntry {\n environmentId: string;\n driver: IDataDriver;\n project: any;\n expiresAt: number;\n}\n\nexport interface ArtifactEnvironmentRegistryConfig {\n client: ArtifactApiClient;\n /** Cache TTL for resolved drivers in ms. Default: 5 min. */\n cacheTtlMs?: number;\n /** Optional logger. */\n logger?: { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n}\n\nexport class ArtifactEnvironmentRegistry implements EnvironmentDriverRegistry {\n private readonly client: ArtifactApiClient;\n private readonly cacheTTL: number;\n private readonly logger: NonNullable<ArtifactEnvironmentRegistryConfig['logger']>;\n\n private readonly hostnameCache = new Map<string, CacheEntry>();\n private readonly idCache = new Map<string, CacheEntry>();\n private readonly pending = new Map<string, Promise<CacheEntry | null>>();\n\n constructor(config: ArtifactEnvironmentRegistryConfig) {\n this.client = config.client;\n this.cacheTTL = config.cacheTtlMs ?? 5 * 60 * 1000;\n this.logger = config.logger ?? console;\n }\n\n async resolveByHostname(host: string): Promise<{ environmentId: string; driver: IDataDriver } | null> {\n const cached = this.hostnameCache.get(host);\n if (cached && cached.expiresAt > Date.now()) {\n return { environmentId: cached.environmentId, driver: cached.driver };\n }\n const key = `host:${host}`;\n const inflight = this.pending.get(key);\n if (inflight) {\n const result = await inflight;\n return result ? { environmentId: result.environmentId, driver: result.driver } : null;\n }\n const promise = (async (): Promise<CacheEntry | null> => {\n try {\n const resolved = await this.client.resolveHostname(host);\n if (!resolved) return null;\n const entry = await this.buildCacheEntry(resolved.environmentId, resolved.runtime, resolved.organizationId, host);\n if (!entry) return null;\n this.hostnameCache.set(host, entry);\n this.idCache.set(entry.environmentId, entry);\n return entry;\n } catch (err: any) {\n this.logger.error?.('[ArtifactEnvironmentRegistry] resolveByHostname failed', {\n host,\n error: err?.message ?? err,\n });\n return null;\n } finally {\n this.pending.delete(key);\n }\n })();\n this.pending.set(key, promise);\n const entry = await promise;\n return entry ? { environmentId: entry.environmentId, driver: entry.driver } : null;\n }\n\n async resolveById(environmentId: string): Promise<IDataDriver | null> {\n const cached = this.idCache.get(environmentId);\n if (cached && cached.expiresAt > Date.now()) return cached.driver;\n\n const key = `id:${environmentId}`;\n const inflight = this.pending.get(key);\n if (inflight) {\n const result = await inflight;\n return result?.driver ?? null;\n }\n const promise = (async (): Promise<CacheEntry | null> => {\n try {\n const entry = await this.buildCacheEntry(environmentId, undefined, undefined, undefined);\n if (!entry) return null;\n this.idCache.set(environmentId, entry);\n if (entry.project?.hostname) this.hostnameCache.set(entry.project.hostname, entry);\n return entry;\n } catch (err: any) {\n this.logger.error?.('[ArtifactEnvironmentRegistry] resolveById failed', {\n environmentId,\n error: err?.message ?? err,\n });\n return null;\n } finally {\n this.pending.delete(key);\n }\n })();\n this.pending.set(key, promise);\n const entry = await promise;\n return entry?.driver ?? null;\n }\n\n peekById(environmentId: string): { environmentId: string; driver: IDataDriver; project: any } | null {\n const cached = this.idCache.get(environmentId);\n if (cached && cached.expiresAt > Date.now()) {\n return { environmentId: cached.environmentId, driver: cached.driver, project: cached.project };\n }\n return null;\n }\n\n invalidate(environmentId: string): void {\n this.idCache.delete(environmentId);\n for (const [host, entry] of this.hostnameCache) {\n if (entry.environmentId === environmentId) this.hostnameCache.delete(host);\n }\n this.client.invalidate(environmentId);\n }\n\n private async buildCacheEntry(\n environmentId: string,\n runtimeFromHostname: EnvironmentRuntimeConfig | undefined,\n orgIdFromHostname: string | undefined,\n hostname: string | undefined,\n ): Promise<CacheEntry | null> {\n let runtime = runtimeFromHostname;\n let organizationId = orgIdFromHostname;\n let host = hostname;\n let artifactProjectId = environmentId;\n\n if (!runtime || !organizationId) {\n const artifact = await this.client.fetchArtifact(environmentId);\n if (!artifact) {\n this.logger.warn?.('[ArtifactEnvironmentRegistry] artifact not found', { environmentId });\n return null;\n }\n artifactProjectId = artifact.environmentId ?? environmentId;\n if (!runtime) runtime = artifact.runtime ?? extractRuntimeFromMetadata(artifact.metadata);\n if (!organizationId) organizationId = artifact.runtime?.organizationId;\n if (!host) host = artifact.runtime?.hostname;\n }\n\n if (!runtime || !runtime.databaseUrl || !runtime.databaseDriver) {\n this.logger.warn?.('[ArtifactEnvironmentRegistry] no runtime config for project', { environmentId });\n return null;\n }\n\n const driver = await createDriver(runtime.databaseDriver, runtime.databaseUrl, runtime.databaseAuthToken ?? '');\n\n const projectRow = {\n id: artifactProjectId,\n organization_id: organizationId,\n hostname: host,\n database_url: runtime.databaseUrl,\n database_driver: runtime.databaseDriver,\n metadata: runtime.metadata,\n };\n\n return {\n environmentId: artifactProjectId,\n driver,\n project: projectRow,\n expiresAt: Date.now() + this.cacheTTL,\n };\n }\n}\n\n/**\n * Best-effort fallback: if the control plane did not return an explicit\n * `runtime` block, look for a default datasource in the compiled artifact\n * and reuse its connection config. Useful for self-published artifacts\n * where the developer encoded the connection inline (e.g. memory:// for\n * demos).\n */\nfunction extractRuntimeFromMetadata(metadata: any): EnvironmentRuntimeConfig | undefined {\n const datasources = metadata?.datasources;\n if (!Array.isArray(datasources) || datasources.length === 0) return undefined;\n const mapping: any[] | undefined = metadata?.datasourceMapping;\n let preferredName: string | undefined;\n if (mapping) {\n const def = mapping.find((m: any) => m?.default === true);\n if (def?.datasource) preferredName = def.datasource;\n }\n const ds = preferredName\n ? datasources.find((d: any) => d?.name === preferredName)\n : datasources[0];\n if (!ds || typeof ds !== 'object') return undefined;\n const config = (ds.config ?? {}) as Record<string, any>;\n const url = config.url ?? config.connectionString ?? config.connection ?? config.filename;\n const driver = ds.driver;\n if (typeof driver !== 'string' || typeof url !== 'string') return undefined;\n return {\n databaseDriver: driver,\n databaseUrl: url,\n databaseAuthToken: typeof config.authToken === 'string' ? config.authToken : undefined,\n };\n}\n\nasync function createDriver(driverType: string, databaseUrl: string, authToken: string): Promise<IDataDriver> {\n switch (driverType) {\n case 'libsql':\n case 'turso': {\n // The libsql/turso driver was extracted out of the framework\n // monorepo into `cloud/packages/driver-turso` (May 2026).\n // Package name is unchanged, so `await import(...)` resolves\n // it from the host app's node_modules (apps/objectos pins\n // `@objectstack/driver-turso: workspace:*` from the cloud\n // workspace, which surfaces in the Docker image's\n // node_modules layout). Self-host installs that need Turso\n // must `npm install @objectstack/driver-turso` from the cloud\n // package (or use the published version) before booting.\n // pnpm symlinks `@objectstack/runtime` into the host app's\n // node_modules but Node's ESM resolver follows the file's\n // realpath, which lives under framework/packages/runtime — from\n // there `@objectstack/driver-turso` (which lives in cloud/) is\n // invisible. We resolve explicitly from the host process cwd\n // (apps/objectos at runtime), which can see the cloud package\n // via its workspace:* dependency.\n let TursoDriver: any;\n try {\n ({ TursoDriver } = await import('@objectstack/driver-turso' as any));\n } catch (primaryErr: any) {\n try {\n const { createRequire } = await import('node:module');\n const path = await import('node:path');\n const url = await import('node:url');\n const hostRequire = createRequire(path.join(process.cwd(), 'noop.js'));\n const resolved = hostRequire.resolve('@objectstack/driver-turso');\n ({ TursoDriver } = await import(url.pathToFileURL(resolved).href));\n } catch (fallbackErr: any) {\n throw new Error(\n `[ArtifactEnvironmentRegistry] libsql/turso driver requested but @objectstack/driver-turso is not resolvable. ` +\n `Install it from the cloud monorepo (cloud/packages/driver-turso) or via npm. ` +\n `(primary: ${primaryErr?.message ?? primaryErr}; fallback: ${fallbackErr?.message ?? fallbackErr})`,\n );\n }\n }\n return new TursoDriver({ url: databaseUrl, authToken }) as unknown as IDataDriver;\n }\n case 'memory': {\n const { InMemoryDriver } = await import('@objectstack/driver-memory');\n const dbName = databaseUrl.replace(/^memory:\\/\\//, '').trim();\n // Resolve memory persistence files under the process cwd's\n // `.objectstack/data/projects/<name>.json` — keeps file-only dev\n // self-contained without depending on the cloud package's\n // serverless data-dir resolver.\n const filePath = dbName\n ? resolvePathNode(process.cwd(), '.objectstack/data/projects', `${dbName}.json`)\n : undefined;\n return new InMemoryDriver({\n persistence: filePath ? { type: 'file', path: filePath } : 'file',\n }) as unknown as IDataDriver;\n }\n case 'sqlite':\n case 'sql': {\n const filePath = databaseUrl.replace(/^file:/, '').replace(/^sql:\\/\\//, '');\n const { SqlDriver } = await import('@objectstack/driver-sql');\n return new SqlDriver({\n client: 'better-sqlite3',\n connection: { filename: filePath },\n useNullAsDefault: true,\n }) as unknown as IDataDriver;\n }\n case 'postgres':\n case 'postgresql':\n case 'pg': {\n const { SqlDriver } = await import('@objectstack/driver-sql');\n return new SqlDriver({\n client: 'pg',\n connection: databaseUrl,\n pool: { min: 0, max: 5 },\n }) as unknown as IDataDriver;\n }\n case 'mongodb':\n case 'mongo': {\n const { MongoDBDriver } = await import('@objectstack/driver-mongodb');\n return new MongoDBDriver({ url: databaseUrl }) as unknown as IDataDriver;\n }\n default:\n throw new Error(`[ArtifactEnvironmentRegistry] Unsupported driver type: ${driverType}`);\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * EnvironmentKernelFactory backed by the control plane's Artifact API.\n *\n * Differs from {@link DefaultEnvironmentKernelFactory} in two ways:\n *\n * 1. There is no local control-plane database to query — project rows\n * come from the {@link ArtifactEnvironmentRegistry} cache populated\n * via HTTP.\n * 2. There is no `ControlPlaneProxyDriver` mounted on the per-project\n * kernel. The runtime is intentionally isolated from the control\n * plane: each project kernel only knows about its own data driver.\n *\n * The kernel is bootstrapped with:\n * • DriverPlugin(driver) — project-scoped data driver, also aliased\n * as the `'cloud'` datasource so AuthPlugin's\n * identity manifest resolves locally.\n * • ObjectQLPlugin\n * • MetadataPlugin (registers `sys_metadata` + `sys_metadata_history` on\n * the project DB — required by ADR-0005: customization\n * overlays such as user-created views/dashboards are\n * persisted by ObjectStackProtocolImplementation on the\n * per-project engine, so the table must exist there).\n * • AuthPlugin — per-project, derives an HKDF secret from\n * `OS_AUTH_SECRET` + environmentId. Each project owns its\n * own `sys_user/sys_session/...` tables in its own\n * Turso DB. Cookies are scoped to the project's\n * hostname (no `.<root>`-wide cross-project leak).\n * • AppPlugin(artifact.metadata) — compiled developer code\n */\n\nimport { createHmac } from 'node:crypto';\nimport { ObjectKernel } from '@objectstack/core';\nimport { readEnvWithDeprecation } from '@objectstack/types';\nimport type * as Contracts from '@objectstack/spec/contracts';\nimport { DriverPlugin } from '../driver-plugin.js';\nimport { AppPlugin } from '../app-plugin.js';\nimport type { EnvironmentKernelFactory } from './kernel-manager.js';\nimport type { EnvironmentDriverRegistry } from './environment-registry.js';\nimport type { ArtifactApiClient } from './artifact-api-client.js';\nimport { loadCapabilities } from './capability-loader.js';\nimport {\n PLATFORM_SSO_PROVIDER_ID,\n derivePlatformSsoClientId,\n derivePlatformSsoClientSecret,\n} from './platform-sso.js';\n\ntype IDataDriver = Contracts.IDataDriver;\n\nexport interface ArtifactKernelFactoryConfig {\n client: ArtifactApiClient;\n envRegistry: EnvironmentDriverRegistry;\n /** Optional logger. */\n logger?: { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n /** Optional kernel constructor config. */\n kernelConfig?: ConstructorParameters<typeof ObjectKernel>[0];\n /**\n * Base secret used to derive per-project AuthPlugin secrets via\n * HKDF-style HMAC-SHA256(baseSecret, environmentId). Falls back to\n * `process.env.OS_AUTH_SECRET` / `AUTH_SECRET` at construction time.\n */\n authBaseSecret?: string;\n}\n\n/**\n * Derive a deterministic per-project auth secret. HMAC-SHA256 of the\n * environmentId keyed by the base secret yields a 64-char hex string that is:\n * - stable across container cold-starts (no DB lookup needed)\n * - independent per project (forging a token on project A does not\n * compromise project B)\n * - rotatable by changing the base secret (will invalidate all sessions)\n */\nfunction deriveProjectAuthSecret(baseSecret: string, environmentId: string): string {\n return createHmac('sha256', baseSecret).update(`project:${environmentId}`).digest('hex');\n}\n\nexport class ArtifactKernelFactory implements EnvironmentKernelFactory {\n private readonly client: ArtifactApiClient;\n private readonly envRegistry: EnvironmentDriverRegistry;\n private readonly logger: NonNullable<ArtifactKernelFactoryConfig['logger']>;\n private readonly kernelConfig?: ArtifactKernelFactoryConfig['kernelConfig'];\n private readonly authBaseSecret: string;\n\n constructor(config: ArtifactKernelFactoryConfig) {\n this.client = config.client;\n this.envRegistry = config.envRegistry;\n this.logger = config.logger ?? console;\n this.kernelConfig = config.kernelConfig;\n this.authBaseSecret = (\n config.authBaseSecret\n ?? readEnvWithDeprecation('OS_AUTH_SECRET', ['AUTH_SECRET', 'BETTER_AUTH_SECRET'])\n ?? ''\n ).trim();\n }\n\n async create(environmentId: string): Promise<ObjectKernel> {\n let cached = this.envRegistry.peekById(environmentId);\n if (!cached) {\n const driver = await this.envRegistry.resolveById(environmentId);\n if (!driver) {\n throw new Error(`[ArtifactKernelFactory] Could not resolve driver for project '${environmentId}'`);\n }\n cached = this.envRegistry.peekById(environmentId);\n if (!cached) {\n throw new Error(`[ArtifactKernelFactory] envRegistry returned a driver but no cached entry for '${environmentId}'`);\n }\n }\n\n const driver: IDataDriver = cached.driver;\n const project = cached.project as { id: string; organization_id?: string; hostname?: string };\n\n const artifact = await this.client.fetchArtifact(environmentId);\n if (!artifact) {\n throw new Error(`[ArtifactKernelFactory] Artifact not available for project '${environmentId}'`);\n }\n\n const { ObjectQLPlugin } = await import('@objectstack/objectql');\n const { MetadataPlugin } = await import('@objectstack/metadata');\n\n const kernel = new ObjectKernel(this.kernelConfig);\n\n // Register the project driver as both the unnamed default AND under\n // the `'cloud'` alias. AuthPlugin's manifest header historically\n // declares `defaultDatasource: 'cloud'`; aliasing here keeps that\n // path working without forcing every project's identity table\n // through a control-plane proxy.\n await kernel.use(new DriverPlugin(driver, { datasourceName: 'cloud' } as any));\n // Enable schema sync per-project so sys_user / sys_session / etc.\n // tables get created on the project's own DB. The host worker sets\n // `OS_SKIP_SCHEMA_SYNC=1` for the control-plane DB; that env var\n // must NOT bleed into project kernels because their auth tables\n // need provisioning. KernelManager caches kernels so this runs\n // at most once per cold-start per project.\n await kernel.use(new ObjectQLPlugin({ environmentId: environmentId, skipSchemaSync: false }));\n await kernel.use(new MetadataPlugin({\n watch: false,\n environmentId: environmentId,\n organizationId: project.organization_id,\n // ADR-0005: customization overlays (user-created views, dashboards,\n // edited objects, ...) are persisted by\n // ObjectStackProtocolImplementation.saveMetaItem on whichever\n // engine the protocol is attached to. For per-project kernels that\n // means the project's own DB, so the sys_metadata + history tables\n // MUST be provisioned here. The previous `false` setting caused\n // \"no such table: sys_metadata\" errors on any PUT /api/v1/meta/*\n // call (e.g. Studio \"Create View\") against a project deployment.\n registerSystemObjects: true,\n }));\n\n // Per-project AuthPlugin — only when an OS_AUTH_SECRET base is\n // configured. Without it we cannot derive a secret deterministically\n // and refuse to start auth (better silent-fail than insecure default).\n if (this.authBaseSecret) {\n try {\n const { AuthPlugin } = await import('@objectstack/plugin-auth');\n const projectSecret = deriveProjectAuthSecret(this.authBaseSecret, environmentId);\n const baseUrl = project.hostname\n ? (project.hostname.startsWith('http')\n ? project.hostname\n : (/(\\.|^)localhost(:\\d+)?$/i.test(project.hostname)\n ? (() => {\n const runtimePort = (process.env.OS_RUNTIME_PORT ?? '').trim();\n const hasPort = /:\\d+$/.test(project.hostname);\n const hostWithPort = hasPort || !runtimePort\n ? project.hostname\n : `${project.hostname}:${runtimePort}`;\n return `http://${hostWithPort}`;\n })()\n : `https://${project.hostname}`))\n : undefined;\n\n // Build the list of trusted origins for CSRF.\n // - Production: just the project's https baseUrl + any\n // platform-wide origins from OS_TRUSTED_ORIGINS (so\n // hostname renames don't require a kernel evict — the\n // parent worker already trusts `https://*.<rootdomain>`).\n // - Dev (*.localhost): also trust http variants on any port so\n // the local objectos dev server (PORT=4100 or any user-chosen\n // port) can complete sign-in from the browser. baseUrl alone\n // is `https://*.localhost` (no port, https) which the\n // browser's Origin (`http://*.localhost:4100`) does NOT\n // match — leading to better-auth \"Invalid origin\" 403.\n const trustedOriginsList: string[] = [];\n if (baseUrl) trustedOriginsList.push(baseUrl);\n // Inherit platform trusted-origin wildcards from the host\n // worker. Without this, renaming an environment leaves the\n // cached per-project kernel rejecting callbackURL=<new-host>\n // with INVALID_CALLBACK_URL until the next cold-start.\n const platformOrigins = (process.env.OS_TRUSTED_ORIGINS ?? '')\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n for (const o of platformOrigins) {\n if (!trustedOriginsList.includes(o)) trustedOriginsList.push(o);\n }\n // Convenience: when OS_ROOT_DOMAIN is set, trust the entire\n // platform subdomain space. Matches the host worker's CORS\n // posture so SSO survives any future tenant-domain rename.\n const rootDomain = (process.env.OS_ROOT_DOMAIN ?? '').trim().replace(/^https?:\\/\\//, '');\n if (rootDomain) {\n const wildcard = `https://*.${rootDomain}`;\n if (!trustedOriginsList.includes(wildcard)) trustedOriginsList.push(wildcard);\n }\n if (project.hostname) {\n const bareHost = project.hostname.replace(/^https?:\\/\\//, '');\n if (bareHost.endsWith('.localhost') || bareHost === 'localhost') {\n trustedOriginsList.push(`http://${bareHost}`);\n trustedOriginsList.push(`http://${bareHost}:*`);\n trustedOriginsList.push(`https://${bareHost}:*`);\n }\n }\n\n // Platform SSO (\"Airtable-style unified login\"): when the\n // cloud control-plane is reachable AND the master secret is\n // shared between the two containers, wire better-auth's\n // genericOAuth plugin so a builder who already signed in\n // on `cloud.<root>` is JIT-provisioned as a `sys_user` on\n // every per-project deployment without re-registering.\n //\n // Opt-out: set OS_PLATFORM_SSO=false to fall back to the\n // legacy \"every project owns its own login\" mode.\n const platformSsoEnabled = String(\n process.env.OS_PLATFORM_SSO ?? 'true',\n ).toLowerCase() !== 'false';\n const cloudBaseUrl = (process.env.OS_CLOUD_URL ?? '').trim().replace(/\\/+$/, '');\n const oidcProviders = platformSsoEnabled\n && cloudBaseUrl\n && /^https?:\\/\\//.test(cloudBaseUrl)\n ? [{\n providerId: PLATFORM_SSO_PROVIDER_ID,\n name: 'ObjectStack',\n discoveryUrl: `${cloudBaseUrl}/.well-known/openid-configuration`,\n clientId: derivePlatformSsoClientId(environmentId),\n clientSecret: derivePlatformSsoClientSecret(this.authBaseSecret, environmentId),\n scopes: ['openid', 'email', 'profile'],\n }]\n : undefined;\n\n await kernel.use(new AuthPlugin({\n secret: projectSecret,\n baseUrl,\n // Project kernel has no http-server (host owns it). The\n // dispatcher's handleAuth path resolves `auth` via\n // getService and invokes the handler directly — route\n // registration is unnecessary and would warn.\n registerRoutes: false,\n // Identity tables live in the project's own DB — keep\n // sys_user/sys_session local to this kernel.\n manifestDatasource: 'default',\n // Cookie scope: default to the project's own host. We\n // intentionally do NOT pass crossSubDomainCookies here\n // so cookies stay isolated per project subdomain.\n trustedOrigins: trustedOriginsList.length ? trustedOriginsList : undefined,\n ...(oidcProviders ? { oidcProviders } : {}),\n } as any));\n if (oidcProviders) {\n this.logger.info?.('[ArtifactKernelFactory] platform SSO wired', {\n environmentId,\n cloudBaseUrl,\n });\n }\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] AuthPlugin not registered', {\n environmentId,\n error: err?.message,\n });\n }\n } else {\n this.logger.warn?.('[ArtifactKernelFactory] OS_AUTH_SECRET not set — per-project AuthPlugin skipped (auth endpoints will return 404)', { environmentId });\n }\n\n // Per-project SecurityPlugin — provides RBAC + tenant_isolation RLS.\n // Multi-tenant deployments additionally register OrgScopingPlugin,\n // which provides organization_id auto-stamping, per-org seed\n // replay, and default-org bootstrap. SecurityPlugin probes the\n // `org-scoping` service at start time and strips the wildcard\n // `tenant_isolation` RLS when the scoping plugin is absent —\n // so OrgScopingPlugin MUST be registered before SecurityPlugin.\n try {\n const multiTenant = String(readEnvWithDeprecation('OS_MULTI_ORG_ENABLED', 'OS_MULTI_TENANT') ?? 'false').toLowerCase() !== 'false';\n if (multiTenant) {\n try {\n const { OrgScopingPlugin } = await import('@objectstack/plugin-org-scoping');\n await kernel.use(new OrgScopingPlugin() as any);\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] OrgScopingPlugin not registered (multi-tenant disabled)', {\n environmentId,\n error: err?.message,\n });\n }\n }\n const { SecurityPlugin } = await import('@objectstack/plugin-security');\n await kernel.use(new SecurityPlugin() as any);\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] SecurityPlugin not registered', {\n environmentId,\n error: err?.message,\n });\n }\n\n const projectName = project.hostname ?? environmentId;\n // Cloud Artifact API envelope shape (see\n // `service-cloud/src/routes/cloud.ts`):\n // { schemaVersion, environmentId, commitId, checksum,\n // metadata: { objects, views, apps, ... }, // category arrays only\n // functions, manifest, builtAt, runtime }\n // `manifest` is a TOP-LEVEL SIBLING of `metadata`, not nested\n // inside it. AppPlugin reads `bundle.manifest.id` for the plugin\n // name, so we must surface the sibling manifest onto the bundle\n // we hand it — otherwise it falls back to `'unnamed-app'` and a\n // package install (e.g. CRM Starter with declarative hooks)\n // crashes the env kernel at start, rolling back all plugins and\n // 500'ing every API.\n const artifactAny = artifact as any;\n const topLevelManifest = (artifactAny?.manifest && typeof artifactAny.manifest === 'object')\n ? artifactAny.manifest\n : null;\n const topLevelFunctions = Array.isArray(artifactAny?.functions) ? artifactAny.functions : [];\n const bundle: any = {\n ...(artifact.metadata ?? {}),\n ...(topLevelManifest ? { manifest: topLevelManifest } : {}),\n functions: topLevelFunctions,\n };\n const sys = bundle.manifest ?? bundle;\n const packageId = sys?.packageId ?? sys?.package_id ?? bundle?.packageId;\n\n // Per-project i18n: register I18nServicePlugin BEFORE AppPlugin so\n // AppPlugin.loadTranslations() finds an i18n service to populate.\n // Without this, the artifact's `translations` array is silently\n // dropped and the `/api/v1/i18n/*` endpoints return empty payloads.\n const i18nCfg = (bundle?.i18n ?? sys?.i18n ?? {}) as Record<string, any>;\n const trArr = Array.isArray(bundle?.translations) ? bundle.translations\n : Array.isArray(sys?.translations) ? sys.translations : [];\n // Always register — even with no inline translations the service\n // can serve labels/locales loaded by hosted apps. Cheap to register.\n try {\n const { I18nServicePlugin } = await import('@objectstack/service-i18n');\n await kernel.use(new I18nServicePlugin({\n defaultLocale: i18nCfg.defaultLocale,\n fallbackLocale: i18nCfg.fallbackLocale ?? i18nCfg.defaultLocale ?? 'en',\n // Routes are dispatched by HttpDispatcher.handleI18n via\n // kernel.getService('i18n'); the host worker owns the\n // HTTP server. Skip self-registration to avoid warnings.\n registerRoutes: false,\n } as any));\n console.warn(\n `[ArtifactKernelFactory] I18nServicePlugin registered (project=${environmentId}, translations=${trArr.length}, defaultLocale=${i18nCfg.defaultLocale ?? 'en'})`,\n );\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] I18nServicePlugin not registered', {\n environmentId,\n error: err?.message,\n });\n }\n\n // Tier-driven capability loading: install service plugins listed\n // in the artifact's `requires` array (e.g. ['ai','automation',\n // 'analytics']). Must be registered BEFORE AppPlugin so that\n // AppPlugin's start phase can hand off flows/agents/cubes to\n // services that are already initialised.\n const requiresRaw =\n (Array.isArray(bundle?.requires) ? bundle.requires : null) ??\n (Array.isArray(sys?.requires) ? sys.requires : null) ??\n [];\n const requires: string[] = (requiresRaw as unknown[])\n .filter((x): x is string => typeof x === 'string' && x.length > 0);\n\n if (requires.length > 0) {\n const installed = await loadCapabilities({\n kernel,\n requires,\n bundle: { ...(bundle ?? {}), ...(sys ?? {}) } as Record<string, unknown>,\n logger: this.logger,\n environmentId,\n });\n this.logger.info?.('[ArtifactKernelFactory] capabilities loaded', {\n environmentId,\n requires,\n installed,\n });\n }\n\n await kernel.use(new AppPlugin(bundle, {\n environmentId,\n organizationId: project.organization_id ?? '',\n projectName,\n packageId,\n source: packageId ? 'package' : 'user',\n } as any));\n\n await kernel.bootstrap();\n\n // Pre-seed the project owner. The cloud control-plane stashed the\n // creator's identity into `sys_environment.metadata.ownerSeed` at\n // project-create time; replay it AFTER `kernel.bootstrap()` so\n // ObjectQL/Security plugins have fully initialised and\n // `kernel.getService('objectql')` resolves. Pre-bootstrap, plugins\n // are only registered — services aren't wired yet.\n //\n // Order matters:\n // 1. Seed the OWNING cloud org into `sys_organization` so the\n // project's primary workspace matches the cloud team that\n // owns the project at the platform level.\n // 2. Seed the owner's `sys_user` row.\n // 3. Seed a `sys_member(owner)` row binding the user to the\n // cloud org so their first sign-in resolves an\n // activeOrganizationId without requiring an extra\n // \"create your first organization\" step.\n //\n // All three are idempotent — safe across cold-boots.\n try {\n const projMeta: any = typeof (project as any)?.metadata === 'string'\n ? JSON.parse((project as any).metadata)\n : ((project as any)?.metadata ?? {});\n const ownerSeed = projMeta?.ownerSeed;\n const orgSeed = projMeta?.orgSeed;\n\n if (orgSeed?.id && orgSeed?.name) {\n try {\n const { seedProjectOrganization } = await import('./environment-org-seed.js');\n await seedProjectOrganization(kernel, orgSeed, this.logger);\n } catch (e: any) {\n this.logger.warn?.('[ArtifactKernelFactory] orgSeed threw', {\n environmentId,\n error: e?.message,\n });\n }\n }\n\n if (ownerSeed?.userId && ownerSeed?.email) {\n try {\n const { seedProjectOwner } = await import('./environment-owner-seed.js');\n await seedProjectOwner(kernel, ownerSeed, this.logger);\n } catch (e: any) {\n this.logger.warn?.('[ArtifactKernelFactory] ownerSeed threw', {\n environmentId,\n error: e?.message,\n });\n }\n\n if (orgSeed?.id) {\n try {\n const { seedProjectMember } = await import('./environment-org-seed.js');\n await seedProjectMember(\n kernel,\n { userId: ownerSeed.userId, organizationId: orgSeed.id, role: 'owner' },\n this.logger,\n );\n } catch (e: any) {\n this.logger.warn?.('[ArtifactKernelFactory] memberSeed threw', {\n environmentId,\n error: e?.message,\n });\n }\n }\n }\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] owner/org seed skipped', {\n environmentId,\n error: err?.message,\n });\n }\n\n // Post-bootstrap seed replay. The SecurityPlugin's `sys_organization`\n // insert middleware only fires when a brand-new org row is inserted,\n // so packages installed AFTER the env's primary org already exists\n // would never get their `data` arrays applied. Run the seed-replayer\n // once per kernel cold-start so newly-installed marketplace packages\n // (e.g. CRM with \"Include sample data\" ticked) hydrate the primary\n // org on the next request after install.\n //\n // SeedLoader uses upsert semantics, so re-running across cold-starts\n // is idempotent — at worst we pay one batch upsert per kernel boot.\n try {\n const datasetsNow: any[] | undefined = (() => {\n try { return (kernel as any).getService?.('seed-datasets'); } catch { return undefined; }\n })();\n const replayer: any = (() => {\n try { return (kernel as any).getService?.('seed-replayer'); } catch { return undefined; }\n })();\n\n if (Array.isArray(datasetsNow) && datasetsNow.length > 0 && typeof replayer === 'function') {\n // Resolve the env's primary organization. Prefer the explicit\n // orgSeed metadata (set when env is created via the data API);\n // fall back to scanning sys_organization for the first row\n // (env created via the lifecycle endpoint that doesn't stash\n // orgSeed, or any env that has been used at least once).\n const projMetaRaw: any = (project as any)?.metadata;\n const projMeta: any = typeof projMetaRaw === 'string' ? (() => {\n try { return JSON.parse(projMetaRaw); } catch { return {}; }\n })() : (projMetaRaw ?? {});\n let primaryOrgId: string | undefined = projMeta?.orgSeed?.id;\n\n if (!primaryOrgId) {\n try {\n const ql: any = (kernel as any).getService?.('objectql');\n if (ql?.find) {\n const rows = await ql.find('sys_organization', { limit: 5, orderBy: [{ field: 'created_at', direction: 'asc' }] } as any);\n const list = Array.isArray(rows) ? rows : (rows?.value ?? rows?.records ?? []);\n if (Array.isArray(list) && list.length > 0 && list[0]?.id) {\n primaryOrgId = String(list[0].id);\n }\n }\n } catch { /* org table may not exist yet on a brand-new env */ }\n }\n\n if (primaryOrgId) {\n try {\n const summary = await replayer(primaryOrgId);\n const inserted = summary?.inserted ?? 0;\n const updated = summary?.updated ?? 0;\n const errs = summary?.errors?.length ?? 0;\n if (inserted > 0 || updated > 0 || errs > 0) {\n this.logger.info?.('[ArtifactKernelFactory] post-bootstrap seed replay', {\n environmentId,\n organizationId: primaryOrgId,\n datasets: datasetsNow.length,\n inserted,\n updated,\n errors: errs,\n });\n }\n } catch (e: any) {\n this.logger.warn?.('[ArtifactKernelFactory] post-bootstrap seed replay failed', {\n environmentId,\n organizationId: primaryOrgId,\n error: e?.message,\n });\n }\n }\n }\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] post-bootstrap seed step threw', {\n environmentId,\n error: err?.message,\n });\n }\n\n // Belt-and-braces: load translation bundles directly into the i18n\n // service after bootstrap. AppPlugin.loadTranslations should do this\n // during its `start` phase, but several conditions (missing objectql\n // service, runtime.onEnable throwing, bundle keys mismatch) can cause\n // it to bail before reaching the i18n step. Loading here guarantees\n // the bundles attached to the artifact metadata are always served via\n // `/api/v1/i18n/*`, regardless of AppPlugin's runtime path.\n let i18nSvc: any = null;\n try {\n i18nSvc = (kernel as any).getService?.('i18n');\n } catch {\n // getService throws when service isn't registered — leave null\n i18nSvc = null;\n }\n try {\n if (i18nSvc && typeof i18nSvc.loadTranslations === 'function') {\n if (i18nCfg.defaultLocale && typeof i18nSvc.setDefaultLocale === 'function') {\n i18nSvc.setDefaultLocale(i18nCfg.defaultLocale);\n }\n let loaded = 0;\n for (const tbundle of trArr) {\n if (!tbundle || typeof tbundle !== 'object') continue;\n for (const [locale, data] of Object.entries(tbundle)) {\n if (data && typeof data === 'object') {\n try {\n i18nSvc.loadTranslations(locale, data as Record<string, unknown>);\n loaded++;\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] i18n loadTranslations failed', {\n environmentId, locale, error: err?.message,\n });\n }\n }\n }\n }\n if (loaded > 0) {\n this.logger.info?.('[ArtifactKernelFactory] i18n direct-load complete', {\n environmentId, locales: loaded, bundles: trArr.length,\n });\n }\n }\n } catch (err: any) {\n this.logger.warn?.('[ArtifactKernelFactory] i18n direct-load failed', {\n environmentId,\n error: err?.message,\n });\n }\n\n this.logger.info?.('[ArtifactKernelFactory] kernel ready', {\n environmentId,\n commitId: artifact.commitId,\n checksum: artifact.checksum,\n authEnabled: Boolean(this.authBaseSecret),\n });\n\n return kernel;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Capability loader — `bundle.requires` driven dispatch.\n *\n * Mirrors the CAPABILITY_PROVIDERS table in\n * `@objectstack/cli/src/commands/serve.ts` so that per-project kernels\n * built by {@link ArtifactKernelFactory} pick up the same service plugins\n * a developer would get when running `objectstack serve` locally.\n *\n * Design goals:\n * - Single source of truth: artifact's `requires` array. No hardcoded\n * plugin list per host.\n * - Lazy: each provider is dynamically imported only when requested,\n * keeping cold-start small for artifacts that don't need that\n * capability.\n * - Silent on missing deps: a host that doesn't ship the optional\n * package (e.g. service-queue) just logs a warn and continues.\n */\n\nimport type { ObjectKernel } from '@objectstack/core';\n\nexport interface CapabilitySpec {\n /** npm package name to import. */\n pkg: string;\n /** Named export — class constructor for the main plugin. */\n export: string;\n /**\n * Optional bundle key that, when present, is forwarded as constructor\n * argument (e.g. analytics needs `analyticsCubes`).\n */\n configKey?: string;\n /** Auxiliary plugins loaded alongside the main one. */\n extras?: Array<{ pkg: string; export: string }>;\n}\n\n/**\n * Registry of `requires` token → plugin provider.\n *\n * Keep keys in sync with the user-facing tokens accepted by\n * `defineStack({ requires: [...] })` and the CLI's CAPABILITY_PROVIDERS.\n *\n * Tier-gated capabilities (`auth`, `ui`, `i18n`) are intentionally NOT\n * listed here — they are wired explicitly by the kernel factory because\n * they need bespoke configuration (per-project HKDF secret, UI dist\n * paths, etc).\n */\nexport const CAPABILITY_PROVIDERS: Record<string, CapabilitySpec> = {\n automation: {\n // Self-contained: AutomationServicePlugin seeds all built-in node\n // executors itself (ADR-0018), so no companion node-pack plugins.\n pkg: '@objectstack/service-automation',\n export: 'AutomationServicePlugin',\n },\n ai: {\n pkg: '@objectstack/service-ai',\n export: 'AIServicePlugin',\n },\n analytics: {\n pkg: '@objectstack/service-analytics',\n export: 'AnalyticsServicePlugin',\n configKey: 'analyticsCubes',\n },\n audit: {\n pkg: '@objectstack/plugin-audit',\n export: 'AuditPlugin',\n },\n cache: {\n pkg: '@objectstack/service-cache',\n export: 'CacheServicePlugin',\n },\n storage: {\n pkg: '@objectstack/service-storage',\n export: 'StorageServicePlugin',\n },\n queue: {\n pkg: '@objectstack/service-queue',\n export: 'QueueServicePlugin',\n },\n job: {\n pkg: '@objectstack/service-job',\n export: 'JobServicePlugin',\n },\n messaging: {\n // Backs the `notify` flow node (ADR-0012): delivers to a user's\n // channels (inbox by default → `sys_inbox_message` rows).\n pkg: '@objectstack/service-messaging',\n export: 'MessagingServicePlugin',\n },\n triggers: {\n // Concrete flow triggers — record-change (ObjectQL hooks) + schedule\n // (cron/interval via the job service; pair `triggers` with `job`).\n pkg: '@objectstack/plugin-trigger-record-change',\n export: 'RecordChangeTriggerPlugin',\n extras: [{ pkg: '@objectstack/plugin-trigger-schedule', export: 'ScheduleTriggerPlugin' }],\n },\n realtime: {\n pkg: '@objectstack/service-realtime',\n export: 'RealtimeServicePlugin',\n },\n feed: {\n pkg: '@objectstack/service-feed',\n export: 'FeedServicePlugin',\n },\n settings: {\n pkg: '@objectstack/service-settings',\n export: 'SettingsServicePlugin',\n },\n};\n\ntype Logger = { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n\nexport interface LoadCapabilitiesOptions {\n kernel: ObjectKernel;\n /** Tokens from `bundle.requires` (e.g. `['ai','automation','analytics']`). */\n requires: readonly string[];\n /** Compiled artifact metadata. Used to pull `configKey`-driven args. */\n bundle: Record<string, unknown>;\n /** Optional logger. */\n logger?: Logger;\n /** environmentId for log breadcrumbs. */\n environmentId: string;\n}\n\n/**\n * Walk `requires` and install each known capability on the kernel.\n *\n * Returns the list of plugin exports actually installed for diagnostics.\n */\nexport async function loadCapabilities(opts: LoadCapabilitiesOptions): Promise<string[]> {\n const { kernel, requires, bundle, environmentId } = opts;\n const logger: Logger = opts.logger ?? console;\n const installed: string[] = [];\n\n // De-dupe, then ensure dependent capabilities are present. ADR-0030:\n // collaboration notifications (audit @mention/assignment) and the bell now\n // deliver through the messaging pipeline, so `messaging` must load whenever\n // `audit` does — otherwise those notifications silently no-op on cloud\n // per-project kernels (which, unlike `objectstack serve`, have no\n // always-on capability slate). Mirrors the CLI's foundational defaults.\n const resolved = [...new Set(requires)];\n if (resolved.includes('audit') && !resolved.includes('messaging')) {\n resolved.push('messaging');\n }\n\n for (const cap of resolved) {\n const spec = CAPABILITY_PROVIDERS[cap];\n if (!spec) {\n // Tier-gated capability (auth/ui/i18n) — wired elsewhere.\n continue;\n }\n\n try {\n const mod: any = await import(/* webpackIgnore: true */ spec.pkg);\n const Ctor = mod[spec.export];\n if (!Ctor) {\n logger.warn?.(\n `[CapabilityLoader] '${cap}': package '${spec.pkg}' did not export '${spec.export}'`,\n { environmentId },\n );\n continue;\n }\n\n let arg: unknown;\n if (spec.configKey) {\n const v = (bundle as Record<string, unknown>)[spec.configKey];\n if (spec.configKey === 'analyticsCubes') {\n arg = { cubes: Array.isArray(v) ? v : [] };\n } else if (v !== undefined) {\n arg = v;\n }\n }\n\n await kernel.use(arg !== undefined ? new Ctor(arg) : new Ctor());\n installed.push(spec.export);\n\n if (spec.extras) {\n for (const ex of spec.extras) {\n try {\n const exMod: any = await import(/* webpackIgnore: true */ ex.pkg);\n const ExCtor = exMod[ex.export];\n if (ExCtor) {\n await kernel.use(new ExCtor());\n installed.push(ex.export);\n }\n } catch {\n // Optional extra — silently skip.\n }\n }\n }\n\n logger.info?.(\n `[CapabilityLoader] '${cap}' installed (${spec.export}${spec.extras ? ' + ' + spec.extras.length + ' extras' : ''})`,\n { environmentId },\n );\n } catch (err: any) {\n const msg = err?.message ?? String(err);\n if (msg.includes('Cannot find module') || msg.includes('ERR_MODULE_NOT_FOUND')) {\n logger.warn?.(\n `[CapabilityLoader] '${cap}' requested but '${spec.pkg}' not installed in host — skipped`,\n { environmentId },\n );\n } else {\n logger.error?.(\n `[CapabilityLoader] '${cap}' load failed: ${msg}`,\n { environmentId },\n );\n }\n }\n }\n\n return installed;\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Platform SSO — shared between the cloud control-plane and the per-project\n * runtime kernels created by {@link ArtifactKernelFactory}.\n *\n * The architecture is \"Airtable-style unified login\": a builder signs in\n * once on `cloud.<root>` and is JIT-provisioned as a `sys_user` on every\n * per-project deployment (`<project>.<root>`) via the OAuth2 / OIDC\n * authorization-code flow.\n *\n * - cloud = OIDC Identity Provider (better-auth's `oauth-provider` plugin\n * — already wired in {@link AuthPlugin} when `oidcProvider:true`)\n * - project = OIDC Relying Party (better-auth's `genericOAuth` plugin —\n * opted in via the `oidcProviders` array on AuthPluginOptions)\n *\n * For the two sides to trust each other without runtime DB calls during\n * the SSO handshake, we use deterministic, derived client credentials:\n *\n * - `client_id` = `'project_' + environmentId`\n * - `client_secret` = HMAC-SHA256(baseSecret, 'oauth-client:' + environmentId)\n * - `redirect_uri` = `https://<hostname>/api/v1/auth/oauth2/callback/<PROVIDER_ID>`\n *\n * Both cloud and project containers share the same `OS_AUTH_SECRET` (or\n * `AUTH_SECRET`) — that's the only piece of state required for the\n * project-side runtime to derive the right secret without a control-plane\n * lookup. The cloud-side row in `sys_oauth_application` is a one-time\n * write per project and is upserted in two places:\n *\n * 1. {@link seedPlatformSsoClient} — called from the project-provisioning\n * flow in `http-dispatcher.ts` right after the `sys_environment` row is\n * inserted, so brand-new projects can SSO from the very first request.\n * 2. {@link backfillPlatformSsoClients} — registered as a boot-time\n * plugin in `control-plane-preset.ts` to retro-fit any pre-existing\n * projects that were created before this code shipped.\n */\n\nimport { createHmac, createHash } from 'node:crypto';\n\n/**\n * Provider id used in better-auth's `genericOAuth` and as part of the\n * callback URL: `/api/v1/auth/oauth2/callback/<PROVIDER_ID>`. Keep stable —\n * changing it invalidates every registered redirect_uri.\n */\nexport const PLATFORM_SSO_PROVIDER_ID = 'objectstack-cloud';\n\n/**\n * Derive the per-project OAuth client_id used in `sys_oauth_application`\n * (cloud side) and {@link genericOAuth} config (project side).\n */\nexport function derivePlatformSsoClientId(environmentId: string): string {\n return `project_${environmentId}`;\n}\n\n/**\n * Derive the per-project OAuth client_secret deterministically from the\n * shared master secret. HMAC-SHA256(baseSecret, 'oauth-client:' + environmentId)\n * yields a 64-char hex string that is:\n * - stable across container cold-starts (no DB lookup needed)\n * - independent per project (compromising one does not compromise others)\n * - rotatable via OS_AUTH_SECRET rotation (invalidates all SSO clients)\n *\n * This is the **plaintext** value the RP must present at the token endpoint.\n * The cloud-side `sys_oauth_application.client_secret` column instead stores\n * {@link hashPlatformSsoClientSecret}(plaintext) — better-auth's oauth-provider\n * defaults to `storeClientSecret: 'hashed'` (SHA-256 + base64url) when the JWT\n * plugin is enabled, and looks up the row by hashing the presented secret.\n */\nexport function derivePlatformSsoClientSecret(baseSecret: string, environmentId: string): string {\n return createHmac('sha256', baseSecret).update(`oauth-client:${environmentId}`).digest('hex');\n}\n\n/**\n * Hash the plaintext client_secret the same way `@better-auth/oauth-provider`'s\n * `defaultHasher` does it: SHA-256 → base64url (no padding). This MUST match\n * exactly or the token endpoint returns `invalid_client / invalid client_secret`\n * even though the row is present.\n *\n * Reference: `node_modules/@better-auth/oauth-provider/dist/utils-*.mjs` →\n * `const defaultHasher = async (value) => base64Url.encode(SHA-256(value))`\n */\nexport function hashPlatformSsoClientSecret(plaintext: string): string {\n return createHash('sha256').update(plaintext)\n .digest('base64')\n .replace(/=+$/, '')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_');\n}\n\n/**\n * Build the redirect_uri better-auth's `genericOAuth` plugin will use\n * when the project kernel mounts the provider with id\n * {@link PLATFORM_SSO_PROVIDER_ID}. MUST be one of the URIs registered\n * on the cloud-side oauth client or the authorization server will reject\n * the callback with `invalid_request`.\n */\nexport function buildPlatformSsoRedirectUri(hostname: string, basePath: string = '/api/v1/auth'): string {\n let host: string;\n if (hostname.startsWith('http://') || hostname.startsWith('https://')) {\n host = hostname;\n } else if (/(\\.|^)localhost(:\\d+)?$/i.test(hostname)) {\n // Local dev: localhost subdomains run on plain http with a custom\n // port. When the caller passes only a hostname (no scheme/port),\n // append the configured runtime port so the OAuth redirect_uri\n // matches what the browser can actually reach. We read\n // OS_RUNTIME_PORT (NOT PORT) because both the cloud control plane\n // and the runtime container call this function — only the runtime\n // port is meaningful for the callback.\n const port = (process.env.OS_RUNTIME_PORT ?? '').trim();\n const hostWithPort = /:\\d+$/.test(hostname) || !port ? hostname : `${hostname}:${port}`;\n host = `http://${hostWithPort}`;\n } else {\n host = `https://${hostname}`;\n }\n const trimmed = host.replace(/\\/+$/, '');\n const path = basePath.replace(/\\/+$/, '');\n return `${trimmed}${path}/oauth2/callback/${PLATFORM_SSO_PROVIDER_ID}`;\n}\n\nexport interface SeedPlatformSsoClientOptions {\n /**\n * Cloud control-plane ObjectQL engine. Must expose `find(object, query)`,\n * `insert(object, data)`, and `update(object, data, {where})`. Both the\n * `apps/cloud` boot kernel (via `kernel.getService('objectql')`) and the\n * dispatcher's local `ql` reference satisfy this shape.\n */\n ql: {\n find: (object: string, query: any, opts?: any) => Promise<any>;\n insert: (object: string, data: any, opts?: any) => Promise<any>;\n update: (object: string, data: any, where: any, opts?: any) => Promise<any>;\n };\n /** Project id (also used to derive client_id + client_secret). */\n environmentId: string;\n /**\n * Project hostname (e.g. `acme-crm.objectos.ai`). Optional — projects\n * may be created before a hostname is assigned, in which case no\n * redirect_uri is registered yet and the row is upserted with an\n * empty `redirect_uris` array. Calling this function again once the\n * hostname is known will merge the new URI in.\n */\n hostname?: string | null;\n /** Master secret shared between cloud and project containers. */\n baseSecret: string;\n /** Optional logger for diagnostics. */\n logger?: { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n /** When true, rethrow insert/update errors instead of swallowing them.\n * Backfill uses this to surface real failures via the admin endpoint. */\n throwOnError?: boolean;\n}\n\n/**\n * Idempotently upsert a `sys_oauth_application` row for the given project.\n * Re-running with the same `environmentId` is a no-op (the deterministic\n * `client_id` is uniquely indexed and the secret derivation is stable).\n * Re-running with a new `hostname` adds the new redirect_uri to the\n * existing row's JSON array.\n */\nexport async function seedPlatformSsoClient(opts: SeedPlatformSsoClientOptions): Promise<void> {\n const { ql, environmentId, hostname, baseSecret, logger, throwOnError } = opts;\n if (!baseSecret) {\n logger?.warn?.('[platform-sso] OS_AUTH_SECRET not set — skipping client seed', { environmentId });\n return;\n }\n const clientId = derivePlatformSsoClientId(environmentId);\n const clientSecretPlaintext = derivePlatformSsoClientSecret(baseSecret, environmentId);\n const clientSecretStored = hashPlatformSsoClientSecret(clientSecretPlaintext);\n const desiredRedirect = hostname ? buildPlatformSsoRedirectUri(hostname) : null;\n\n let existing: any = null;\n try {\n const rows = await ql.find('sys_oauth_application', {\n where: { client_id: clientId },\n limit: 1,\n }, { context: { isSystem: true } });\n const list = Array.isArray(rows) ? rows : Array.isArray((rows as any)?.records) ? (rows as any).records : [];\n existing = list[0] ?? null;\n } catch (err) {\n // Table may not exist yet (control-plane not yet migrated). Treat\n // as a no-op rather than crashing the project-create flow.\n logger?.warn?.('[platform-sso] sys_oauth_application read failed — skipping seed', {\n environmentId,\n error: (err as Error)?.message,\n });\n return;\n }\n\n const nowIso = new Date().toISOString();\n if (!existing) {\n const redirects = desiredRedirect ? [desiredRedirect] : [];\n try {\n await ql.insert('sys_oauth_application', {\n id: `oauthc_${environmentId}`,\n name: `Project ${environmentId}`,\n client_id: clientId,\n client_secret: clientSecretStored,\n type: 'web',\n redirect_uris: JSON.stringify(redirects),\n grant_types: JSON.stringify(['authorization_code', 'refresh_token']),\n response_types: JSON.stringify(['code']),\n scopes: JSON.stringify(['openid', 'email', 'profile']),\n token_endpoint_auth_method: 'client_secret_basic',\n require_pkce: false,\n skip_consent: true,\n disabled: false,\n subject_type: 'public',\n created_at: nowIso,\n updated_at: nowIso,\n }, { context: { isSystem: true } });\n logger?.info?.('[platform-sso] sys_oauth_application row created', { environmentId, clientId });\n } catch (err) {\n // Unique-index conflict implies a parallel writer raced us; treat\n // as success. Other errors are logged but non-fatal so they\n // don't poison the project-create response.\n logger?.warn?.('[platform-sso] sys_oauth_application create failed', {\n environmentId,\n error: (err as Error)?.message,\n });\n if (throwOnError) throw err;\n }\n return;\n }\n\n // Row exists — repair it. We always overwrite the canonical fields\n // (client_secret, grant_types, response_types, scopes, token_endpoint_auth_method,\n // require_pkce, skip_consent, subject_type, type, disabled) because older code\n // paths may have written rows with missing or wrong-shape values, and\n // re-running the seed should converge to the known-good shape.\n // For redirect_uris we MERGE — re-provisioning a project under an\n // additional hostname should add the new URI without dropping the old one.\n let currentRedirects: string[] = [];\n try {\n const raw = existing.redirect_uris;\n const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;\n if (Array.isArray(parsed)) currentRedirects = parsed.filter((s): s is string => typeof s === 'string');\n } catch { /* malformed JSON — treat as empty */ }\n const mergedRedirects = desiredRedirect && !currentRedirects.includes(desiredRedirect)\n ? [...currentRedirects, desiredRedirect]\n : currentRedirects;\n\n const repairPatch: Record<string, any> = {\n name: existing.name || `Project ${environmentId}`,\n client_secret: clientSecretStored,\n type: existing.type || 'web',\n redirect_uris: JSON.stringify(mergedRedirects),\n grant_types: JSON.stringify(['authorization_code', 'refresh_token']),\n response_types: JSON.stringify(['code']),\n scopes: JSON.stringify(['openid', 'email', 'profile']),\n token_endpoint_auth_method: 'client_secret_basic',\n require_pkce: false,\n skip_consent: true,\n disabled: false,\n subject_type: 'public',\n updated_at: nowIso,\n };\n try {\n await ql.update(\n 'sys_oauth_application',\n repairPatch,\n { where: { id: existing.id } },\n { context: { isSystem: true } },\n );\n logger?.info?.('[platform-sso] sys_oauth_application repaired', {\n environmentId,\n clientId,\n redirect_uris: mergedRedirects,\n });\n } catch (err) {\n logger?.warn?.('[platform-sso] sys_oauth_application repair failed', {\n environmentId,\n error: (err as Error)?.message,\n });\n if (throwOnError) throw err;\n }\n}\n\nexport interface BackfillPlatformSsoClientsOptions {\n ql: SeedPlatformSsoClientOptions['ql'];\n baseSecret: string;\n logger?: { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n /** Hard cap on rows scanned (default: 1000). */\n limit?: number;\n}\n\n/**\n * Scan `sys_environment` and ensure every active project has a corresponding\n * `sys_oauth_application` row. Intended to run once at cloud boot — the\n * happy path is dominated by the project-create hook\n * ({@link seedPlatformSsoClient}); the backfill exists so projects\n * created before this feature shipped also get SSO support without an\n * out-of-band migration.\n */\nexport async function backfillPlatformSsoClients(opts: BackfillPlatformSsoClientsOptions): Promise<{\n scanned: number;\n seeded: number;\n alreadyExisted: number;\n failures: Array<{ environmentId: string; error: string }>;\n}> {\n const { ql, baseSecret, logger, limit = 1000 } = opts;\n if (!baseSecret) {\n logger?.warn?.('[platform-sso] backfill skipped — OS_AUTH_SECRET not set');\n return { scanned: 0, seeded: 0, alreadyExisted: 0, failures: [] };\n }\n let projects: any[] = [];\n try {\n const rows = await ql.find('sys_environment', {\n limit,\n fields: ['id', 'hostname', 'status'],\n }, { context: { isSystem: true } });\n projects = Array.isArray(rows) ? rows : Array.isArray((rows as any)?.records) ? (rows as any).records : [];\n } catch (err) {\n logger?.warn?.('[platform-sso] backfill: sys_environment read failed', {\n error: (err as Error)?.message,\n });\n return { scanned: 0, seeded: 0, alreadyExisted: 0, failures: [{ environmentId: '<scan>', error: (err as Error)?.message ?? String(err) }] };\n }\n let seeded = 0;\n let alreadyExisted = 0;\n const failures: Array<{ environmentId: string; error: string }> = [];\n for (const p of projects) {\n if (!p?.id) continue;\n const before = await (async () => {\n try {\n const r = await ql.find('sys_oauth_application', {\n where: { client_id: derivePlatformSsoClientId(p.id) },\n limit: 1,\n }, { context: { isSystem: true } });\n const list = Array.isArray(r) ? r : Array.isArray((r as any)?.records) ? (r as any).records : [];\n return list[0] ?? null;\n } catch { return null; }\n })();\n try {\n await seedPlatformSsoClient({ ql, environmentId: p.id, hostname: p.hostname, baseSecret, logger, throwOnError: true });\n if (before) alreadyExisted++;\n else {\n // Verify the row is actually readable post-insert.\n const after = await (async () => {\n try {\n const r = await ql.find('sys_oauth_application', {\n where: { client_id: derivePlatformSsoClientId(p.id) },\n limit: 1,\n }, { context: { isSystem: true } });\n const list = Array.isArray(r) ? r : Array.isArray((r as any)?.records) ? (r as any).records : [];\n return list[0] ?? null;\n } catch (err) { return { _readErr: (err as Error)?.message }; }\n })();\n if (after && !(after as any)._readErr) seeded++;\n else failures.push({ environmentId: p.id, error: `post-insert read returned ${after ? JSON.stringify(after) : 'null'}` });\n }\n } catch (err: any) {\n failures.push({ environmentId: p.id, error: err?.message ?? String(err) });\n }\n }\n logger?.info?.('[platform-sso] backfill complete', { scanned: projects.length, seeded, alreadyExisted, failures: failures.length });\n return { scanned: projects.length, seeded, alreadyExisted, failures };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * AuthProxyPlugin\n *\n * Mounts a single `/api/v1/auth/*` wildcard route on the host's Hono server\n * that forwards every request to the per-project `AuthManager` registered\n * by `ArtifactKernelFactory`.\n *\n * Why a dedicated plugin: AuthPlugin (better-auth) registers its routes by\n * grabbing the host's `http-server` service from its own `PluginContext`.\n * In objectos runtime mode AuthPlugin lives on a per-project kernel — it\n * has no access to the host's HTTP server, so its `kernel:ready` route\n * registration is a no-op. The dispatcher plugin's wildcard registration\n * via `IHttpServer.post('/auth/*', …)` proved unreliable in practice,\n * so this plugin uses Hono's raw app directly (same path AuthPlugin took\n * historically) which is rock solid.\n *\n * Routing:\n * 1. Resolve the project from the request hostname via `env-registry`.\n * 2. Acquire the project's kernel via `kernel-manager`.\n * 3. Look up the `auth` service on that kernel — this is the better-auth\n * handler injected by `ArtifactKernelFactory`.\n * 4. Build a Web `Request` using the project's canonical baseUrl and\n * hand it to the better-auth handler.\n * 5. Stream the response back through Hono.\n */\n\nimport type { Plugin, PluginContext } from '@objectstack/core';\nimport { createHmac, randomUUID } from 'node:crypto';\nimport type { KernelManager } from './kernel-manager.js';\nimport type { EnvironmentDriverRegistry } from './environment-registry.js';\n\nconst AUTH_PREFIX = '/api/v1/auth';\n\n/**\n * HMAC-SHA256 + base64 + percent-encode the resulting `value.signature`\n * payload — replicates `serializeSignedCookie` from `better-call` so the\n * env's better-auth `getSignedCookie` validator accepts the cookie we\n * write here (without pulling better-call into runtime's deps).\n */\nfunction signSessionCookieValue(rawToken: string, secret: string): string {\n const signature = createHmac('sha256', secret).update(rawToken).digest('base64');\n return encodeURIComponent(`${rawToken}.${signature}`);\n}\n\n/**\n * Serialize a Set-Cookie header value matching better-auth's session-cookie\n * attributes. Attributes come from `authCookies.sessionToken.attributes`.\n */\nfunction buildSetCookieHeader(\n name: string,\n encodedValue: string,\n attrs: Record<string, any> | undefined,\n maxAgeSec: number,\n): string {\n const parts: string[] = [`${name}=${encodedValue}`];\n const a = attrs ?? {};\n if (a.path) parts.push(`Path=${a.path}`); else parts.push('Path=/');\n if (Number.isFinite(maxAgeSec) && maxAgeSec > 0) parts.push(`Max-Age=${Math.floor(maxAgeSec)}`);\n if (a.domain) parts.push(`Domain=${a.domain}`);\n if (a.sameSite) {\n const ss = String(a.sameSite);\n parts.push(`SameSite=${ss.charAt(0).toUpperCase() + ss.slice(1)}`);\n } else {\n parts.push('SameSite=Lax');\n }\n if (a.secure) parts.push('Secure');\n if (a.httpOnly !== false) parts.push('HttpOnly');\n if (a.partitioned) parts.push('Partitioned');\n return parts.join('; ');\n}\n\n// AuthCapableManager interface removed — unused (pickHandler uses duck typing on `any`).\n\nfunction pickHandler(svc: any): ((req: Request) => Promise<Response>) | undefined {\n if (!svc) return undefined;\n // AuthManager exposes handleRequest(req) — preferred entry point.\n if (typeof svc.handleRequest === 'function') return svc.handleRequest.bind(svc);\n if (typeof svc.handler === 'function') return svc.handler.bind(svc);\n if (svc.api && typeof svc.api.handler === 'function') return svc.api.handler.bind(svc.api);\n // AuthManager keeps the better-auth instance under `auth`.\n if (svc.auth && typeof svc.auth.handler === 'function') return svc.auth.handler.bind(svc.auth);\n return undefined;\n}\n\nasync function resolveAuthHandler(svc: any): Promise<((req: Request) => Promise<Response>) | undefined> {\n const direct = pickHandler(svc);\n if (direct) return direct;\n if (typeof svc?.getApi === 'function') {\n try {\n const api = await svc.getApi();\n return pickHandler(api) ?? pickHandler({ api });\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\nexport class AuthProxyPlugin implements Plugin {\n readonly name = 'com.objectstack.runtime.auth-proxy';\n readonly version = '1.0.0';\n\n init = async (_ctx: PluginContext): Promise<void> => {\n // No services registered — pure HTTP wiring during start().\n };\n\n start = async (ctx: PluginContext): Promise<void> => {\n // Mount routes on kernel:ready so HonoServerPlugin has finished\n // registering the http-server service. Doing this in start() can\n // race with HonoServerPlugin.init/start ordering.\n ctx.hook('kernel:ready', async () => {\n let httpServer: any;\n try {\n httpServer = ctx.getService('http-server');\n } catch {\n ctx.logger?.warn?.('[AuthProxyPlugin] http-server not available — auth routes not mounted');\n return;\n }\n if (!httpServer || typeof httpServer.getRawApp !== 'function') {\n ctx.logger?.warn?.('[AuthProxyPlugin] http-server missing getRawApp() — auth routes not mounted');\n return;\n }\n\n const rawApp = httpServer.getRawApp();\n const kernelManager = ctx.getService<KernelManager>('kernel-manager');\n const envRegistry = ctx.getService<EnvironmentDriverRegistry>('env-registry');\n\n const handler = async (c: any) => {\n try {\n const url = new URL(c.req.url);\n const host = url.hostname;\n let environmentId: string | undefined;\n try {\n const env = await envRegistry.resolveByHostname(host);\n environmentId = env?.environmentId;\n } catch {\n // ignore\n }\n if (!environmentId) {\n return c.json({ error: 'project_not_found', host }, 404);\n }\n\n const projectKernel = await kernelManager.getOrCreate(environmentId);\n let authSvc: any;\n try {\n authSvc = await (projectKernel as any).getServiceAsync?.('auth');\n } catch { authSvc = undefined; }\n if (!authSvc) {\n try { authSvc = (projectKernel as any).getService?.('auth'); } catch { /* ignore */ }\n }\n\n // Custom non-better-auth endpoints. better-auth has no\n // /config or /bootstrap-status route, so without these\n // short-circuits the request would fall through to the\n // better-auth handler and 404. The Account SPA needs\n // /config to render the \"Continue with ObjectStack\"\n // platform SSO button via SocialSignInButtons.\n const subPath = url.pathname.startsWith(AUTH_PREFIX + '/')\n ? url.pathname.substring(AUTH_PREFIX.length + 1)\n : '';\n if (c.req.method === 'GET' && (subPath === 'config' || subPath === 'bootstrap-status')) {\n if (subPath === 'config') {\n try {\n const config = typeof authSvc?.getPublicConfig === 'function'\n ? authSvc.getPublicConfig()\n : null;\n if (config) {\n return c.json({ success: true, data: config });\n }\n return c.json({ success: false, error: { code: 'auth_config_unavailable', message: 'AuthManager has no getPublicConfig()' } }, 503);\n } catch (e: any) {\n return c.json({ success: false, error: { code: 'auth_config_error', message: String(e?.message ?? e) } }, 500);\n }\n }\n // bootstrap-status\n try {\n // Report the real local owner state. Earlier the\n // proxy short-circuited to `hasOwner: true` as\n // soon as the `objectstack-cloud` SSO provider\n // was wired — the idea being \"identity lives in\n // cloud, JIT-create on first SSO callback\". That\n // forced every project to depend on cloud being\n // reachable for first-time setup AND made the\n // local /setup wizard unreachable. With SSO now\n // demoted to an *optional* federation button,\n // bootstrap status MUST reflect the project's\n // own `sys_user` table so /setup can run when\n // there is genuinely no local owner yet.\n const dataEngine = typeof authSvc?.getDataEngine === 'function'\n ? authSvc.getDataEngine()\n : null;\n if (!dataEngine || typeof dataEngine.count !== 'function') {\n return c.json({ hasOwner: true });\n }\n const count = await dataEngine.count('sys_user', {});\n return c.json({ hasOwner: (count ?? 0) > 0 });\n } catch {\n return c.json({ hasOwner: true });\n }\n }\n\n // ── sso-handoff-issue ─────────────────────────────\n // POST /api/v1/auth/sso-handoff-issue\n //\n // Called server-to-server by cloud's `sso_as_owner`\n // action. Cloud control plane (createCloudStack) has\n // no kernel-manager, so it cannot write into the env's\n // better-auth verification table itself — this endpoint\n // does it locally where the env kernel lives.\n //\n // Auth: `Authorization: Bearer <OS_CLOUD_API_KEY>` must\n // match `process.env.OS_CLOUD_API_KEY` on the env\n // runtime. The same secret is shared between cloud and\n // every env runtime (cloud uses it to verify env →\n // cloud calls; we reuse it for the reverse direction).\n //\n // Body: { email, name?, by?, envId? } — payload that\n // sso-exchange will JSON.parse from the verification\n // value. Returns { token, expiresAt, ttlSec }.\n if (c.req.method === 'POST' && subPath === 'sso-handoff-issue') {\n try {\n const expected = (process.env.OS_CLOUD_API_KEY ?? '').trim();\n if (!expected) {\n return c.json({ error: 'sso_handoff_disabled', reason: 'OS_CLOUD_API_KEY unset on env runtime' }, 503);\n }\n const authz = c.req.header('authorization') ?? '';\n const provided = authz.toLowerCase().startsWith('bearer ')\n ? authz.slice(7).trim()\n : '';\n if (!provided || provided !== expected) {\n return c.json({ error: 'unauthorized' }, 401);\n }\n\n if (typeof authSvc?.getAuthContext !== 'function') {\n return c.json({ error: 'auth_service_unavailable' }, 503);\n }\n const handoffAuthCtx: any = await authSvc.getAuthContext();\n const internal = handoffAuthCtx?.internalAdapter;\n if (!internal?.createVerificationValue) {\n return c.json({ error: 'verification_api_unavailable' }, 503);\n }\n\n let body: any = {};\n try { body = await c.req.json(); } catch { body = {}; }\n const email = String(body?.email ?? '').toLowerCase().trim();\n if (!email) return c.json({ error: 'email_required' }, 400);\n const name = body?.name == null ? null : String(body.name);\n const by = body?.by == null ? 'service' : String(body.by);\n const envIdInBody = body?.envId == null ? null : String(body.envId);\n\n const handoff = randomUUID().replace(/-/g, '')\n + randomUUID().replace(/-/g, '');\n const ttlSec = 60;\n const expiresAt = new Date(Date.now() + ttlSec * 1000);\n await internal.createVerificationValue({\n identifier: `sso-handoff:${handoff}`,\n value: JSON.stringify({ email, name, by, envId: envIdInBody ?? environmentId }),\n expiresAt,\n });\n return c.json({\n token: handoff,\n expiresAt: expiresAt.toISOString(),\n ttlSec,\n });\n } catch (err: any) {\n ctx.logger?.error?.('[AuthProxyPlugin] sso-handoff-issue failed', err instanceof Error ? err : new Error(String(err)));\n return c.json({ error: 'sso_handoff_issue_failed', message: String(err?.message ?? err) }, 500);\n }\n }\n\n // ── sso-exchange ───────────────────────────────────\n // GET /api/v1/auth/sso-exchange?token=<handoff>&next=/\n //\n // Consumes a single-use handoff token previously written\n // by the cloud `sso_as_owner` action (via the\n // sso-handoff-issue endpoint above), finds-or-creates\n // the user in the env by email, mints a fresh better-auth\n // session, sets the signed session cookie and 302s to\n // `next`. If the user has no credential account yet, we\n // redirect to /_console/system/profile?recovery_needed=true\n // so they can configure a disaster-recovery local password.\n if (c.req.method === 'GET' && subPath === 'sso-exchange') {\n try {\n const token = (url.searchParams.get('token') ?? '').trim();\n const nextRaw = url.searchParams.get('next') ?? '/';\n const next = nextRaw.startsWith('/') ? nextRaw : '/';\n if (!token) return c.text('missing token', 400);\n\n if (typeof authSvc?.getAuthContext !== 'function') {\n return c.text('auth service unavailable', 503);\n }\n const authCtx: any = await authSvc.getAuthContext();\n const internal = authCtx?.internalAdapter;\n if (!internal?.consumeVerificationValue) {\n return c.text('verification API unavailable', 503);\n }\n\n const consumed = await internal.consumeVerificationValue(`sso-handoff:${token}`);\n if (!consumed) return c.text('invalid or expired token', 401);\n const expiresAt = consumed?.expiresAt ? new Date(consumed.expiresAt).getTime() : 0;\n if (!expiresAt || expiresAt < Date.now()) return c.text('expired token', 401);\n\n let payload: { email?: string; name?: string | null } = {};\n try { payload = JSON.parse(String(consumed.value)); } catch { payload = { email: String(consumed.value) }; }\n const email = String(payload.email ?? '').toLowerCase().trim();\n if (!email) return c.text('handoff missing email', 400);\n\n const found = await internal.findUserByEmail(email, { includeAccounts: true });\n let userId: string | undefined = found?.user?.id;\n let hasCredentialAccount = (found?.accounts ?? []).some((a: any) => a.providerId === 'credential' && a.password);\n\n if (!userId) {\n const created = await internal.createUser({\n email,\n name: payload.name ?? email,\n emailVerified: true,\n });\n userId = created?.id;\n hasCredentialAccount = false;\n }\n if (!userId) return c.text('failed to provision user', 500);\n\n const session = await internal.createSession(userId, false);\n const rawToken: string | undefined = session?.token;\n const sessionExpiresAt = session?.expiresAt ? new Date(session.expiresAt) : new Date(Date.now() + 7 * 24 * 3600 * 1000);\n if (!rawToken) return c.text('failed to mint session', 500);\n\n const secret: string = authCtx?.secret ?? '';\n if (!secret) return c.text('auth secret unavailable', 503);\n const cookieName: string = authCtx?.authCookies?.sessionToken?.name ?? 'better-auth.session_token';\n const cookieAttrs = authCtx?.authCookies?.sessionToken?.attributes ?? {};\n const encoded = signSessionCookieValue(rawToken, secret);\n const maxAgeSec = Math.max(60, Math.floor((sessionExpiresAt.getTime() - Date.now()) / 1000));\n const setCookie = buildSetCookieHeader(cookieName, encoded, cookieAttrs, maxAgeSec);\n\n const finalNext = hasCredentialAccount\n ? next\n : `/_console/system/profile?recovery_needed=true&next=${encodeURIComponent(next)}`;\n const headers = new Headers();\n headers.set('Set-Cookie', setCookie);\n headers.set('Location', finalNext);\n headers.set('Cache-Control', 'no-store');\n return new Response(null, { status: 302, headers });\n } catch (err: any) {\n ctx.logger?.error?.('[AuthProxyPlugin] sso-exchange failed', err instanceof Error ? err : new Error(String(err)));\n return c.text(`sso-exchange failed: ${err?.message ?? String(err)}`, 500);\n }\n }\n\n // ── set-initial-password ────────────────────────────\n // POST /api/v1/auth/set-initial-password { newPassword }\n //\n // The \"Set local password\" affordance the sso-exchange\n // recovery redirect points at. The full AuthPlugin registers\n // this route, but AuthPlugin is skipped on a per-environment\n // runtime, so without this the request falls through to\n // better-auth (no such route) and 404s. Mirrors AuthPlugin's\n // handler against THIS environment's auth context. (#1544)\n if (c.req.method === 'POST' && subPath === 'set-initial-password') {\n try {\n let body: any = {};\n try { body = await c.req.json(); } catch { body = {}; }\n const newPassword: unknown = body?.newPassword;\n if (typeof newPassword !== 'string' || newPassword.length === 0) {\n return c.json({ success: false, error: { code: 'invalid_request', message: 'newPassword is required' } }, 400);\n }\n if (typeof authSvc?.getAuthContext !== 'function') {\n return c.json({ success: false, error: { code: 'unavailable', message: 'Auth context unavailable' } }, 503);\n }\n // Resolve the caller's session on this environment.\n let userId: string | undefined;\n try {\n const api = typeof authSvc.getApi === 'function' ? await authSvc.getApi() : null;\n const session = await api?.getSession?.({ headers: c.req.raw.headers });\n userId = session?.user?.id ? String(session.user.id) : undefined;\n } catch { /* fall through to 401 */ }\n if (!userId) {\n return c.json({ success: false, error: { code: 'unauthorized', message: 'Sign in first' } }, 401);\n }\n const setPwCtx: any = await authSvc.getAuthContext();\n if (!setPwCtx?.internalAdapter || !setPwCtx?.password) {\n return c.json({ success: false, error: { code: 'unavailable', message: 'Auth context unavailable' } }, 503);\n }\n const minLen = setPwCtx.password?.config?.minPasswordLength ?? 8;\n const maxLen = setPwCtx.password?.config?.maxPasswordLength ?? 128;\n if (newPassword.length < minLen) {\n return c.json({ success: false, error: { code: 'password_too_short', message: `Password must be at least ${minLen} characters` } }, 400);\n }\n if (newPassword.length > maxLen) {\n return c.json({ success: false, error: { code: 'password_too_long', message: `Password must be at most ${maxLen} characters` } }, 400);\n }\n const accounts = await setPwCtx.internalAdapter.findAccounts(userId);\n const existingCredential = accounts?.find?.((a: any) => a.providerId === 'credential' && a.password);\n if (existingCredential) {\n return c.json({ success: false, error: { code: 'credential_account_exists', message: 'A local password is already set for this account. Use change-password instead.' } }, 409);\n }\n const passwordHash = await setPwCtx.password.hash(newPassword);\n await setPwCtx.internalAdapter.createAccount({\n userId,\n providerId: 'credential',\n accountId: userId,\n password: passwordHash,\n });\n return c.json({ success: true });\n } catch (err: any) {\n ctx.logger?.error?.('[AuthProxyPlugin] set-initial-password failed', err instanceof Error ? err : new Error(String(err)));\n return c.json({ success: false, error: { code: 'set_password_failed', message: String(err?.message ?? err) } }, 500);\n }\n }\n\n const fn = await resolveAuthHandler(authSvc);\n if (!fn) {\n return c.json({ error: 'auth_service_unavailable', environmentId }, 503);\n }\n\n // Forward the original Web Request directly — better-auth\n // accepts a standard `Request` and returns a `Response`.\n const resp = await fn(c.req.raw);\n\n // ── Cookie-leak cleanup ─────────────────────────────────\n // Cloud previously set OS_COOKIE_DOMAIN=.objectos.ai,\n // which made cloud's better-auth session cookies leak\n // into every *.objectos.ai project subdomain and\n // collide with each project's own session_token.\n // The setting has been removed from cloud, but existing\n // browsers still carry the wide-scoped cookies. Append\n // delete instructions (Max-Age=0 + matching Domain) on\n // every per-project auth response so the leaked cookies\n // get drained on the next auth round-trip. Safe to keep\n // long-term: it only deletes cookies on a parent domain\n // that project containers never legitimately set.\n const rootDomain = process.env.OS_ROOT_DOMAIN || '';\n if (rootDomain) {\n const leakyDomain = rootDomain.startsWith('.') ? rootDomain : `.${rootDomain}`;\n const leakyNames = [\n '__Secure-better-auth.session_token',\n 'better-auth.session_token',\n '__Secure-better-auth.state',\n 'better-auth.state',\n '__Secure-better-auth.csrf_token',\n 'better-auth.csrf_token',\n ];\n try {\n for (const n of leakyNames) {\n const isSecure = n.startsWith('__Secure-');\n const attrs = `Max-Age=0; Path=/; Domain=${leakyDomain}; SameSite=Lax${isSecure ? '; Secure' : ''}`;\n (resp as any).headers?.append?.('Set-Cookie', `${n}=; ${attrs}`);\n }\n } catch { /* best-effort cleanup */ }\n }\n\n return resp;\n } catch (err: any) {\n (ctx.logger?.error as any)?.('[AuthProxyPlugin] auth dispatch failed', {\n error: err?.message,\n stack: err?.stack,\n });\n return c.json({\n error: 'auth_dispatch_failed',\n message: err?.message ?? String(err),\n }, 500);\n }\n };\n\n // Mount on every method via Hono's `all`. AuthPlugin previously\n // registered with `rawApp.all('/api/v1/auth/*', handler)` — same\n // shape here.\n if (typeof rawApp.all === 'function') {\n rawApp.all(`${AUTH_PREFIX}/*`, handler);\n } else {\n for (const m of ['get', 'post', 'put', 'delete', 'patch', 'options'] as const) {\n try { rawApp[m]?.(`${AUTH_PREFIX}/*`, handler); } catch { /* best effort */ }\n }\n }\n ctx.logger?.info?.(`[AuthProxyPlugin] auth proxy mounted at ${AUTH_PREFIX}/*`);\n });\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Shared marketplace / cloud control-plane defaults.\n *\n * Centralised so every plugin + the CLI auto-inject path agree on\n * \"what cloud URL do we mean when the user didn't set OS_CLOUD_URL?\".\n * Until we have a competing public hosted cloud, this points at the\n * ObjectStack-operated control plane so a vanilla `objectstack dev` can\n * browse the marketplace out of the box.\n */\nexport const DEFAULT_CLOUD_URL = 'https://cloud.objectos.ai';\n\n/**\n * Resolve the effective control-plane URL from an explicit constructor\n * value, the OS_CLOUD_URL env var, or the default. Returns an empty\n * string when the caller explicitly disabled cloud with\n * `OS_CLOUD_URL=off` / `local` — callers should treat that as\n * \"marketplace unavailable on this runtime\".\n */\nexport function resolveCloudUrl(explicit?: string | null): string {\n const raw = (explicit ?? process.env.OS_CLOUD_URL ?? '').trim();\n const lower = raw.toLowerCase();\n if (lower === 'off' || lower === 'none' || lower === 'local' || lower === 'disabled') {\n return '';\n }\n const picked = raw || DEFAULT_CLOUD_URL;\n return picked.replace(/\\/+$/, '');\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Marketplace public R2 base URL — when set, points at a Cloudflare R2\n * bucket (custom domain or `pub-*.r2.dev`) that serves pre-rendered\n * marketplace browse + install JSON snapshots. The snapshots are\n * written by ObjectStack Cloud (`packages/service-cloud/src/marketplace-snapshot.ts`).\n *\n * Architecture: cloud writes, tenants read directly from R2 → CDN.\n * Marketplace browse + install never touch the cloud control plane,\n * so Cloud cold-start (~12s) is bypassed entirely and the read path\n * scales to CF's edge capacity for free.\n *\n * Default: when OS_MARKETPLACE_PUBLIC_BASE_URL is unset we skip the\n * public fast-path and fall back to the legacy cloud proxy. Once the\n * R2 bucket public domain is wired up in operations, set\n * `OS_MARKETPLACE_PUBLIC_BASE_URL=https://marketplace.objectos.ai`\n * (or your own custom domain) to enable. Set to \"off\" / \"none\" to\n * explicitly disable even if a default is configured.\n *\n * Path layout under the base URL (matches the snapshot writer):\n * <base>/packages.json\n * <base>/packages/{id}.json\n * <base>/packages/{id}/versions/{versionId}/manifest.json\n * <base>/packages/{id}/versions/latest/manifest.json\n *\n * Each JSON file is already in the same `{ success: true, data: ... }`\n * shape as the corresponding cloud API endpoint, so callers can\n * substitute one for the other transparently.\n */\n\n/**\n * Resolve the effective public marketplace base URL. Returns an empty\n * string when the public fast-path is disabled — callers should fall\n * back to fetching via the cloud control plane.\n */\nexport function resolveMarketplacePublicBaseUrl(explicit?: string | null): string {\n const raw = (explicit ?? process.env.OS_MARKETPLACE_PUBLIC_BASE_URL ?? '').trim();\n const lower = raw.toLowerCase();\n if (!raw || lower === 'off' || lower === 'none' || lower === 'disabled' || lower === 'false') {\n return '';\n }\n return raw.replace(/\\/+$/, '');\n}\n\n/**\n * Map an incoming `/api/v1/marketplace/...` API path to a public R2\n * object key (relative — caller prepends the base URL).\n *\n * Returns `null` when the path is not snapshot-backed. Today three\n * paths are covered (list, detail, manifest); anything else (search\n * with non-trivial filters, install actions, etc.) routes via cloud.\n *\n * Query strings are NOT included in the returned key — R2 is static.\n * Callers that need filtering must fetch the full snapshot and filter\n * client-side.\n */\nexport function publicMarketplaceKeyForApiPath(pathname: string): string | null {\n const prefix = '/api/v1/marketplace/packages';\n if (pathname === prefix) return 'packages.json';\n if (!pathname.startsWith(`${prefix}/`)) return null;\n const tail = pathname.slice(prefix.length + 1);\n if (!tail) return null;\n const parts = tail.split('/');\n // /packages/{id}\n if (parts.length === 1) {\n const id = decodeURIComponent(parts[0] ?? '');\n if (!id) return null;\n return `packages/${encodeURIComponent(id)}.json`;\n }\n // /packages/{id}/versions/{versionId}/manifest\n if (parts.length === 4 && parts[1] === 'versions' && parts[3] === 'manifest') {\n const id = decodeURIComponent(parts[0] ?? '');\n const versionId = decodeURIComponent(parts[2] ?? '');\n if (!id || !versionId) return null;\n return `packages/${encodeURIComponent(id)}/versions/${encodeURIComponent(versionId)}/manifest.json`;\n }\n return null;\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * MarketplaceProxyPlugin\n *\n * Forwards `GET /api/v1/marketplace/*` from a tenant ObjectOS runtime to\n * the configured ObjectStack Cloud control-plane URL. The cloud endpoint\n * is unauthenticated and only exposes packages whose owner has opted in\n * to the public catalog (`sys_package.marketplace_listed = true`) — so the\n * proxy passes through without any credentials.\n *\n * Why proxy instead of direct browser → cloud:\n * - The Console SPA stays on the tenant origin, so no CORS configuration\n * is required on the cloud side.\n * - Local-dev `os serve` works regardless of whether the developer's\n * browser has cookies for cloud.objectos.ai.\n * - Adds a single, easily auditable network seam between tenant and\n * control plane.\n *\n * Install is NOT proxied here. Installing a package mutates control-plane\n * state and requires a cloud session + active organization context — the\n * Console SPA performs install by opening the cloud's install dialog in a\n * new tab so the user authenticates against cloud directly. A future\n * iteration may introduce a delegated install token; until then, browse\n * here and install on cloud.\n */\n\nimport type { Plugin, PluginContext } from '@objectstack/core';\nimport { resolveCloudUrl } from './cloud-url.js';\nimport {\n resolveMarketplacePublicBaseUrl,\n publicMarketplaceKeyForApiPath,\n} from './marketplace-public-url.js';\n\nconst MARKETPLACE_PREFIX = '/api/v1/marketplace';\n\n/**\n * In-memory cache for GET/HEAD marketplace responses.\n *\n * Marketplace data changes infrequently (new package versions are\n * audited & published in ~hours, not seconds), so we cache aggressively\n * with conditional revalidation:\n *\n * - listing/search → 30 min hard TTL\n * - package detail → 2 h\n * - version detail /\n * readme / assets → 24 h (versions are immutable once published)\n *\n * After TTL expiry the next request issues an `If-None-Match` /\n * `If-Modified-Since` and, on `304 Not Modified`, simply refreshes the\n * TTL without re-downloading the body.\n *\n * Bypass conditions (always re-fetch, no cache write):\n * - `OS_MARKETPLACE_CACHE=off`\n * - Request header `Cache-Control: no-cache` (the Console SPA's\n * \"Refresh\" button sets this)\n * - Non-2xx upstream responses (avoid pinning transient errors)\n *\n * Every response carries `X-Cache: HIT|REVALIDATED|MISS|BYPASS` to make\n * the layer observable in browser devtools.\n */\nconst DEFAULT_LRU_MAX = 200;\nconst LIST_TTL_MS = 30 * 60 * 1000; // 30 min\nconst PACKAGE_TTL_MS = 2 * 60 * 60 * 1000; // 2 h\nconst VERSION_TTL_MS = 24 * 60 * 60 * 1000; // 24 h\n\ninterface CacheEntry {\n status: number;\n body: ArrayBuffer;\n headers: Record<string, string>;\n etag?: string;\n lastModified?: string;\n expiresAt: number;\n ttlMs: number;\n}\n\nfunction ttlForPath(pathname: string): number {\n // `/api/v1/marketplace/packages/:id/versions/:v(.../...)?` → 24h\n if (/\\/packages\\/[^/]+\\/versions\\//.test(pathname)) return VERSION_TTL_MS;\n // `/api/v1/marketplace/packages/:id(/readme)?` → 2h\n if (/\\/packages\\/[^/]+/.test(pathname)) return PACKAGE_TTL_MS;\n // Listings, search, categories, anything else → 30 min\n return LIST_TTL_MS;\n}\n\nclass LruTtlCache {\n private readonly map = new Map<string, CacheEntry>();\n constructor(private readonly max: number) {}\n\n get(key: string): CacheEntry | undefined {\n const entry = this.map.get(key);\n if (!entry) return undefined;\n // LRU touch: re-insert to move to end.\n this.map.delete(key);\n this.map.set(key, entry);\n return entry;\n }\n\n set(key: string, entry: CacheEntry): void {\n if (this.map.has(key)) this.map.delete(key);\n this.map.set(key, entry);\n while (this.map.size > this.max) {\n const oldest = this.map.keys().next().value;\n if (oldest === undefined) break;\n this.map.delete(oldest);\n }\n }\n\n clear(): void {\n this.map.clear();\n }\n}\n\nexport interface MarketplaceProxyPluginConfig {\n /**\n * Control-plane base URL (e.g. https://cloud.objectos.ai). When the\n * caller passes nothing AND the runtime has no OS_CLOUD_URL set, the\n * plugin falls back to the public ObjectStack-operated cloud so that\n * `objectstack dev` can browse the marketplace out of the box. Set\n * OS_CLOUD_URL=off (or `local`) to opt out — the plugin then mounts\n * a stub that responds 503 and the SPA renders an empty-state\n * explaining marketplace is unavailable in this runtime.\n */\n controlPlaneUrl?: string;\n\n /**\n * Disable the in-memory response cache (testing / debugging).\n * Defaults to the value of `OS_MARKETPLACE_CACHE` (anything in\n * {\"off\",\"false\",\"0\",\"no\"} disables).\n */\n cacheDisabled?: boolean;\n\n /**\n * Override the LRU upper bound. Defaults to 200 entries.\n */\n cacheMaxEntries?: number;\n /**\n * Public R2 base URL for marketplace snapshots. When set, GETs for\n * snapshot-backed paths (`/packages`, `/packages/:id`,\n * `/packages/:id/versions/:vid/manifest`) are fetched directly from\n * R2 (CF edge) — bypassing the cloud control plane entirely.\n * Defaults to the value of OS_MARKETPLACE_PUBLIC_BASE_URL. Empty\n * string disables the public fast-path (legacy cloud-proxy only).\n */\n publicMarketplaceBaseUrl?: string;\n}\n\nexport class MarketplaceProxyPlugin implements Plugin {\n readonly name = 'com.objectstack.runtime.marketplace-proxy';\n readonly version = '1.1.0';\n\n private readonly cloudUrl: string;\n private readonly publicBaseUrl: string;\n private readonly cache: LruTtlCache | null;\n\n constructor(config: MarketplaceProxyPluginConfig = {}) {\n this.cloudUrl = resolveCloudUrl(config.controlPlaneUrl);\n this.publicBaseUrl = resolveMarketplacePublicBaseUrl(config.publicMarketplaceBaseUrl);\n\n const envFlag = (process.env.OS_MARKETPLACE_CACHE ?? '').trim().toLowerCase();\n const envDisabled = ['off', 'false', '0', 'no', 'disable', 'disabled'].includes(envFlag);\n const disabled = config.cacheDisabled ?? envDisabled;\n this.cache = disabled\n ? null\n : new LruTtlCache(Math.max(8, config.cacheMaxEntries ?? DEFAULT_LRU_MAX));\n }\n\n init = async (_ctx: PluginContext): Promise<void> => {\n // No services registered — pure HTTP wiring during start().\n };\n\n start = async (ctx: PluginContext): Promise<void> => {\n ctx.hook('kernel:ready', async () => {\n let httpServer: any;\n try {\n httpServer = ctx.getService('http-server');\n } catch {\n ctx.logger?.warn?.('[MarketplaceProxyPlugin] http-server not available — marketplace routes not mounted');\n return;\n }\n if (!httpServer || typeof httpServer.getRawApp !== 'function') {\n ctx.logger?.warn?.('[MarketplaceProxyPlugin] http-server missing getRawApp() — marketplace routes not mounted');\n return;\n }\n\n const rawApp = httpServer.getRawApp();\n const cloudUrl = this.cloudUrl;\n const publicBaseUrl = this.publicBaseUrl;\n const cache = this.cache;\n\n if (publicBaseUrl) {\n ctx.logger?.info?.(`[MarketplaceProxyPlugin] public R2 fast-path enabled → ${publicBaseUrl}`);\n }\n\n const handler = async (c: any, next: any) => {\n if (!cloudUrl) {\n return c.json({\n success: false,\n error: {\n code: 'marketplace_unavailable',\n message: 'No control-plane URL configured for this runtime (OS_CLOUD_URL).',\n },\n }, 503);\n }\n try {\n const incomingUrl = new URL(c.req.url);\n // Do NOT proxy install-local — those are owned by\n // MarketplaceInstallLocalPlugin and must hit this\n // runtime, never cloud. Pass through so Hono can match\n // the install-local route registered on the same app.\n if (incomingUrl.pathname.startsWith(`${MARKETPLACE_PREFIX}/install-local`)) {\n return next();\n }\n\n const method = String(c.req.method ?? 'GET').toUpperCase();\n\n // ── Public R2 fast-path ─────────────────────────\n // When OS_MARKETPLACE_PUBLIC_BASE_URL is configured,\n // GETs for snapshot-backed paths fetch directly from\n // R2 → CF edge cache. This skips the cloud control\n // plane entirely so marketplace browse + install\n // work even when cloud is asleep or completely down.\n if (publicBaseUrl && (method === 'GET' || method === 'HEAD')) {\n const r2Resp = await tryPublicMarketplaceFetch(\n publicBaseUrl, incomingUrl, method, c.req.header('accept'),\n ctx.logger,\n );\n if (r2Resp) return r2Resp;\n // Fall through on miss / error to the cloud path.\n }\n\n // Preserve the full /api/v1/marketplace/... path on cloud.\n const target = `${cloudUrl}${incomingUrl.pathname}${incomingUrl.search}`;\n\n // Forward only safe, idempotent methods. We intentionally\n // do NOT proxy POST / PUT / DELETE here — those would\n // need credentialled cloud auth which the tenant runtime\n // does not carry.\n if (method !== 'GET' && method !== 'HEAD') {\n return c.json({\n success: false,\n error: {\n code: 'marketplace_method_not_allowed',\n message: `Marketplace proxy only forwards GET/HEAD; install via cloud.`,\n },\n }, 405);\n }\n\n // Cache lookup. Key includes accept-language because\n // cloud may serve locale-specific copy in the future;\n // HEAD shares the cache slot with GET (we just elide the\n // body in the response).\n const accept = c.req.header('accept') ?? 'application/json';\n const acceptLang = c.req.header('accept-language') ?? '';\n const cacheKey = `${incomingUrl.pathname}${incomingUrl.search}|al=${acceptLang}|a=${accept}`;\n const reqCacheCtl = (c.req.header('cache-control') ?? '').toLowerCase();\n const bypass = !cache || reqCacheCtl.includes('no-cache') || reqCacheCtl.includes('no-store');\n const now = Date.now();\n\n if (cache && !bypass) {\n const hit = cache.get(cacheKey);\n if (hit && hit.expiresAt > now) {\n return buildCachedResponse(hit, method, 'HIT');\n }\n if (hit) {\n // TTL expired — try conditional revalidate so we\n // don't pay for the body when nothing changed.\n const revalHeaders: Record<string, string> = {\n 'Accept': accept,\n 'User-Agent': `objectos-marketplace-proxy/${MarketplaceProxyPlugin.prototype.version ?? '1.0.0'}`,\n };\n if (acceptLang) revalHeaders['Accept-Language'] = acceptLang;\n if (hit.etag) revalHeaders['If-None-Match'] = hit.etag;\n if (hit.lastModified) revalHeaders['If-Modified-Since'] = hit.lastModified;\n const revalResp = await fetch(target, { method: 'GET', headers: revalHeaders });\n if (revalResp.status === 304) {\n hit.expiresAt = now + hit.ttlMs;\n // Refresh ETag/Last-Modified if the upstream\n // re-issued them on the 304 (per RFC 7232 §4.1).\n const newEtag = revalResp.headers.get('etag');\n const newLm = revalResp.headers.get('last-modified');\n if (newEtag) hit.etag = newEtag;\n if (newLm) hit.lastModified = newLm;\n cache.set(cacheKey, hit);\n return buildCachedResponse(hit, method, 'REVALIDATED');\n }\n // 200 (or anything else): fall through to the\n // normal fetch+store path below, using the\n // revalidation response we already have in hand.\n return await consumeAndMaybeCache(revalResp, cacheKey, incomingUrl.pathname, method, cache);\n }\n }\n\n // MISS (or BYPASS): origin fetch.\n const reqHeaders: Record<string, string> = {\n // Strip the inbound Host header — fetch will set\n // it to the cloud host. Forward only the\n // identifying headers cloud might log.\n 'Accept': accept,\n 'User-Agent': `objectos-marketplace-proxy/${MarketplaceProxyPlugin.prototype.version ?? '1.0.0'}`,\n };\n if (acceptLang) reqHeaders['Accept-Language'] = acceptLang;\n const resp = await fetch(target, { method: 'GET', headers: reqHeaders });\n\n if (bypass || !cache) {\n // Don't write to cache; just stream back.\n return await passthroughResponse(resp, method, bypass ? 'BYPASS' : 'MISS');\n }\n return await consumeAndMaybeCache(resp, cacheKey, incomingUrl.pathname, method, cache);\n } catch (err: any) {\n const errObj = err instanceof Error ? err : new Error(err?.message ?? String(err));\n ctx.logger?.error?.('[MarketplaceProxyPlugin] proxy failed', errObj);\n return c.json({\n success: false,\n error: {\n code: 'marketplace_proxy_failed',\n message: err?.message ?? String(err),\n },\n }, 502);\n }\n };\n\n if (typeof rawApp.all === 'function') {\n rawApp.all(`${MARKETPLACE_PREFIX}/*`, handler);\n } else {\n for (const m of ['get', 'head'] as const) {\n try { rawApp[m]?.(`${MARKETPLACE_PREFIX}/*`, handler); } catch { /* best effort */ }\n }\n }\n\n ctx.logger?.info?.(`[MarketplaceProxyPlugin] mounted at ${MARKETPLACE_PREFIX}/* → ${cloudUrl || '(unconfigured)'} (cache=${this.cache ? 'on' : 'off'})`);\n });\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public R2 fast-path (module-private)\n// ---------------------------------------------------------------------------\n\n/**\n * Fetch a marketplace API path from the public R2 base URL and return\n * the response shaped exactly like the cloud API endpoint would. The\n * snapshots are already in `{ success: true, data: ... }` shape so for\n * direct lookups we stream bytes verbatim. The list endpoint applies\n * query-string filters (q / category / limit / offset) client-side\n * from the full snapshot.\n *\n * Returns `null` for any of:\n * - path is not snapshot-backed (e.g. featured / categories / etc.)\n * - R2 returned 404 (snapshot not yet generated for this id)\n * - network error fetching from R2\n *\n * On `null`, the caller falls back to the cloud proxy path.\n */\nasync function tryPublicMarketplaceFetch(\n publicBaseUrl: string,\n incomingUrl: URL,\n method: string,\n acceptHeader: string | undefined,\n logger: any,\n): Promise<Response | null> {\n const key = publicMarketplaceKeyForApiPath(incomingUrl.pathname);\n if (!key) return null;\n\n const target = `${publicBaseUrl}/${key}`;\n let resp: Response;\n try {\n resp = await fetch(target, {\n method: 'GET',\n headers: {\n 'Accept': acceptHeader || 'application/json',\n 'User-Agent': `objectos-marketplace-proxy/public-r2`,\n },\n });\n } catch (err: any) {\n logger?.warn?.(`[MarketplaceProxyPlugin] public R2 fetch failed (${target}): ${err?.message ?? err}`);\n return null;\n }\n if (resp.status === 404) return null;\n if (!resp.ok) {\n logger?.warn?.(`[MarketplaceProxyPlugin] public R2 ${target} returned ${resp.status} — falling back to cloud`);\n return null;\n }\n\n // List endpoint: apply optional q/category/limit/offset filters on\n // the full snapshot. Detail + manifest snapshots stream verbatim.\n const isList = key === 'packages.json';\n const hasFilters = isList && (\n incomingUrl.searchParams.has('q') ||\n incomingUrl.searchParams.has('category') ||\n incomingUrl.searchParams.has('limit') ||\n incomingUrl.searchParams.has('offset')\n );\n\n if (!hasFilters) {\n // Verbatim passthrough — preserve cache headers from R2 / CF.\n const headers = new Headers();\n const ct = resp.headers.get('content-type') ?? 'application/json; charset=utf-8';\n headers.set('content-type', ct);\n const cc = resp.headers.get('cache-control');\n if (cc) headers.set('cache-control', cc);\n const etag = resp.headers.get('etag');\n if (etag) headers.set('etag', etag);\n headers.set('x-cache', 'PUBLIC-R2');\n const body = method === 'HEAD' ? null : resp.body;\n return new Response(body, { status: 200, headers });\n }\n\n // Filtered list — parse, filter, re-serialize.\n let snapshot: any;\n try { snapshot = await resp.json(); }\n catch (err: any) {\n logger?.warn?.(`[MarketplaceProxyPlugin] public R2 list snapshot parse failed: ${err?.message ?? err}`);\n return null;\n }\n const items: any[] = Array.isArray(snapshot?.data?.items) ? snapshot.data.items : [];\n\n const q = (incomingUrl.searchParams.get('q') ?? '').trim().toLowerCase();\n const category = (incomingUrl.searchParams.get('category') ?? '').trim();\n const limit = Math.min(Math.max(Number(incomingUrl.searchParams.get('limit') ?? 50), 1), 100);\n const offset = Math.max(Number(incomingUrl.searchParams.get('offset') ?? 0), 0);\n\n let filtered = items;\n if (q) {\n filtered = filtered.filter((r) => {\n const dn = String(r?.display_name ?? '').toLowerCase();\n const mid = String(r?.manifest_id ?? '').toLowerCase();\n return dn.includes(q) || mid.includes(q);\n });\n }\n if (category) {\n filtered = filtered.filter((r) => String(r?.category ?? '') === category);\n }\n const total = filtered.length;\n const page = filtered.slice(offset, offset + limit);\n const body = JSON.stringify({ success: true, data: { items: page, total, limit, offset } });\n\n const headers = new Headers({\n 'content-type': 'application/json; charset=utf-8',\n 'cache-control': 'public, max-age=30',\n 'x-cache': 'PUBLIC-R2-FILTERED',\n });\n return new Response(method === 'HEAD' ? null : body, { status: 200, headers });\n}\n\n// ---------------------------------------------------------------------------\n// Cache helpers (module-private)\n// ---------------------------------------------------------------------------\n\nconst PASSTHROUGH_HEADERS = ['content-type', 'cache-control', 'etag', 'last-modified', 'vary'] as const;\n\nfunction collectHeaders(src: Response): Record<string, string> {\n const out: Record<string, string> = {};\n for (const h of PASSTHROUGH_HEADERS) {\n const v = src.headers.get(h);\n if (v) out[h] = v;\n }\n return out;\n}\n\nfunction buildCachedResponse(entry: CacheEntry, method: string, xCache: 'HIT' | 'REVALIDATED'): Response {\n const headers = new Headers(entry.headers);\n headers.set('X-Cache', xCache);\n // Surface remaining freshness so downstream HTTP caches / devtools\n // can reason about it (clamped at 0).\n const ageSec = Math.max(0, Math.floor((entry.expiresAt - entry.ttlMs - Date.now()) / -1000));\n headers.set('Age', String(Math.max(0, ageSec)));\n const body = method === 'HEAD' ? null : entry.body;\n return new Response(body, { status: entry.status, headers });\n}\n\nasync function passthroughResponse(resp: Response, method: string, xCache: 'MISS' | 'BYPASS'): Promise<Response> {\n const headers = new Headers(collectHeaders(resp));\n headers.set('X-Cache', xCache);\n if (method === 'HEAD') {\n // Drain to release the connection.\n try { await resp.arrayBuffer(); } catch { /* ignore */ }\n return new Response(null, { status: resp.status, headers });\n }\n const body = await resp.arrayBuffer();\n return new Response(body, { status: resp.status, headers });\n}\n\nasync function consumeAndMaybeCache(\n resp: Response,\n key: string,\n pathname: string,\n method: string,\n cache: LruTtlCache,\n): Promise<Response> {\n const body = await resp.arrayBuffer();\n const headers = collectHeaders(resp);\n // Only cache success responses — pinning a 404 / 5xx would just\n // amplify a transient failure.\n if (resp.status >= 200 && resp.status < 300) {\n const ttlMs = ttlForPath(pathname);\n const entry: CacheEntry = {\n status: resp.status,\n body,\n headers,\n etag: resp.headers.get('etag') ?? undefined,\n lastModified: resp.headers.get('last-modified') ?? undefined,\n expiresAt: Date.now() + ttlMs,\n ttlMs,\n };\n cache.set(key, entry);\n }\n const respHeaders = new Headers(headers);\n respHeaders.set('X-Cache', 'MISS');\n const outBody = method === 'HEAD' ? null : body;\n return new Response(outBody, { status: resp.status, headers: respHeaders });\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * RuntimeConfigPlugin\n *\n * Serves `GET /api/v1/runtime/config` (and the legacy alias\n * `GET /api/v1/studio/runtime-config`) from a tenant ObjectOS runtime so\n * the Console / Studio SPA can learn the upstream cloud URL and capability\n * flags **at boot time**, instead of sniffing `window.location.hostname`\n * or reading Vite-time env vars.\n *\n * Response shape (mirrors cloud's `createStudioRuntimeConfigPlugin`):\n *\n * {\n * cloudUrl: string, // base URL of the upstream cloud\n * singleEnvironment: false, // multi-tenant runtime\n * features: {\n * installLocal: boolean, // false here — install-local is owned\n * // by CLI `serve` (single-tenant), not\n * // by createObjectOSStack\n * marketplace: boolean, // true — MarketplaceProxyPlugin mounts\n * // /api/v1/marketplace/*\n * }\n * }\n *\n * Registers its routes on the Hono raw app, parallel to MarketplaceProxy /\n * AuthProxy / MarketplaceInstallLocal plugins.\n */\n\nimport type { Plugin, PluginContext } from '@objectstack/core';\nimport { resolveCloudUrl } from './cloud-url.js';\n\nexport interface RuntimeConfigPluginConfig {\n /**\n * Upstream cloud base URL. Falls back to `resolveCloudUrl()` (reads\n * `OS_CLOUD_URL` / built-in default) when omitted. Pass an explicit\n * empty string to declare \"this runtime IS the cloud\" (same-origin\n * for marketplace + install).\n */\n controlPlaneUrl?: string;\n /** Override the `features.installLocal` flag. Default: false. */\n installLocal?: boolean;\n /**\n * Report this runtime as a single-environment deployment (CLI\n * `objectstack dev` / `os serve`). Defaults to `false` for\n * multi-tenant ObjectOS.\n */\n singleEnvironment?: boolean;\n /**\n * Product name shown in browser title, splash screen, and other\n * client chrome. Operators can override per-deployment (white-label,\n * regional rebrands). Falls back to `OS_PRODUCT_NAME` env var, then\n * to the default `'ObjectOS'`.\n */\n productName?: string;\n /** Short product name (PWA shortName, compact spots). Defaults to productName. */\n productShortName?: string;\n}\n\nexport class RuntimeConfigPlugin implements Plugin {\n readonly name = 'com.objectstack.runtime.runtime-config';\n readonly version = '1.0.0';\n\n private readonly cloudUrl: string;\n private readonly installLocal: boolean;\n private readonly singleEnvironment: boolean;\n private readonly productName: string;\n private readonly productShortName: string;\n\n constructor(config: RuntimeConfigPluginConfig = {}) {\n // An explicit empty string means \"stay on this origin\" — bypass the\n // resolver which would otherwise fall back to the default cloud URL.\n this.cloudUrl = config.controlPlaneUrl === ''\n ? ''\n : (resolveCloudUrl(config.controlPlaneUrl) ?? '');\n this.installLocal = !!config.installLocal;\n this.singleEnvironment = !!config.singleEnvironment;\n const envName = (typeof process !== 'undefined' ? process.env?.OS_PRODUCT_NAME : undefined)?.trim();\n const envShort = (typeof process !== 'undefined' ? process.env?.OS_PRODUCT_SHORT_NAME : undefined)?.trim();\n this.productName = (config.productName ?? envName ?? 'ObjectOS').trim() || 'ObjectOS';\n this.productShortName = (config.productShortName ?? envShort ?? this.productName).trim() || this.productName;\n }\n\n init = async (_ctx: PluginContext): Promise<void> => {};\n\n start = async (ctx: PluginContext): Promise<void> => {\n ctx.hook('kernel:ready', async () => {\n let httpServer: any;\n try {\n httpServer = ctx.getService('http-server');\n } catch {\n ctx.logger?.warn?.('[RuntimeConfigPlugin] http-server not available — runtime/config not mounted');\n return;\n }\n if (!httpServer || typeof httpServer.getRawApp !== 'function') {\n ctx.logger?.warn?.('[RuntimeConfigPlugin] http-server missing getRawApp() — runtime/config not mounted');\n return;\n }\n const rawApp = httpServer.getRawApp();\n\n // The tenant runtime is multi-tenant: one process serves many\n // subdomains, each mapped to one sys_environment row. Telling the\n // SPA *which* environment it is attached to (per-request) lets\n // the App Marketplace skip the env-picker dialog and install\n // directly into \"this\" env — the operator's domain already\n // identifies it.\n //\n // Hostname → env is resolved by the same registry the per-env\n // kernel router uses (env-registry). Falls back to the static\n // payload when the host doesn't map to any env (e.g. a\n // marketing root, a CLI-served single-env runtime, or\n // cloud.objectos.ai which mounts its own static handler).\n const features = {\n installLocal: this.installLocal,\n marketplace: true,\n };\n let envRegistry: any = null;\n try { envRegistry = ctx.getService('env-registry'); } catch { /* not mounted (file/CLI mode) */ }\n\n const handler = async (c: any) => {\n const rawHost = c.req.header('host') ?? '';\n const host = rawHost.split(':')[0].toLowerCase().trim();\n let defaultEnvironmentId: string | undefined;\n let defaultOrgId: string | undefined;\n let resolvedSingleEnv = this.singleEnvironment;\n // EnvironmentDriverRegistry exposes `resolveByHostname()`;\n // older code paths used `resolveHostname()` on the client.\n // Accept either so production runtimes (which register the\n // ArtifactEnvironmentRegistry implementing `resolveByHostname`)\n // don't silently no-op and leave the SPA showing the env\n // picker on per-subdomain pages.\n const resolveFn: ((h: string) => Promise<any>) | null =\n typeof envRegistry?.resolveByHostname === 'function'\n ? envRegistry.resolveByHostname.bind(envRegistry)\n : typeof envRegistry?.resolveHostname === 'function'\n ? envRegistry.resolveHostname.bind(envRegistry)\n : null;\n if (resolveFn && host) {\n try {\n const resolved = await resolveFn(host);\n if (resolved?.environmentId) {\n defaultEnvironmentId = String(resolved.environmentId);\n const orgId = resolved.organizationId ?? resolved.organization_id;\n if (orgId) defaultOrgId = String(orgId);\n // Each subdomain is one environment from the\n // operator's POV: surface as single-environment\n // so the SPA hides multi-env affordances.\n resolvedSingleEnv = true;\n }\n } catch {\n // Resolver failures are non-fatal — fall through\n // to the static payload so /runtime/config never\n // 500s. Worst case the SPA shows its env picker.\n }\n }\n return c.json({\n cloudUrl: this.cloudUrl,\n singleEnvironment: resolvedSingleEnv,\n defaultOrgId,\n defaultEnvironmentId,\n features,\n branding: {\n productName: this.productName,\n productShortName: this.productShortName,\n },\n });\n };\n rawApp.get('/api/v1/runtime/config', handler);\n // Legacy alias for older Studio bundles.\n rawApp.get('/api/v1/studio/runtime-config', handler);\n ctx.logger?.info?.('[RuntimeConfigPlugin] mounted /api/v1/runtime/config', {\n cloudUrl: this.cloudUrl || '(empty)',\n installLocal: this.installLocal,\n perHostEnvResolution: !!envRegistry,\n });\n });\n };\n\n destroy = async (): Promise<void> => {};\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * File-backed ArtifactApiClient.\n *\n * A drop-in replacement for {@link ArtifactApiClient} that reads a\n * single project's compiled artifact from a local JSON file instead of\n * an HTTP control plane. Intended for:\n *\n * - `pnpm dev` workflows where standing up a full `apps/cloud`\n * instance to host one artifact is overkill.\n * - Smoke tests / CI that need a hermetic objectos boot.\n * - Single-tenant self-hosted deployments that ship one artifact\n * baked into the container image.\n *\n * Hostname resolution is the identity function: every host resolves\n * to the same `environmentId`. The runtime config (database URL +\n * driver) is synthesised from the artifact's default datasource,\n * matching what the cloud API would mint for a project whose\n * developer declared an inline datasource in `defineStack()`.\n *\n * Public API mirrors {@link ArtifactApiClient} so callers can swap\n * implementations transparently.\n */\n\nimport { readFile, stat } from 'node:fs/promises';\nimport { resolve as resolvePath } from 'node:path';\nimport type {\n EnvironmentArtifactResponse,\n EnvironmentRuntimeConfig,\n ResolvedHostname,\n} from './artifact-api-client.js';\n\nexport interface FileArtifactApiClientConfig {\n /**\n * Path to a compiled artifact JSON file (`dist/objectstack.json`).\n * Resolved against `process.cwd()` when relative. Defaults to\n * `<cwd>/dist/objectstack.json`.\n */\n artifactPath?: string;\n /**\n * Project id every hostname maps to. Defaults to\n * `process.env.OS_ENVIRONMENT_ID` or `'proj_local'`.\n */\n environmentId?: string;\n /**\n * Organization id surfaced alongside the project. Defaults to\n * `process.env.OS_ORGANIZATION_ID` or `'org_local'`.\n */\n organizationId?: string;\n /**\n * Override runtime config. When unset, the client tries to derive\n * one from the artifact's `datasources` array; if that fails it\n * falls back to a local-file SQLite DB at\n * `<cwd>/.objectstack/data/<environmentId>.db`.\n */\n runtime?: EnvironmentRuntimeConfig;\n /**\n * Reload the artifact on every fetch instead of caching the first\n * read. Useful when iterating on a project's metadata without\n * restarting objectos. Defaults to `true` for dev ergonomics.\n */\n watch?: boolean;\n /** Optional logger. */\n logger?: { info?: (...a: any[]) => void; warn?: (...a: any[]) => void; error?: (...a: any[]) => void };\n}\n\nexport class FileArtifactApiClient {\n private readonly artifactPath: string;\n private readonly environmentId: string;\n private readonly organizationId: string;\n private readonly overrideRuntime?: EnvironmentRuntimeConfig;\n private readonly watch: boolean;\n private readonly logger: NonNullable<FileArtifactApiClientConfig['logger']>;\n\n private cached?: { mtimeMs: number; response: EnvironmentArtifactResponse };\n\n constructor(config: FileArtifactApiClientConfig = {}) {\n const cwd = process.cwd();\n this.artifactPath = resolvePath(\n cwd,\n config.artifactPath\n ?? process.env.OS_ARTIFACT_PATH\n ?? 'dist/objectstack.json',\n );\n this.environmentId = config.environmentId\n ?? process.env.OS_ENVIRONMENT_ID\n ?? 'proj_local';\n this.organizationId = config.organizationId\n ?? process.env.OS_ORGANIZATION_ID\n ?? 'org_local';\n this.overrideRuntime = config.runtime;\n this.watch = config.watch ?? true;\n this.logger = config.logger ?? console;\n }\n\n async resolveHostname(_host: string): Promise<ResolvedHostname | null> {\n // Single-project mode: every host maps to the one configured project.\n const runtime = this.overrideRuntime ?? (await this.readRuntimeFromArtifact());\n return {\n environmentId: this.environmentId,\n organizationId: this.organizationId,\n ...(runtime ? { runtime } : {}),\n };\n }\n\n async fetchArtifact(_environmentId: string, _opts?: { commit?: string }): Promise<EnvironmentArtifactResponse | null> {\n return this.loadArtifact();\n }\n\n async lookupProjectByShortId(_shortId: string): Promise<{ environmentId: string; organizationId?: string } | null> {\n return { environmentId: this.environmentId, organizationId: this.organizationId };\n }\n\n async fetchBranchHead(\n _environmentId: string,\n _branchName: string,\n ): Promise<{ commitId: string; publishedAt?: string | null } | null> {\n const artifact = await this.loadArtifact();\n return artifact\n ? { commitId: artifact.commitId ?? 'local', publishedAt: null }\n : null;\n }\n\n invalidate(_environmentId: string): void {\n this.cached = undefined;\n }\n\n clear(): void {\n this.cached = undefined;\n }\n\n private async loadArtifact(): Promise<EnvironmentArtifactResponse | null> {\n try {\n const stats = await stat(this.artifactPath);\n const mtimeMs = stats.mtimeMs;\n if (!this.watch && this.cached) return this.cached.response;\n if (this.cached && this.cached.mtimeMs === mtimeMs) return this.cached.response;\n\n const raw = await readFile(this.artifactPath, 'utf8');\n const parsed = JSON.parse(raw);\n // The compiled JSON may already be a `EnvironmentArtifact` envelope\n // (with a `metadata` block) or a bare bundle. Wrap when needed.\n const isEnvelope = parsed && typeof parsed === 'object'\n && typeof parsed.metadata === 'object'\n && parsed.metadata !== null;\n const metadata = isEnvelope ? parsed.metadata : parsed;\n const runtime = this.overrideRuntime\n ?? (isEnvelope ? parsed.runtime : undefined)\n ?? this.deriveRuntimeFromMetadata(metadata)\n ?? this.defaultLocalSqliteRuntime();\n const response: EnvironmentArtifactResponse = {\n schemaVersion: parsed.schemaVersion ?? '1',\n environmentId: parsed.environmentId ?? this.environmentId,\n commitId: parsed.commitId ?? 'local',\n checksum: parsed.checksum ?? '',\n publishedAt: parsed.publishedAt ?? new Date().toISOString(),\n metadata,\n functions: parsed.functions,\n manifest: parsed.manifest,\n runtime: {\n organizationId: this.organizationId,\n ...runtime,\n },\n } as EnvironmentArtifactResponse;\n this.cached = { mtimeMs, response };\n return response;\n } catch (err: any) {\n this.logger.error?.('[FileArtifactApiClient] failed to load artifact', {\n artifactPath: this.artifactPath,\n error: err?.message ?? err,\n });\n return null;\n }\n }\n\n private async readRuntimeFromArtifact(): Promise<EnvironmentRuntimeConfig | undefined> {\n const artifact = await this.loadArtifact();\n return artifact?.runtime;\n }\n\n private deriveRuntimeFromMetadata(metadata: any): EnvironmentRuntimeConfig | undefined {\n const datasources = metadata?.datasources;\n if (!Array.isArray(datasources) || datasources.length === 0) return undefined;\n const mapping: any[] | undefined = metadata?.datasourceMapping;\n let preferredName: string | undefined;\n if (mapping) {\n const def = mapping.find((m: any) => m?.default === true);\n if (def?.datasource) preferredName = def.datasource;\n }\n const ds = preferredName\n ? datasources.find((d: any) => d?.name === preferredName) ?? datasources[0]\n : datasources[0];\n if (!ds || typeof ds !== 'object') return undefined;\n const config = (ds.config ?? {}) as Record<string, any>;\n const url = config.url ?? config.connectionString ?? config.connection ?? config.filename;\n const driver = ds.driver;\n if (typeof driver !== 'string' || typeof url !== 'string') return undefined;\n return {\n databaseDriver: driver,\n databaseUrl: url,\n databaseAuthToken: typeof config.authToken === 'string' ? config.authToken : undefined,\n };\n }\n\n private defaultLocalSqliteRuntime(): EnvironmentRuntimeConfig {\n const cwd = process.cwd();\n const dbPath = resolvePath(cwd, '.objectstack/data', `${this.environmentId}.db`);\n return {\n databaseDriver: 'sqlite',\n databaseUrl: `file:${dbPath}`,\n };\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * createObjectOSStack\n *\n * ObjectOS pure-runtime stack — no control-plane database, no auth /\n * security / audit / tenant plugins. The host kernel registers:\n *\n * - A minimal engine triplet (ObjectQL + in-memory DriverPlugin +\n * MetadataPlugin) so CLI auto-injected plugins (Setup, Studio,\n * Dispatcher, REST) and the runtime can boot. The host kernel itself\n * never reads or writes business data — every record query is routed\n * to a per-project kernel built from a remote artifact.\n * - The `env-registry` and `kernel-manager` services, so the runtime's\n * HTTP dispatcher can resolve hostnames and dispatch every request\n * to the matching project kernel.\n *\n * Invoked by `createRuntimeStack()` whenever `OS_CLOUD_URL`\n * (or `config.controlPlaneUrl`) is set. The same plugin shape is returned\n * as `createCloudStack()` so host configs can swap stacks transparently.\n */\n\nimport { Plugin, PluginContext } from '@objectstack/core';\nimport type { EnvironmentDriverRegistry } from './environment-registry.js';\nimport { KernelManager } from './kernel-manager.js';\nimport { ArtifactApiClient } from './artifact-api-client.js';\nimport { ArtifactEnvironmentRegistry } from './artifact-environment-registry.js';\nimport { ArtifactKernelFactory } from './artifact-kernel-factory.js';\nimport { AuthProxyPlugin } from './auth-proxy-plugin.js';\nimport { MarketplaceProxyPlugin } from './marketplace-proxy-plugin.js';\nimport { RuntimeConfigPlugin } from './runtime-config-plugin.js';\nimport { FileArtifactApiClient, type FileArtifactApiClientConfig } from './file-artifact-api-client.js';\n\nexport interface ObjectOSStackConfig {\n /**\n * Control-plane base URL (HTTP) or a sentinel of `'file'` for the\n * local file-backed dev mode. Required unless `client` is supplied.\n *\n * - `http(s)://…` — talk to a real ObjectStack Cloud control plane\n * over HTTP and resolve hostnames via its `/cloud/*` API.\n * - `'file'` — load a single project from a local\n * `dist/objectstack.json` (or `fileConfig.artifactPath`). Every\n * request, regardless of hostname, resolves to the same project.\n * Intended for `pnpm dev` / smoke tests where standing up a\n * separate control plane is overkill.\n */\n controlPlaneUrl?: string;\n /** Optional bearer token for the control-plane API. */\n controlPlaneApiKey?: string;\n /**\n * Override the artifact client entirely. When supplied,\n * `controlPlaneUrl` is ignored — useful for tests or custom transports.\n */\n client?: ArtifactApiClient | FileArtifactApiClient;\n /** Config for the file-backed mode (used when `controlPlaneUrl === 'file'`). */\n fileConfig?: FileArtifactApiClientConfig;\n /** KernelManager LRU size. Default: 32. */\n kernelCacheSize?: number;\n /** KernelManager idle TTL (ms). Default: 15 min. */\n kernelTtlMs?: number;\n /** EnvironmentDriverRegistry cache TTL (ms). Default: 5 min. */\n envCacheTtlMs?: number;\n /** Artifact / hostname response cache TTL (ms). Default: 5 min. */\n artifactCacheTtlMs?: number;\n /** API prefix (carried for parity with cloud-stack). Default: /api/v1. */\n apiPrefix?: string;\n /**\n * Host-supplied runtime plugins appended to the stack's default plugin\n * list. This is the official seam for a host (e.g. the ObjectStack Cloud\n * repo) to add **product/policy** plugins — marketplace install, cloud-\n * account binding, set-initial-password — to the otherwise-neutral\n * framework runtime, WITHOUT a framework release and without reaching into\n * the returned array by hand.\n *\n * They are appended last, so they mount their routes after the framework\n * plugins and can override/augment behaviour (e.g. supply a credentialled\n * install path that the browse-only MarketplaceProxyPlugin deliberately\n * does not). See docs/design/cloud-account-binding-marketplace-install.md\n * (ADR §5.2 — \"framework exposes seams; cloud supplies metadata + policy\").\n */\n extraPlugins?: Plugin[];\n}\n\nexport interface ObjectOSStackResult {\n plugins: any[];\n api: { enableProjectScoping: true; projectResolution: 'auto'; requireAuth: true };\n}\n\n/**\n * Lazy-loaded host engine plugins. Mirrors the head of\n * `createControlPlanePlugins()` — ObjectQL + InMemory Driver + Metadata.\n *\n * The host kernel in objectos is a pure routing shell. Per-tenant auth +\n * business data live in per-project kernels (each backed by the project's\n * own Turso/Postgres DB), so there is nothing to persist on the host.\n *\n * AuthPlugin is intentionally NOT injected on the host (CLI's\n * `serve.ts` auto-injection guard skips it when `OS_CLOUD_URL` is set).\n * Identity is owned by `ArtifactKernelFactory` per project so that:\n * - users persist in the project's DB across container cold-starts\n * - cookies are scoped to the project's hostname (no `.<root>`-wide leak)\n * - tokens are signed with a per-project HKDF-derived secret\n */\nasync function createHostEnginePlugins(): Promise<Plugin[]> {\n const { ObjectQLPlugin } = await import('@objectstack/objectql');\n const { DriverPlugin } = await import('../driver-plugin.js');\n const { MetadataPlugin } = await import('@objectstack/metadata');\n const { InMemoryDriver } = await import('@objectstack/driver-memory');\n\n const driver = new InMemoryDriver();\n const driverName = 'memory';\n\n const oqlRef: { ql: any } = { ql: null };\n const objectql: Plugin = {\n name: 'com.objectstack.engine.objectql',\n version: '0.0.0',\n async init(ctx: PluginContext) {\n const plugin = new ObjectQLPlugin();\n (this as any)._inner = plugin;\n if ((plugin as any).init) await (plugin as any).init(ctx);\n // Capture the engine instance AFTER init() — ObjectQLPlugin\n // creates its `ql` lazily inside init(), so reading `plugin.ql`\n // before that returns undefined and breaks the\n // datasource-mapping wiring below.\n oqlRef.ql = (plugin as any).ql ?? plugin;\n },\n async start(ctx: PluginContext) {\n const plugin = (this as any)._inner;\n // Forward start() so ObjectQLPlugin can discover `driver.*`\n // services (registered by DriverPlugin.init) and wire them\n // into the engine via `ql.registerDriver(...)`. Without this\n // the engine has zero drivers at request time, causing\n // `[ObjectQL] No driver available for object '...'` errors.\n if (plugin?.start) await plugin.start(ctx);\n },\n async destroy() {\n const plugin = (this as any)._inner;\n if (plugin?.destroy) await plugin.destroy();\n else if (plugin?.stop) await plugin.stop();\n },\n };\n\n const datasourceMapping: Plugin = {\n name: 'objectos-host-datasource-mapping',\n version: '0.0.0',\n dependencies: ['com.objectstack.engine.objectql'],\n async init() {\n const ql = oqlRef.ql;\n if (ql?.setDatasourceMapping) {\n ql.setDatasourceMapping([\n { default: true, datasource: `com.objectstack.driver.${driverName}` },\n ]);\n }\n },\n };\n\n const driverPlugin = new DriverPlugin(driver as any, driverName);\n\n const metadata = new MetadataPlugin({\n watch: false,\n // The host kernel is a routing shell. It doesn't own metadata —\n // every per-project kernel registers its own.\n registerSystemObjects: false,\n });\n\n return [objectql, datasourceMapping, driverPlugin as unknown as Plugin, metadata as unknown as Plugin];\n}\n\n/**\n * Single host plugin that owns the artifact API client, the env registry,\n * and the kernel manager. Registered as services on the host kernel so\n * downstream plugins (the dispatcher, the REST API plugin) pick them up\n * automatically.\n */\nclass ObjectOSEnvironmentPlugin implements Plugin {\n readonly name = 'com.objectstack.runtime.objectos-environment';\n readonly version = '1.0.0';\n\n private readonly config: ObjectOSStackConfig;\n private kernelManager?: KernelManager;\n private client?: ArtifactApiClient;\n\n constructor(config: ObjectOSStackConfig) {\n this.config = config;\n }\n\n init = async (ctx: PluginContext): Promise<void> => {\n const client: ArtifactApiClient | FileArtifactApiClient = this.config.client\n ?? (this.config.controlPlaneUrl === 'file'\n ? new FileArtifactApiClient({\n ...(this.config.fileConfig ?? {}),\n logger: ctx.logger as any,\n })\n : new ArtifactApiClient({\n controlPlaneUrl: this.config.controlPlaneUrl!,\n apiKey: this.config.controlPlaneApiKey,\n cacheTtlMs: this.config.artifactCacheTtlMs,\n logger: ctx.logger,\n }));\n this.client = client as ArtifactApiClient;\n\n const envRegistry: EnvironmentDriverRegistry = new ArtifactEnvironmentRegistry({\n client: client as ArtifactApiClient,\n cacheTtlMs: this.config.envCacheTtlMs,\n logger: ctx.logger,\n });\n\n const factory = new ArtifactKernelFactory({\n client: client as ArtifactApiClient,\n envRegistry,\n logger: ctx.logger,\n });\n\n const kernelManager = new KernelManager({\n factory,\n maxSize: this.config.kernelCacheSize,\n ttlMs: this.config.kernelTtlMs,\n logger: ctx.logger,\n // Only the HTTP client exposes /freshness; file-mode (CLI dev)\n // has no upstream to probe.\n freshnessProbe: this.config.controlPlaneUrl === 'file'\n ? undefined\n : async (envId, builtAtMs) => {\n const fresh = await (client as ArtifactApiClient).getFreshness(envId);\n if (!fresh) return false; // unknown / unreachable → treat as fresh\n const t = fresh.lastPublishedAt ? Date.parse(fresh.lastPublishedAt) : NaN;\n if (!Number.isFinite(t)) return false;\n if (t <= builtAtMs) return false;\n // Upstream changed since this kernel was built. Drop\n // the artifact cache too so the rebuild sees the new\n // bundle (otherwise we'd happily rebuild from the\n // same 5-minute-cached artifact JSON).\n try { (client as ArtifactApiClient).invalidate(envId); } catch { /* best effort */ }\n return true;\n },\n });\n this.kernelManager = kernelManager;\n\n ctx.registerService('env-registry', envRegistry);\n ctx.registerService('kernel-manager', kernelManager);\n ctx.registerService('artifact-api-client', client);\n\n ctx.logger.info?.('ObjectOSEnvironmentPlugin: registered env-registry + kernel-manager', {\n mode: this.config.controlPlaneUrl === 'file' ? 'file' : 'http',\n controlPlaneUrl: this.config.controlPlaneUrl,\n });\n };\n\n destroy = async (): Promise<void> => {\n try { await this.kernelManager?.evictAll(); } catch { /* best effort */ }\n try { this.client?.clear(); } catch { /* best effort */ }\n };\n}\n\nexport async function createObjectOSStack(config: ObjectOSStackConfig): Promise<ObjectOSStackResult> {\n if (!config.controlPlaneUrl && !config.client) {\n throw new Error('[createObjectOSStack] either controlPlaneUrl or client is required');\n }\n const merged: ObjectOSStackConfig = {\n ...config,\n kernelCacheSize: Number(process.env.OS_KERNEL_CACHE_SIZE ?? config.kernelCacheSize ?? 32),\n kernelTtlMs: Number(process.env.OS_KERNEL_TTL_MS ?? config.kernelTtlMs ?? 15 * 60 * 1000),\n envCacheTtlMs: Number(process.env.OS_ENV_CACHE_TTL_MS ?? config.envCacheTtlMs ?? 5 * 60 * 1000),\n artifactCacheTtlMs: Number(process.env.OS_ARTIFACT_CACHE_TTL_MS ?? config.artifactCacheTtlMs ?? 5 * 60 * 1000),\n };\n\n const enginePlugins = await createHostEnginePlugins();\n\n return {\n plugins: [\n ...enginePlugins,\n new ObjectOSEnvironmentPlugin(merged),\n new AuthProxyPlugin(),\n new MarketplaceProxyPlugin({ controlPlaneUrl: merged.controlPlaneUrl === 'file' ? undefined : merged.controlPlaneUrl }),\n new RuntimeConfigPlugin({ controlPlaneUrl: merged.controlPlaneUrl === 'file' ? undefined : merged.controlPlaneUrl, installLocal: false }),\n // Host-supplied product/policy plugins (the official seam — see\n // ObjectOSStackConfig.extraPlugins). Appended last so they mount\n // after the framework defaults.\n ...(config.extraPlugins ?? []),\n ],\n api: {\n enableProjectScoping: true,\n projectResolution: 'auto',\n // ObjectOS is multi-tenant: anonymous /api/v1/data/* must never\n // leak per-project data across organisations. AuthProxyPlugin\n // verifies upstream tokens and populates ctx.userId; requireAuth\n // turns missing userId into 401 at the REST layer before the\n // request reaches the per-project kernel.\n requireAuth: true,\n },\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * MarketplaceInstallLocalPlugin\n *\n * Installs marketplace packages into THIS runtime's kernel as opposed to a\n * remote cloud environment. Conceptually different from cloud install in\n * three important ways:\n *\n * 1. Single target — the local kernel is the only install target; there\n * is no `sys_environment` picker.\n * 2. Manifests are cached on disk — once installed, the package is\n * runnable offline. Cloud is only needed during the install action\n * itself (to fetch the manifest snapshot).\n * 3. Coexists with user-authored apps — the local runtime usually has\n * its own `objectstack.config.ts` declared apps. Install refuses to\n * overwrite a manifest_id that's already registered to avoid silently\n * replacing user code.\n *\n * Endpoints (mounted by `start()` on the `kernel:ready` hook):\n *\n * POST /api/v1/marketplace/install-local\n * body: { packageId: string, versionId?: string } (default: \"latest\")\n * → fetches manifest from cloud, caches to disk, registers via\n * the kernel's `manifest` service. Returns the installed entry.\n *\n * GET /api/v1/marketplace/install-local\n * → lists currently installed marketplace packages\n *\n * DELETE /api/v1/marketplace/install-local/:manifestId\n * → removes the cached manifest. Kernel must be restarted to fully\n * unload — `engine.registerApp` is additive only. We document\n * this in the response message.\n *\n * Persistence layout:\n * <cwd>/.objectstack/installed-packages/<safe-manifest-id>.json\n * Each file: { packageId, versionId, manifestId, version, manifest, installedAt, installedBy }\n *\n * On `kernel:ready`, the plugin scans the directory and re-registers each\n * cached manifest so installs survive process restarts without further\n * cloud round-trips.\n */\n\nimport { existsSync, mkdirSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport type { Plugin, PluginContext } from '@objectstack/core';\nimport { readEnvWithDeprecation } from '@objectstack/types';\nimport { resolveCloudUrl } from './cloud-url.js';\nimport { resolveMarketplacePublicBaseUrl } from './marketplace-public-url.js';\n\nconst ROUTE_BASE = '/api/v1/marketplace/install-local';\nconst DEFAULT_DIR = '.objectstack/installed-packages';\n\nexport interface MarketplaceInstallLocalPluginConfig {\n /** Cloud control-plane base URL. When unset, falls back to OS_CLOUD_URL\n * and then to the public ObjectStack cloud so a fresh `objectstack dev`\n * can install from the marketplace without configuration. Set\n * OS_CLOUD_URL=off to disable (the install endpoint then returns 503). */\n controlPlaneUrl?: string;\n /** Override the on-disk cache directory. Defaults to\n * `<cwd>/.objectstack/installed-packages`. */\n storageDir?: string;\n}\n\ninterface InstalledEntry {\n packageId: string;\n versionId: string;\n manifestId: string;\n version: string;\n manifest: any;\n installedAt: string;\n installedBy: string | null;\n /** Whether the bundled seed datasets have been loaded into the kernel\n * database. True after install (seedNow=true) or an explicit reseed;\n * false after a purge. Persisted so the UI can show \"Add\" vs \"Re-seed\". */\n withSampleData?: boolean;\n}\n\nfunction safeFilename(manifestId: string): string {\n return manifestId.replace(/[^a-zA-Z0-9._-]/g, '_') + '.json';\n}\n\nexport class MarketplaceInstallLocalPlugin implements Plugin {\n readonly name = 'com.objectstack.runtime.marketplace-install-local';\n readonly version = '1.0.0';\n\n private readonly cloudUrl: string;\n private readonly storageDir: string;\n\n constructor(config: MarketplaceInstallLocalPluginConfig = {}) {\n this.cloudUrl = resolveCloudUrl(config.controlPlaneUrl);\n this.storageDir = config.storageDir\n ? resolve(config.storageDir)\n : resolve(process.cwd(), DEFAULT_DIR);\n }\n\n init = async (_ctx: PluginContext): Promise<void> => {\n // No services registered — pure HTTP wiring during start().\n };\n\n start = async (ctx: PluginContext): Promise<void> => {\n ctx.hook('kernel:ready', async () => {\n // 1. Rehydrate previously installed packages so they survive restart.\n await this.rehydrate(ctx);\n\n // 2. Mount HTTP endpoints.\n let httpServer: any;\n try {\n httpServer = ctx.getService('http-server');\n } catch {\n ctx.logger?.warn?.('[MarketplaceInstallLocal] http-server not available — install endpoints not mounted');\n return;\n }\n if (!httpServer || typeof httpServer.getRawApp !== 'function') {\n ctx.logger?.warn?.('[MarketplaceInstallLocal] http-server missing getRawApp() — install endpoints not mounted');\n return;\n }\n const rawApp = httpServer.getRawApp();\n\n const postHandler = async (c: any) => this.handleInstall(c, ctx);\n const getHandler = async (c: any) => this.handleList(c);\n const deleteHandler = async (c: any) => this.handleUninstall(c, ctx);\n\n const reseedHandler = async (c: any) => this.handleReseed(c, ctx);\n const purgeHandler = async (c: any) => this.handlePurge(c, ctx);\n\n if (typeof rawApp.post === 'function') rawApp.post(ROUTE_BASE, postHandler);\n if (typeof rawApp.get === 'function') rawApp.get(ROUTE_BASE, getHandler);\n if (typeof rawApp.delete === 'function') rawApp.delete(`${ROUTE_BASE}/:manifestId`, deleteHandler);\n if (typeof rawApp.post === 'function') {\n rawApp.post(`${ROUTE_BASE}/:manifestId/reseed-sample-data`, reseedHandler);\n rawApp.post(`${ROUTE_BASE}/:manifestId/purge-sample-data`, purgeHandler);\n }\n\n ctx.logger?.info?.(`[MarketplaceInstallLocal] mounted at ${ROUTE_BASE} (storage: ${this.storageDir})`);\n });\n };\n\n /**\n * Re-register every cached manifest with the kernel's manifest service.\n * Safe to call on a kernel that already has the same manifest_id (the\n * underlying ObjectQL registry overwrites by id, but we still warn so\n * a developer can spot the dev-time clash between their config.ts and\n * a marketplace package).\n */\n private rehydrate = async (ctx: PluginContext): Promise<void> => {\n const entries = this.readAll();\n if (entries.length === 0) return;\n\n let manifestService: { register(m: any): void } | null = null;\n try {\n manifestService = ctx.getService('manifest') as any;\n } catch {\n ctx.logger?.warn?.('[MarketplaceInstallLocal] no `manifest` service — rehydrate skipped');\n return;\n }\n\n for (const entry of entries) {\n try {\n manifestService!.register(entry.manifest);\n // Sync schemas so the driver creates tables for the newly-\n // registered objects (idempotent — already-synced tables\n // are no-ops).\n try {\n const ql: any = ctx.getService('objectql');\n if (ql && typeof ql.syncSchemas === 'function') await ql.syncSchemas();\n } catch { /* non-fatal */ }\n // Replay translations + register seed datasets, but don't\n // re-run seeding — existing rows are already in the DB from\n // the original install, and multi-tenant orgs will replay\n // via the security middleware on next sys_organization insert.\n await this.applySideEffects(ctx, entry.manifest, { seedNow: false });\n ctx.logger?.info?.(`[MarketplaceInstallLocal] rehydrated ${entry.manifestId}@${entry.version}`);\n } catch (err: any) {\n ctx.logger?.error?.(`[MarketplaceInstallLocal] rehydrate failed for ${entry.manifestId}`, err instanceof Error ? err : new Error(String(err)));\n }\n }\n };\n\n private handleInstall = async (c: any, ctx: PluginContext): Promise<Response> => {\n const userId = await this.requireAuthenticatedUser(c, ctx);\n if (!userId) {\n return c.json({ success: false, error: { code: 'unauthorized', message: 'Authentication required to install packages.' } }, 401);\n }\n\n let body: any = {};\n try { body = await c.req.json(); } catch { /* empty body */ }\n\n // ── Offline path: an inline manifest was supplied (file import). ──\n // Bypass the cloud-fetch entirely; no OS_CLOUD_URL required.\n const inlineManifest = body?.manifest && typeof body.manifest === 'object' ? body.manifest : null;\n\n let manifest: any;\n let resolvedVersionId: string;\n let version: string;\n let packageId: string;\n\n if (inlineManifest) {\n manifest = inlineManifest;\n packageId = String(manifest.id ?? manifest.name ?? '').trim();\n version = String(manifest.version ?? 'unknown');\n resolvedVersionId = String(body?.versionId ?? version);\n if (!packageId) {\n return c.json({ success: false, error: { code: 'invalid_manifest', message: 'Inline manifest must have an \"id\" or \"name\".' } }, 400);\n }\n } else {\n if (!this.cloudUrl) {\n return c.json({ success: false, error: { code: 'marketplace_unavailable', message: 'OS_CLOUD_URL not configured.' } }, 503);\n }\n packageId = String(body?.packageId ?? '').trim();\n const versionId = String(body?.versionId ?? 'latest').trim() || 'latest';\n if (!packageId) {\n return c.json({ success: false, error: { code: 'bad_request', message: 'packageId is required.' } }, 400);\n }\n\n // 1. Fetch manifest snapshot — prefer public R2 fast-path so\n // install works even when cloud is asleep or down. Fall back\n // to cloud on miss/error.\n let payload: any;\n const publicBase = resolveMarketplacePublicBaseUrl();\n const fetchAttempts: { label: string; url: string }[] = [];\n if (publicBase) {\n fetchAttempts.push({\n label: 'public-r2',\n url: `${publicBase}/packages/${encodeURIComponent(packageId)}/versions/${encodeURIComponent(versionId)}/manifest.json`,\n });\n }\n fetchAttempts.push({\n label: 'cloud',\n url: `${this.cloudUrl}/api/v1/marketplace/packages/${encodeURIComponent(packageId)}/versions/${encodeURIComponent(versionId)}/manifest`,\n });\n\n let lastErrStatus = 0;\n let lastErrText = '';\n for (const attempt of fetchAttempts) {\n try {\n const resp = await fetch(attempt.url, { headers: { 'Accept': 'application/json' } });\n if (!resp.ok) {\n lastErrStatus = resp.status;\n lastErrText = (await resp.text().catch(() => '')).slice(0, 200);\n // 404 from public R2 is not fatal — fall through to cloud.\n if (attempt.label === 'public-r2' && resp.status === 404) {\n ctx.logger?.info?.(`[MarketplaceInstallLocal] public-r2 miss for ${packageId}@${versionId}, falling back to cloud`);\n continue;\n }\n if (attempt.label === 'public-r2' && resp.status >= 500) {\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] public-r2 ${resp.status}, falling back to cloud`);\n continue;\n }\n break; // cloud non-ok → surface error\n }\n payload = await resp.json();\n lastErrStatus = 0;\n break;\n } catch (err: any) {\n if (attempt.label === 'public-r2') {\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] public-r2 fetch error: ${err?.message ?? err}, falling back to cloud`);\n continue;\n }\n return c.json({\n success: false,\n error: { code: 'cloud_fetch_failed', message: err?.message ?? String(err) },\n }, 502);\n }\n }\n if (!payload) {\n return c.json({\n success: false,\n error: { code: 'cloud_fetch_failed', message: `Cloud returned ${lastErrStatus}: ${lastErrText}` },\n }, lastErrStatus === 404 ? 404 : 502);\n }\n\n const data = payload?.data ?? payload;\n manifest = data?.manifest;\n resolvedVersionId = String(data?.version_id ?? versionId);\n version = String(data?.version ?? 'unknown');\n }\n\n const manifestId = String(manifest?.id ?? manifest?.name ?? '');\n if (!manifest || !manifestId) {\n return c.json({ success: false, error: { code: 'invalid_manifest', message: 'Invalid manifest payload.' } }, inlineManifest ? 400 : 502);\n }\n\n // 2. Conflict check — refuse to overwrite user-authored apps\n const conflict = this.findConflict(ctx, manifestId);\n if (conflict === 'user-code') {\n return c.json({\n success: false,\n error: {\n code: 'manifest_conflict',\n message: `manifest_id \"${manifestId}\" is already defined by this runtime's local code. Refusing to overwrite. Uninstall the local definition first.`,\n },\n }, 409);\n }\n\n // 3. Hot-register FIRST so a malformed inline manifest fails the\n // install loudly rather than persisting a broken record that\n // would also fail on every subsequent rehydrate.\n try {\n const manifestService = ctx.getService('manifest') as any;\n manifestService.register(manifest);\n } catch (err: any) {\n // For offline file imports we treat a register failure as a hard\n // failure (don't persist). Cloud installs historically tolerated\n // this (the on-disk record survives a restart), so keep that path\n // lenient for backwards compatibility.\n if (inlineManifest) {\n return c.json({\n success: false,\n error: { code: 'register_failed', message: `Failed to register imported manifest: ${err?.message ?? err}` },\n }, 422);\n }\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] hot-register failed for ${manifestId} (will load on next restart): ${err?.message ?? err}`);\n }\n\n // 4. Persist on disk\n const entry: InstalledEntry = {\n packageId,\n versionId: resolvedVersionId,\n manifestId,\n version,\n manifest,\n installedAt: new Date().toISOString(),\n installedBy: userId,\n withSampleData: false,\n };\n try {\n mkdirSync(this.storageDir, { recursive: true });\n writeFileSync(join(this.storageDir, safeFilename(manifestId)), JSON.stringify(entry, null, 2), 'utf8');\n } catch (err: any) {\n return c.json({\n success: false,\n error: { code: 'storage_failed', message: `Failed to persist manifest: ${err?.message ?? err}` },\n }, 500);\n }\n\n // 4b. Sync schemas to physical tables — registerApp only adds the\n // object definitions to the in-memory registry; the driver\n // must be asked to materialize tables/columns before any seed\n // insert (or user write) succeeds.\n try {\n const ql: any = ctx.getService('objectql');\n if (ql && typeof ql.syncSchemas === 'function') {\n await ql.syncSchemas();\n ctx.logger?.info?.(`[MarketplaceInstallLocal] syncSchemas() ran after registering ${manifestId}`);\n }\n } catch (err: any) {\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] syncSchemas failed for ${manifestId}: ${err?.message ?? err}`);\n }\n\n // 5. Replicate the AppPlugin start-time side-effects that the\n // `manifest` service does NOT do on its own:\n // • load translation bundles into the i18n service\n // • stash seed datasets on the kernel + run them now so the\n // installed app has demo data on first paint.\n const seededSummary = await this.applySideEffects(ctx, manifest, { seedNow: true, c });\n if (seededSummary.seeded.mode === 'inline' && (seededSummary.seeded.inserted ?? 0) + (seededSummary.seeded.updated ?? 0) > 0) {\n entry.withSampleData = true;\n try {\n writeFileSync(join(this.storageDir, safeFilename(manifestId)), JSON.stringify(entry, null, 2), 'utf8');\n } catch { /* non-fatal — entry already on disk */ }\n }\n\n return c.json({\n success: true,\n data: {\n manifestId,\n version,\n versionId: resolvedVersionId,\n installedAt: entry.installedAt,\n hotLoaded: true,\n upgradedFrom: conflict === 'marketplace' ? 'previous-marketplace-version' : null,\n translationsLoaded: seededSummary.translationsLoaded,\n seeded: seededSummary.seeded,\n note: 'App is now available in this runtime. Refresh the console to see it in the app switcher.',\n },\n }, 200);\n };\n\n private handleList = async (c: any): Promise<Response> => {\n const entries = this.readAll();\n return c.json({\n success: true,\n data: {\n items: entries.map(e => ({\n packageId: e.packageId,\n versionId: e.versionId,\n manifestId: e.manifestId,\n version: e.version,\n installedAt: e.installedAt,\n installedBy: e.installedBy,\n withSampleData: e.withSampleData ?? false,\n })),\n total: entries.length,\n storageDir: this.storageDir,\n },\n }, 200);\n };\n\n private handleUninstall = async (c: any, ctx: PluginContext): Promise<Response> => {\n const userId = await this.requireAuthenticatedUser(c, ctx);\n if (!userId) {\n return c.json({ success: false, error: { code: 'unauthorized', message: 'Authentication required.' } }, 401);\n }\n const manifestId = String(c.req.param?.('manifestId') ?? c.req.params?.manifestId ?? '').trim();\n if (!manifestId) {\n return c.json({ success: false, error: { code: 'bad_request', message: 'manifestId path param required.' } }, 400);\n }\n const file = join(this.storageDir, safeFilename(manifestId));\n if (!existsSync(file)) {\n return c.json({ success: false, error: { code: 'not_found', message: `No marketplace install for ${manifestId}.` } }, 404);\n }\n try {\n unlinkSync(file);\n } catch (err: any) {\n return c.json({ success: false, error: { code: 'storage_failed', message: err?.message ?? String(err) } }, 500);\n }\n ctx.logger?.info?.(`[MarketplaceInstallLocal] uninstalled ${manifestId} (cached manifest removed; restart runtime to unload from running kernel)`);\n return c.json({\n success: true,\n data: {\n manifestId,\n note: 'Cached manifest removed. The app remains loaded in the running kernel until the next restart (the kernel API does not support unregistering apps in-place).',\n },\n }, 200);\n };\n\n /**\n * Detect whether `manifestId` is already known to the kernel and classify\n * the source so we can refuse vs upgrade gracefully.\n *\n * 'none' — fresh install\n * 'marketplace' — previously installed by this plugin (allow upgrade)\n * 'user-code' — defined by AppPlugin from objectstack.config.ts\n * (refuse to avoid silently overwriting authored code)\n */\n private findConflict = (ctx: PluginContext, manifestId: string): 'none' | 'marketplace' | 'user-code' => {\n // First check: do we already have a marketplace install file?\n if (existsSync(join(this.storageDir, safeFilename(manifestId)))) {\n return 'marketplace';\n }\n // Then check: is the manifest_id already in the engine's registry?\n try {\n const ql: any = ctx.getService('objectql');\n const packages: any[] = ql?.registry?.getAllPackages?.() ?? [];\n const hit = packages.find((p: any) =>\n (p?.manifest?.id ?? p?.id ?? p?.manifest?.name) === manifestId,\n );\n if (hit) return 'user-code';\n } catch { /* objectql not registered yet — treat as fresh */ }\n return 'none';\n };\n\n /**\n * Pull a userId out of the request's better-auth session, if any.\n * Returns null when there is no signed-in user. v1 does not check\n * admin role — UI gating + the auth requirement is sufficient for\n * dev / single-tenant runtimes. Stricter checks can be layered on\n * via a middleware in cloud-hosted multi-tenant deployments.\n */\n /**\n * POST /api/v1/marketplace/install-local/:manifestId/reseed-sample-data\n *\n * Re-runs SeedLoaderService against the cached manifest's `data` arrays.\n * Idempotent (upsert by id). Useful when:\n * • The user installed an app and skipped sample data\n * • A purge was undone\n * • The user wants a clean baseline back after editing demo rows\n *\n * Multi-tenant: requires an active organization on the session (same\n * rule as install seed path).\n */\n private handleReseed = async (c: any, ctx: PluginContext): Promise<Response> => {\n const userId = await this.requireAuthenticatedUser(c, ctx);\n if (!userId) {\n return c.json({ success: false, error: { code: 'unauthorized', message: 'Authentication required.' } }, 401);\n }\n const manifestId = String(c.req.param?.('manifestId') ?? c.req.params?.manifestId ?? '').trim();\n if (!manifestId) {\n return c.json({ success: false, error: { code: 'bad_request', message: 'manifestId path param required.' } }, 400);\n }\n const file = join(this.storageDir, safeFilename(manifestId));\n if (!existsSync(file)) {\n return c.json({ success: false, error: { code: 'not_found', message: `No marketplace install for ${manifestId}.` } }, 404);\n }\n\n let entry: InstalledEntry;\n try {\n entry = JSON.parse(readFileSync(file, 'utf8'));\n } catch (err: any) {\n return c.json({ success: false, error: { code: 'storage_failed', message: `Failed to read manifest cache: ${err?.message ?? err}` } }, 500);\n }\n\n const summary = await this.applySideEffects(ctx, entry.manifest, { seedNow: true, c });\n if (summary.seeded.mode === 'skipped') {\n return c.json({\n success: false,\n error: {\n code: 'reseed_skipped',\n message: `Reseed did not run: ${summary.seeded.reason ?? 'unknown reason'}`,\n },\n }, 400);\n }\n\n // Persist flag flip\n try {\n entry.withSampleData = true;\n writeFileSync(file, JSON.stringify(entry, null, 2), 'utf8');\n } catch { /* non-fatal */ }\n\n return c.json({\n success: true,\n data: {\n manifestId,\n inserted: summary.seeded.inserted ?? 0,\n updated: summary.seeded.updated ?? 0,\n errors: summary.seeded.errors ?? 0,\n withSampleData: true,\n },\n }, 200);\n };\n\n /**\n * POST /api/v1/marketplace/install-local/:manifestId/purge-sample-data\n *\n * Deletes every record whose id is declared in the cached manifest's\n * seed datasets. Uses the `driver` service directly to bypass ACL /\n * lifecycle hooks (same pattern as cloud purge). User-created records\n * are never touched — only ids declared in the package's bundled\n * datasets are removed. Already-deleted rows count as `skipped`.\n */\n private handlePurge = async (c: any, ctx: PluginContext): Promise<Response> => {\n const userId = await this.requireAuthenticatedUser(c, ctx);\n if (!userId) {\n return c.json({ success: false, error: { code: 'unauthorized', message: 'Authentication required.' } }, 401);\n }\n const manifestId = String(c.req.param?.('manifestId') ?? c.req.params?.manifestId ?? '').trim();\n if (!manifestId) {\n return c.json({ success: false, error: { code: 'bad_request', message: 'manifestId path param required.' } }, 400);\n }\n const file = join(this.storageDir, safeFilename(manifestId));\n if (!existsSync(file)) {\n return c.json({ success: false, error: { code: 'not_found', message: `No marketplace install for ${manifestId}.` } }, 404);\n }\n\n let entry: InstalledEntry;\n try {\n entry = JSON.parse(readFileSync(file, 'utf8'));\n } catch (err: any) {\n return c.json({ success: false, error: { code: 'storage_failed', message: `Failed to read manifest cache: ${err?.message ?? err}` } }, 500);\n }\n\n const datasets = Array.isArray(entry.manifest?.data)\n ? entry.manifest.data.filter((d: any) => d && d.object && Array.isArray(d.records))\n : [];\n\n if (datasets.length === 0) {\n return c.json({\n success: false,\n error: { code: 'nothing_to_purge', message: 'This package declares no seed datasets.' },\n }, 400);\n }\n\n let driver: any;\n try { driver = ctx.getService('driver'); } catch { /* none */ }\n if (!driver || typeof driver.delete !== 'function') {\n return c.json({\n success: false,\n error: { code: 'driver_missing', message: 'driver service unavailable — cannot purge.' },\n }, 500);\n }\n\n let deleted = 0;\n let skipped = 0;\n let errors = 0;\n for (const ds of datasets) {\n const object = String(ds.object);\n for (const rec of ds.records as any[]) {\n const id = rec?.id;\n if (id === undefined || id === null || id === '') { skipped++; continue; }\n try {\n const r = await driver.delete(object, id);\n if (r === false || r === 0 || r?.deleted === 0) skipped++;\n else deleted++;\n } catch (err: any) {\n // Treat \"not found\" as skipped; anything else as error.\n const msg = String(err?.message ?? err);\n if (/not.?found|no row/i.test(msg)) skipped++;\n else { errors++; ctx.logger?.warn?.(`[MarketplaceInstallLocal] purge ${object}#${id}: ${msg}`); }\n }\n }\n }\n\n // Flip flag so UI reflects the empty baseline\n try {\n entry.withSampleData = false;\n writeFileSync(file, JSON.stringify(entry, null, 2), 'utf8');\n } catch { /* non-fatal */ }\n\n ctx.logger?.info?.(`[MarketplaceInstallLocal] purged ${manifestId}: deleted=${deleted} skipped=${skipped} errors=${errors}`);\n return c.json({\n success: true,\n data: { manifestId, deleted, skipped, errors, withSampleData: false },\n }, 200);\n };\n\n /**\n * Replicate the start-time side-effects that AppPlugin runs for\n * statically-declared apps but the `manifest` service does NOT:\n *\n * 1. Load `manifest.translations` (array of `Record<locale, data>`)\n * into the i18n service — auto-creating an in-memory fallback if\n * none is registered, matching AppPlugin's behaviour.\n *\n * 2. Merge `manifest.data` (an array of seed datasets) into the\n * kernel's `seed-datasets` service so SecurityPlugin's per-org\n * replay middleware picks them up on every future\n * sys_organization insert.\n *\n * 3. When `seedNow=true`, also run the seed immediately so the user\n * sees demo data without having to create a new org:\n * • single-tenant: run SeedLoaderService inline (mirrors\n * AppPlugin single-tenant branch)\n * • multi-tenant: invoke `seed-replayer` for the caller's\n * active org (resolved from the request session)\n *\n * Errors are logged but never thrown — install succeeds even if\n * post-register side-effects partially fail (the manifest itself is\n * already registered + cached). Returns a small summary for the\n * response envelope.\n */\n private applySideEffects = async (\n ctx: PluginContext,\n manifest: any,\n opts: { seedNow: boolean; c?: any },\n ): Promise<{ translationsLoaded: number; seeded: { mode: 'inline' | 'replayer' | 'skipped'; inserted?: number; updated?: number; errors?: number; reason?: string } }> => {\n const appId = String(manifest?.id ?? 'unknown');\n let translationsLoaded = 0;\n let seedSummary: any = { mode: 'skipped', reason: 'no-datasets' };\n\n // ── 1. i18n bundles ─────────────────────────────────────────────\n try {\n const bundles: Array<Record<string, unknown>> = [];\n if (Array.isArray(manifest?.translations)) bundles.push(...manifest.translations);\n if (Array.isArray(manifest?.i18n)) bundles.push(...manifest.i18n);\n\n if (bundles.length > 0) {\n let i18nService: any;\n try { i18nService = ctx.getService('i18n'); } catch { /* not registered */ }\n if (!i18nService) {\n try {\n const mod = await import('@objectstack/core');\n const createMemoryI18n = (mod as any).createMemoryI18n;\n if (typeof createMemoryI18n === 'function') {\n i18nService = createMemoryI18n();\n (ctx as any).registerService?.('i18n', i18nService);\n ctx.logger?.info?.(`[MarketplaceInstallLocal] auto-registered in-memory i18n fallback for \"${appId}\"`);\n }\n } catch { /* fallback unavailable */ }\n }\n if (i18nService?.loadTranslations) {\n for (const bundle of bundles) {\n for (const [locale, data] of Object.entries(bundle)) {\n if (data && typeof data === 'object') {\n try {\n i18nService.loadTranslations(locale, data as Record<string, unknown>);\n translationsLoaded++;\n } catch (err: any) {\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] failed to load ${appId} translations for ${locale}: ${err?.message ?? err}`);\n }\n }\n }\n }\n ctx.logger?.info?.(`[MarketplaceInstallLocal] loaded ${translationsLoaded} locale bundle(s) for ${appId}`);\n }\n }\n } catch (err: any) {\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] i18n side-effect failed for ${appId}: ${err?.message ?? err}`);\n }\n\n // ── 2. Seed datasets — merge into kernel service ─────────────────\n const datasets = Array.isArray(manifest?.data)\n ? manifest.data.filter((d: any) => d && d.object && Array.isArray(d.records))\n : [];\n\n if (datasets.length > 0) {\n try {\n const kernel: any = (ctx as any).kernel;\n let existing: any[] = [];\n try {\n const v = kernel?.getService?.('seed-datasets');\n if (Array.isArray(v)) existing = v;\n } catch { /* unset */ }\n const merged = [...existing, ...datasets];\n if (kernel?.registerService) kernel.registerService('seed-datasets', merged);\n else (ctx as any).registerService?.('seed-datasets', merged);\n ctx.logger?.info?.(`[MarketplaceInstallLocal] merged ${datasets.length} seed dataset(s) into kernel (total: ${merged.length})`);\n } catch (err: any) {\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] failed to merge seed-datasets: ${err?.message ?? err}`);\n }\n }\n\n // ── 3. Optional immediate seed ───────────────────────────────────\n // Always seed inline via SeedLoaderService — don't rely on the\n // `seed-replayer` registered by AppPlugin since (a) it isn't\n // registered when the host runtime has no AppPlugin app with\n // seed data, and (b) its closure may use stale datasets. In\n // multi-tenant mode we pass `organizationId` so the loader\n // writes tenant-scoped rows the same way AppPlugin's\n // single-tenant branch + SecurityPlugin's per-org replay do.\n if (opts.seedNow && datasets.length > 0) {\n const multiTenant = String(readEnvWithDeprecation('OS_MULTI_ORG_ENABLED', 'OS_MULTI_TENANT') ?? 'false').toLowerCase() !== 'false';\n try {\n const ql: any = ctx.getService('objectql');\n let metadata: any;\n try { metadata = ctx.getService('metadata'); } catch { /* none */ }\n if (!ql || !metadata) {\n seedSummary = { mode: 'skipped', reason: 'objectql-or-metadata-missing' };\n } else {\n let organizationId: string | undefined;\n if (multiTenant) {\n const resolved = await this.resolveActiveOrgId(opts.c, ctx);\n if (resolved) organizationId = resolved;\n else {\n seedSummary = { mode: 'skipped', reason: 'multi-tenant-no-active-org' };\n ctx.logger?.warn?.('[MarketplaceInstallLocal] multi-tenant: no active org on request — data not seeded');\n }\n }\n if (!multiTenant || organizationId) {\n const [{ SeedLoaderService }, { SeedLoaderRequestSchema }] = await Promise.all([\n import('../seed-loader.js'),\n import('@objectstack/spec/data'),\n ]);\n const seedLoader = new (SeedLoaderService as any)(ql, metadata, ctx.logger);\n const request = (SeedLoaderRequestSchema as any).parse({\n datasets,\n config: {\n defaultMode: 'upsert',\n multiPass: true,\n ...(organizationId ? { organizationId } : {}),\n },\n });\n const result = await seedLoader.load(request);\n seedSummary = {\n mode: 'inline',\n inserted: result.summary.totalInserted,\n updated: result.summary.totalUpdated,\n errors: result.errors.length,\n };\n ctx.logger?.info?.(`[MarketplaceInstallLocal] inline seed for ${appId}${organizationId ? ` (org=${organizationId})` : ''}: inserted=${seedSummary.inserted} updated=${seedSummary.updated} errors=${seedSummary.errors}`);\n }\n }\n } catch (err: any) {\n seedSummary = { mode: 'skipped', reason: `seed-error: ${err?.message ?? err}` };\n ctx.logger?.warn?.(`[MarketplaceInstallLocal] seed run failed for ${appId}: ${err?.message ?? err}`);\n }\n }\n\n return { translationsLoaded, seeded: seedSummary };\n };\n\n /**\n * Best-effort active-org resolution. Reads the better-auth session\n * (same path as requireAuthenticatedUser) and returns\n * `session.activeOrganizationId`, falling back to the user's first\n * org membership.\n */\n private resolveActiveOrgId = async (c: any, ctx: PluginContext): Promise<string | null> => {\n if (!c?.req?.raw?.headers) return null;\n try {\n const authService: any = ctx.getService('auth');\n let api: any = authService?.api;\n if (!api && typeof authService?.getApi === 'function') api = await authService.getApi();\n if (!api?.getSession) return null;\n const session = await api.getSession({ headers: c.req.raw.headers });\n const direct = session?.session?.activeOrganizationId ?? session?.activeOrganizationId ?? null;\n if (direct) return String(direct);\n // Fall back to the user's first membership row.\n const userId = session?.user?.id;\n if (!userId) return null;\n try {\n const ql: any = ctx.getService('objectql');\n if (ql?.find) {\n const rows = await ql.find('sys_organization_member', { where: { user_id: userId }, limit: 1, context: { isSystem: true } } as any);\n const row = Array.isArray(rows) ? rows[0] : (rows?.items?.[0] ?? null);\n return row?.organization_id ? String(row.organization_id) : null;\n }\n } catch { /* ignore */ }\n } catch { /* ignore */ }\n return null;\n };\n\n private requireAuthenticatedUser = async (c: any, ctx: PluginContext): Promise<string | null> => {\n try {\n // Mirror `hono-plugin.ts` resolveCtx: pull the better-auth `api`\n // off the auth service and call `getSession({ headers })`. The\n // earlier guess `c.get('auth').session` is wrong — AuthPlugin\n // does not pre-populate the Hono context.\n const authService: any = ctx.getService('auth');\n let api: any = authService?.api;\n if (!api && typeof authService?.getApi === 'function') {\n api = await authService.getApi();\n }\n if (api?.getSession && c?.req?.raw?.headers) {\n const session = await api.getSession({ headers: c.req.raw.headers });\n const userId = session?.user?.id ?? null;\n if (userId) return String(userId);\n }\n } catch { /* ignore — fall through */ }\n // Header fallback for cases where auth is disabled (e.g. test stubs)\n const xUserId = c?.req?.header?.('x-user-id');\n if (xUserId) return String(xUserId);\n return null;\n };\n\n private readAll = (): InstalledEntry[] => {\n if (!existsSync(this.storageDir)) return [];\n const out: InstalledEntry[] = [];\n for (const name of readdirSync(this.storageDir)) {\n if (!name.endsWith('.json')) continue;\n try {\n const raw = readFileSync(join(this.storageDir, name), 'utf8');\n out.push(JSON.parse(raw));\n } catch { /* skip corrupt files */ }\n }\n return out;\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * # Hook & Action Body Sandbox\n *\n * Pluggable execution engine for L2 `ScriptBody` payloads coming from\n * `@objectstack/spec/data` `HookBodySchema`.\n *\n * ## Engine choice — quickjs-emscripten\n *\n * Two candidates were evaluated:\n *\n * | Property | isolated-vm | quickjs-emscripten |\n * |-------------------------|----------------------------|---------------------------|\n * | True isolation | ✅ V8 isolate | ✅ separate JS heap |\n * | Memory limit enforced | ✅ hard cap | ⚠️ soft (engine-level) |\n * | CPU timeout enforced | ✅ hard kill | ✅ interrupt handler |\n * | Native dependency | ❌ requires N-API build | ✅ pure WASM |\n * | Edge runtime support | ❌ Cloudflare/Vercel ban | ✅ runs on every JS host |\n * | Cold-start cost | ~50ms (native init) | ~100ms (WASM init) |\n * | Per-invocation overhead | very low | low–medium |\n *\n * **Decision:** `quickjs-emscripten`.\n *\n * The single biggest constraint for ObjectStack is that `objectos` ships as a\n * pure-JS runtime so it can run on serverless edges, Cloudflare Workers,\n * Vercel Edge, Deno Deploy, plus traditional Node servers. `isolated-vm`\n * disqualifies us from every edge target because of its N-API dependency.\n * The performance penalty of QuickJS for short hook/action bodies (typically\n * <1 ms of script logic) is dominated by `ctx.api` round-trips anyway, so the\n * trade is favorable.\n *\n * The engine sits behind the `ScriptRunner` interface — if a host environment\n * can guarantee node-only deployment we can plug `isolated-vm` later without\n * touching call sites.\n */\n\nimport type { HookBody, ScriptBody, ExpressionBody } from '@objectstack/spec/data';\n\n/**\n * Identity / origin information used by the sandbox for diagnostics, capability\n * gating, and audit logs.\n */\nexport interface ScriptOrigin {\n /** Whether the body is attached to a Hook or an Action. */\n kind: 'hook' | 'action';\n /** Object the hook/action targets, when applicable. */\n object?: string;\n /** Hook/Action name, used in error messages and traces. */\n name: string;\n}\n\n/**\n * Context object exposed to the script. The shape mirrors `HookContext` /\n * `ActionContext` from `@objectstack/spec`. The sandbox copies a subset of\n * these into the isolated heap; capability checks gate which methods are\n * actually wired up.\n */\nexport interface ScriptContext {\n input: unknown;\n previous?: unknown;\n user?: unknown;\n session?: unknown;\n /**\n * The lifecycle event name the hook is firing for (e.g. `beforeInsert`,\n * `afterUpdate`). Required for hooks that subscribe to multiple events\n * and dispatch on event name.\n */\n event?: string;\n /** The object the hook/action targets — surfaces from `HookContext.object`. */\n object?: string;\n /**\n * Action only: the record id passed in the action invocation URL\n * (`POST /api/v1/actions/:object/:action/:recordId`). Hooks always have\n * the record on `input` so this stays undefined for them.\n */\n recordId?: string;\n /**\n * Action only: the record loaded by the dispatcher before the action ran\n * (when the dispatcher pre-fetches it). May be undefined for actions\n * declared with `requiresRecord: false` or when no `recordId` was supplied.\n */\n record?: unknown;\n /** Engine-side `result` (only set for after* hooks). */\n result?: unknown;\n api?: unknown;\n log?: {\n info: (msg: string, data?: unknown) => void;\n warn: (msg: string, data?: unknown) => void;\n error: (msg: string, data?: unknown) => void;\n };\n crypto?: {\n randomUUID?: () => string;\n hash?: (algo: string, data: string | Uint8Array) => Promise<string>;\n };\n}\n\n/**\n * Result returned to the caller after script execution.\n * - For hooks the `value` is typically `undefined` (mutations happen on `ctx`).\n * - For actions the `value` is the script's return value.\n */\nexport interface ScriptResult {\n value: unknown;\n /** Total wall-clock time inside the sandbox, milliseconds. */\n durationMs: number;\n /**\n * Snapshot of `ctx.input` *as observed inside the VM after the script settled*.\n *\n * Hooks frequently mutate `ctx.input.x = y` directly without returning a value.\n * The runner dumps the post-execution `ctx.input` so the host body-runner can\n * write the mutations back through to the engine's `hookContext.input` (which\n * is itself usually a flat-record Proxy).\n *\n * `undefined` if the dump failed or the script context did not expose `input`.\n */\n mutatedInput?: Record<string, unknown>;\n}\n\nexport interface ScriptRunOptions {\n origin: ScriptOrigin;\n /** Hard timeout for this invocation. The smaller of body.timeoutMs and this wins. */\n timeoutMs?: number;\n /** Optional abort signal from the surrounding kernel. */\n signal?: AbortSignal;\n}\n\n/**\n * The sandbox engine contract. Implementations live under\n * `packages/runtime/src/sandbox/engines/`.\n */\nexport interface ScriptRunner {\n /** Execute an L1 expression. Pure, side-effect-free. */\n evalExpression(body: ExpressionBody, ctx: ScriptContext, opts: ScriptRunOptions): Promise<ScriptResult>;\n\n /** Execute an L2 sandboxed JS script body. */\n runScript(body: ScriptBody, ctx: ScriptContext, opts: ScriptRunOptions): Promise<ScriptResult>;\n\n /** Convenience dispatch on the discriminated union. */\n run(body: HookBody, ctx: ScriptContext, opts: ScriptRunOptions): Promise<ScriptResult>;\n\n /** Release any underlying VM resources. */\n dispose(): Promise<void>;\n}\n\n/**\n * Default no-op runner — throws on every call. The real engine is injected\n * during runtime bootstrap once `quickjs-emscripten` is wired in. This stub\n * lets the rest of the pipeline (loader, dispatcher, type plumbing) compile\n * and be unit-tested ahead of the engine landing.\n */\nexport class UnimplementedScriptRunner implements ScriptRunner {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n evalExpression(_body: ExpressionBody, _ctx: ScriptContext, _opts: ScriptRunOptions): Promise<ScriptResult> {\n return Promise.reject(new Error('ScriptRunner not configured: install a quickjs engine first.'));\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n runScript(_body: ScriptBody, _ctx: ScriptContext, _opts: ScriptRunOptions): Promise<ScriptResult> {\n return Promise.reject(new Error('ScriptRunner not configured: install a quickjs engine first.'));\n }\n run(body: HookBody, ctx: ScriptContext, opts: ScriptRunOptions): Promise<ScriptResult> {\n return body.language === 'expression'\n ? this.evalExpression(body, ctx, opts)\n : this.runScript(body, ctx, opts);\n }\n dispose(): Promise<void> {\n return Promise.resolve();\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nexport {\n UnimplementedScriptRunner,\n} from './script-runner.js';\nexport type {\n ScriptRunner,\n ScriptContext,\n ScriptOrigin,\n ScriptResult,\n ScriptRunOptions,\n} from './script-runner.js';\nexport { QuickJSScriptRunner, SandboxError } from './quickjs-runner.js';\nexport type { QuickJSScriptRunnerOptions } from './quickjs-runner.js';\nexport { hookBodyRunnerFactory, actionBodyRunnerFactory } from './body-runner.js';\n"],"mappings":"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","names":["resolvePath","import_node_path","wrapped","resolve","import_data","resolve","resolvePath","DriverPlugin","AppPlugin","import_node_path","import_node_fs","import_types","import_core","import_node_path","import_node_fs","resolvePath","import_core","import_system","import_shared","safeJsonParse","ql","protocol","labels","result","import_observability","generateRequestId","import_observability","generateRequestId","ctx","import_node_path","entry","resolvePathNode","import_node_crypto","import_core","import_types","driver","seedProjectOrganization","seedProjectOwner","seedProjectMember","import_node_crypto","headers","body","import_promises","import_node_path","resolvePath","DriverPlugin","import_node_fs","import_node_path","import_types","SeedLoaderService","import_types"]}
|