@objectstack/runtime 9.9.0 → 9.10.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 +130 -100
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -24
- package/dist/index.d.ts +0 -24
- package/dist/index.js +100 -70
- package/dist/index.js.map +1 -1
- package/package.json +18 -18
package/dist/index.js.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/index.ts","../src/runtime.ts","../src/default-host.ts","../src/external-validation-plugin.ts","../src/http-dispatcher.ts","../src/api-exposure.ts","../src/security/api-key.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/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//\n// MOVED: SeedLoaderService now lives in @objectstack/objectql so the protocol's\n// `publishMetaItem` can materialize published `seed` metadata into rows on EVERY\n// publish path (per-ref REST publish, package publish-drafts, dispatcher) —\n// packages/rest cannot depend on runtime (runtime → rest), and objectql is the\n// layer that owns both the engine and the publish primitive. This shim keeps\n// the historical runtime import path working.\nexport { SeedLoaderService } from '@objectstack/objectql';\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 host promises settle)\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 // Drive the script's async continuations to completion. Each iteration\n // yields to the host event loop (so in-flight host promises settle and\n // resolve their VM-side deferred handles) and then drains the QuickJS job\n // queue. The ONLY bound on how long we wait is the deadline: a slow but\n // progressing script — many sequential host writes, or one write that\n // synchronously drives a downstream record-change automation — must be\n // allowed to finish within its timeout, and a stuck / never-settling host\n // call is cut off here (the QuickJS interrupt handler can't fire while we\n // are parked on a host promise, so this deadline check is the backstop).\n // The previous fixed `pumps < 1000` cap fired in ~tens of ms on legitimate\n // work and surfaced as \"did not resolve after 1000 pump iterations\".\n let pumps = 0;\n for (;;) {\n // Yield to host event loop so any in-flight 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 (after ${pumps} pump iterations)`,\n );\n }\n pumps++;\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 as deferred-promise functions (see\n * {@link installApiMethod}) so they may return Promises (real ObjectQL\n * `find/count/insert/...` are async) without asyncify's single-unwind limit.\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 * Host-bound API method, exposed to the VM as an async function.\n *\n * IMPORTANT: this deliberately does NOT use `newAsyncifiedFunction`. Asyncify\n * unwinds the WASM stack while a host call is in flight, and the engine forbids\n * one asyncified call from running while another is unwound (\"the stack cannot\n * be unwound twice\"). A script that awaits two host calls in sequence — e.g. the\n * real `lead_apply_convert` action doing `findOne()` then `update()` — trips\n * exactly that: the second call is driven from a resumed continuation inside\n * `executePendingJobs` (a non-async frame), which corrupted the wasm heap\n * (`memory access out of bounds` / `p->ref_count == 0`) and, when it limped\n * along, blew the pump budget (\"did not resolve after 1000 pump iterations\").\n *\n * Instead we hand the VM a real QuickJS promise (a deferred) and settle it from\n * the host event loop. Sequential `await`s are then ordinary promises with no\n * stack unwinding, so any number of host calls compose safely; the pump loop in\n * {@link QuickJSScriptRunner.execute} drains the resulting jobs.\n *\n * The capability check runs synchronously at call time and surfaces inside the\n * 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.newFunction(method, (...argHandles) => {\n // Capability gate — throw synchronously so the VM sees a normal exception at\n // the call site (mirrors ctx.log / ctx.crypto gating).\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 // Dump args now, while the handles are alive — they are freed when this\n // function returns, long before the async work below runs.\n const args = argHandles.map((h) => vm.dump(h));\n\n const deferred = vm.newPromise();\n void (async () => {\n try {\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 if (!vm.alive) return; // VM disposed (e.g. timed out) before we settled.\n const h = jsonToHandle(vm, ret);\n deferred.resolve(h);\n h.dispose();\n } catch (err) {\n if (!vm.alive) return;\n const errH =\n err instanceof Error\n ? vm.newError({ name: err.name || 'Error', message: err.message })\n : vm.newError({ name: 'Error', message: String(err) });\n deferred.reject(errH);\n errH.dispose();\n }\n })();\n // The pump loop is the sole driver of executePendingJobs, so the resolution\n // propagates into the VM on a subsequent pump iteration — no nudge here, to\n // avoid any re-entrant executePendingJobs.\n return deferred.handle;\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 'docs', 'books',\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 seeds: 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 seeds: ${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 seeds: 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","// 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';\n// ADR-0006 generic kernel-resolution seam (retained framework contract; the\n// multi-tenant implementation lives in cloud `@objectstack/objectos-runtime`).\nexport type { KernelResolver } 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// Multi-tenant / cloud-operations code is NOT part of the framework\n// (ADR-0006). The MULTI-TENANT runtime — createObjectOSStack, the kernel\n// manager, environment registries, artifact fetching, the auth proxy,\n// per-environment kernel construction, platform SSO, marketplace\n// browse/install, the runtime-config endpoint — lives in the cloud\n// distribution (`@objectstack/objectos-runtime`). Phase 4 removed the\n// framework's duplicate cloud plugins (= cloud ADR-0007 ⑤); Phase 5\n// converged the dispatcher's environment resolution + kernel routing into\n// the single generic `KernelResolver` seam (exported above with\n// HttpDispatcher) — the only multi-tenant contract the framework retains.\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 { setPackageDisabled } from './package-state-store.js';\nimport { checkApiExposure } from './api-exposure.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';\nimport { generateApiKey } from './security/api-key.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 (set by the host's KernelResolver)\n dataDriver?: any; // IDataDriver - Resolved environment-scoped driver (set by the host's KernelResolver)\n /**\n * Dispatcher-provided hint for the host's {@link KernelResolver}: the\n * cleaned route path (API prefix stripped). Lets the resolver apply its\n * own path policy (e.g. skip env resolution for control-plane routes)\n * without re-deriving the dispatcher's URL handling.\n */\n routePath?: string;\n /**\n * Dispatcher-provided hint for the host's {@link KernelResolver}: the\n * UNVALIDATED environment-id candidate parsed from the scoped URL form\n * (`/environments/:id/...`) or the router's `params.environmentId`.\n * URL parsing is the dispatcher's routing convention, so it stays here;\n * validation (registry lookup) is the resolver's job.\n */\n urlEnvironmentId?: string;\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 * ADR-0006 generic kernel-resolution seam.\n *\n * A host (e.g. ObjectStack Cloud) injects a resolver to own per-request\n * kernel selection. The framework ships NO multi-tenant implementation — all\n * hostname→env strategy, the per-env kernel cache, and the control plane live\n * in the host distribution (`@objectstack/objectos-runtime`). When no resolver\n * is injected the dispatcher serves every request from its single\n * `defaultKernel` (single-environment mode).\n *\n * Returning `undefined` routes the request to `defaultKernel` — resolvers use\n * this for control-plane / unscoped / single-environment requests.\n *\n * As of ADR-0006 Phase 5 the resolver owns the ENTIRE per-request environment\n * resolution, not just kernel selection: the dispatcher no longer performs any\n * hostname / header / session → environment lookup of its own. The dispatcher\n * provides parsing hints on the context (`routePath`, `urlEnvironmentId`) and\n * expects the resolver to SET `context.environmentId` (and optionally\n * `context.dataDriver`) for scoped requests — downstream dispatcher stages\n * (project-membership enforcement, scope TTL touch, scoped service resolution)\n * key off `context.environmentId`.\n */\nexport interface KernelResolver {\n resolveKernel(\n context: HttpProtocolContext,\n defaultKernel: ObjectKernel,\n ): Promise<ObjectKernel | undefined> | ObjectKernel | undefined;\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 generic kernel-resolution seam (ADR-0006). The SOLE\n * multi-tenant hook: the host's resolver owns env resolution + kernel\n * selection per request (see {@link KernelResolver}). Falls back to\n * `resolveService('kernel-resolver')`. Hosts that register none run\n * single-environment on `defaultKernel`. (The legacy `kernelManager`\n * option and the dispatcher's built-in hostname/header/session\n * resolution were removed in ADR-0006 Phase 5 — that strategy lives in\n * the cloud distribution's resolver now.)\n */\n kernelResolver?: KernelResolver;\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 defaultProject?: { environmentId: string; orgId?: string };\n private kernelResolver?: KernelResolver;\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 /**\n * @param _envRegistryIgnored — RETIRED (ADR-0006 Phase 5). Environment\n * resolution moved behind the host's {@link KernelResolver}; the\n * positional parameter is kept so existing 3-arg callers keep compiling,\n * but its value is ignored.\n */\n constructor(kernel: ObjectKernel, _envRegistryIgnored?: unknown, 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.enforceMembership = options?.enforceProjectMembership ?? true;\n // ADR-0006 kernel-resolution seam — the host's resolver owns env\n // resolution + kernel selection. Optional service so single-environment\n // hosts that register none are unchanged.\n this.kernelResolver = options?.kernelResolver ?? resolveService('kernel-resolver');\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 * ADR-0046: `doc` list responses omit `content` by default — manuals\n * are the one metadata payload that grows unbounded, and the list\n * surface only needs `name` + `label`. `?include=content` opts back in\n * (single-item GET /metadata/doc/:name always returns the full body).\n */\n private slimDocList(type: string, data: any, query?: Record<string, string>): any {\n if (type !== 'doc' || query?.include === 'content') return data;\n const strip = (items: any[]) =>\n items.map((i) => {\n if (!i || typeof i !== 'object') return i;\n const { content: _content, ...rest } = i as Record<string, unknown>;\n return rest;\n });\n if (Array.isArray(data)) return strip(data);\n if (data && Array.isArray(data.items)) return { ...data, items: strip(data.items) };\n return data;\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 // ── Object-level API exposure gate (ADR-0049, #1889) ─────\n // Honour the object's `apiEnabled` / `apiMethods` declarations for\n // external traffic. System/internal contexts bypass — these flags\n // govern API *exposure*, not internal engine self-writes.\n if (!executionContext?.isSystem && params?.object) {\n let def: any;\n try {\n const meta = await this.resolveService('metadata', scopeId);\n def = await (meta as any)?.getObject?.(params.object);\n } catch {\n def = undefined; // fall open to schema defaults (apiEnabled=true)\n }\n const gate = checkApiExposure(def, action);\n if (!gate.allowed) {\n throw { statusCode: gate.status ?? 403, message: gate.reason ?? 'API access denied' };\n }\n }\n\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 * Handle an MCP request over the Streamable HTTP transport (`/mcp`).\n *\n * Gating + auth (fail-closed):\n * - **opt-in**: only served when `OS_MCP_SERVER_ENABLED=true` (single-env\n * runtime). Multi-tenant cloud overrides this gate per env. When off we\n * return 404 so the surface isn't advertised.\n * - **auth**: requires a principal already resolved by\n * `resolveExecutionContext` (the `sys_api_key` Bearer/header path or a\n * session). Anonymous → 401.\n *\n * Execution: the MCP runtime builds a stateless per-request server whose\n * object-CRUD tools run through {@link callData} bound to THIS request's\n * ExecutionContext — i.e. the exact permission + RLS path the REST API\n * uses. An external agent can never exceed the key's authority.\n */\n async handleMcp(body: any, context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n if (!HttpDispatcher.isMcpEnabled()) {\n return { handled: true, response: this.error('MCP server is not enabled for this environment', 404) };\n }\n\n const mcp: any = await this.resolveService('mcp', context.environmentId);\n if (!mcp || typeof mcp.handleHttpRequest !== 'function') {\n return { handled: true, response: this.error('MCP server is not available', 501) };\n }\n\n const ec = context.executionContext;\n if (!ec || (!ec.userId && !ec.isSystem)) {\n return { handled: true, response: this.error('Unauthorized: a valid API key is required', 401) };\n }\n\n // The MCP transport needs a Web-standard Request. The runtime HTTP\n // adapter may hand us a node/Hono-style req (plain `headers` object,\n // path-only `url`), so normalise it.\n const webRequest = this.toMcpWebRequest(context.request, body);\n if (!webRequest) {\n return { handled: true, response: this.error('MCP transport requires a standard HTTP request', 400) };\n }\n\n const bridge = this.buildMcpBridge(context);\n let webRes: Response;\n try {\n webRes = await mcp.handleHttpRequest(webRequest, { bridge, parsedBody: body });\n } catch (err: any) {\n return { handled: true, response: this.error(err?.message ?? 'MCP request failed', 500) };\n }\n\n // Convert the transport's buffered Web Response into the dispatcher's\n // `{ status, headers, body }` shape (JSON-response mode → fully buffered).\n const headers: Record<string, string> = {};\n try { webRes.headers.forEach((v, k) => { headers[k] = v; }); } catch { /* no headers */ }\n const text = await webRes.text().catch(() => '');\n let responseBody: any = null;\n if (text) {\n const ct = headers['content-type'] ?? '';\n if (ct.includes('application/json')) {\n try { responseBody = JSON.parse(text); } catch { responseBody = text; }\n } else {\n responseBody = text;\n }\n }\n return { handled: true, response: { status: webRes.status, headers, body: responseBody } };\n }\n\n /** Whether the MCP HTTP surface is opted in for this single-env runtime. */\n private static isMcpEnabled(): boolean {\n return typeof process !== 'undefined' && process.env?.OS_MCP_SERVER_ENABLED === 'true';\n }\n\n /**\n * Normalise the inbound request into a Web-standard `Request` for the MCP\n * transport. Accepts an already-Web `Request`, or a node/Hono-style req\n * (plain `headers` object, path-only `url`). Returns undefined only if the\n * shape is unusable. The body is carried separately via `parsedBody`, so a\n * GET/DELETE (no body) and a POST (JSON-RPC) both normalise cleanly.\n */\n private toMcpWebRequest(raw: any, parsedBody: any): Request | undefined {\n if (!raw) return undefined;\n // Already a Web Request.\n if (typeof raw.headers?.get === 'function' && typeof raw.url === 'string' && typeof raw.method === 'string') {\n return raw as Request;\n }\n try {\n const method = String(raw.method ?? 'POST').toUpperCase();\n\n // Normalise headers (plain object or Headers-like).\n const headers = new Headers();\n const h = raw.headers;\n if (h) {\n if (typeof h.forEach === 'function') {\n h.forEach((v: any, k: any) => { if (v != null) headers.set(String(k), String(v)); });\n } else {\n for (const k of Object.keys(h)) {\n const v = (h as any)[k];\n if (v != null) headers.set(k, Array.isArray(v) ? v.join(',') : String(v));\n }\n }\n }\n\n // Build an absolute URL (node req.url is path-only).\n let url: string;\n try {\n url = new URL(String(raw.url)).toString();\n } catch {\n const host = headers.get('host') || 'mcp.local';\n const path = typeof raw.url === 'string' && raw.url ? raw.url : '/api/v1/mcp';\n url = `https://${host}${path.startsWith('/') ? path : `/${path}`}`;\n }\n\n const init: { method: string; headers: Headers; body?: string } = { method, headers };\n if (method !== 'GET' && method !== 'HEAD' && method !== 'DELETE') {\n init.body = typeof parsedBody === 'string' ? parsedBody : JSON.stringify(parsedBody ?? {});\n }\n return new Request(url, init);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Build a principal-bound {@link McpDataBridge}: every method runs AS the\n * request's ExecutionContext through {@link callData} (RLS/permissions) and\n * the per-env metadata service. Keeps the MCP tool layer free of any direct\n * engine access.\n */\n private buildMcpBridge(context: HttpProtocolContext): any {\n const ec = context.executionContext;\n const envId = context.environmentId;\n const driver = (context as any).dataDriver;\n const callData = this.callData.bind(this);\n const getMeta = () => this.resolveService('metadata', envId);\n\n return {\n listObjects: async () => {\n const meta: any = await getMeta();\n const objs: any[] = (await meta?.listObjects?.()) ?? [];\n return objs.map((o) => ({\n name: o.name,\n label: o.label ?? o.name,\n fieldCount: o.fields ? Object.keys(o.fields).length : undefined,\n }));\n },\n describeObject: async (name: string) => {\n const meta: any = await getMeta();\n const def: any = await meta?.getObject?.(name);\n if (!def) return null;\n const fields = def.fields ?? {};\n return {\n name: def.name,\n label: def.label ?? def.name,\n fields: Object.entries(fields).map(([k, f]: [string, any]) => ({\n name: k,\n type: f?.type,\n label: f?.label ?? k,\n required: f?.required ?? false,\n })),\n enableFeatures: def.enable ?? {},\n };\n },\n query: async (object: string, o: any) => {\n const query: any = {};\n if (o?.where) query.where = o.where;\n if (o?.fields) query.fields = o.fields;\n if (typeof o?.limit === 'number') query.limit = o.limit;\n if (typeof o?.offset === 'number') query.offset = o.offset;\n if (o?.orderBy) query.orderBy = o.orderBy;\n return await callData('query', { object, query }, driver, envId, ec);\n },\n get: async (object: string, id: string) => {\n const res: any = await callData('get', { object, id }, driver, envId, ec);\n return res?.record ?? res ?? null;\n },\n create: async (object: string, data: any) =>\n await callData('create', { object, data }, driver, envId, ec),\n update: async (object: string, id: string, data: any) =>\n await callData('update', { object, id, data }, driver, envId, ec),\n remove: async (object: string, id: string) =>\n await callData('delete', { object, id }, driver, envId, ec),\n };\n }\n\n /**\n * Generate a `sys_api_key` and return the raw secret EXACTLY ONCE\n * (`POST /keys`). This is the only mint path — the raw key is never stored\n * (only its sha256 hash) and never re-displayable.\n *\n * Security (zero-tolerance):\n * - Requires an authenticated principal; `user_id` is PINNED to that\n * caller and is NEVER read from the request body (no impersonation).\n * - Body is whitelisted to `name` (+ optional `expires_at`); any\n * `key` / `id` / `user_id` / `revoked` in the body is ignored, so a\n * caller cannot forge a known-secret or escalate.\n * - `scopes` are intentionally NOT accepted from the body in v1: the\n * verify path ADDS scopes to the principal's permissions, so honouring\n * arbitrary body scopes would be an escalation vector. A generated key\n * therefore acts exactly AS the caller (via `user_id` resolution).\n * Narrowing/scoped keys need subset-enforcement — deferred.\n * - The raw key and its hash never enter logs or error messages.\n * - The row is written with an elevated `{ isSystem: true }` context\n * because `sys_api_key` is protection-locked; safe because the row's\n * contents are fully server-controlled (user_id pinned to caller).\n */\n async handleKeys(method: string, body: any, context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n if (method !== 'POST') {\n return { handled: true, response: this.error('Method not allowed', 405) };\n }\n\n const ec = context.executionContext;\n if (!ec || !ec.userId) {\n return { handled: true, response: this.error('Unauthorized: sign in to generate an API key', 401) };\n }\n\n // ── Whitelist the body. Only `name` and optional `expires_at`. ──\n const rawName = typeof body?.name === 'string' ? body.name.trim() : '';\n const name = rawName || 'API Key';\n\n let expiresAt: string | undefined;\n if (body?.expires_at != null && body.expires_at !== '') {\n const ms = typeof body.expires_at === 'number'\n ? (body.expires_at < 1e12 ? body.expires_at * 1000 : body.expires_at)\n : Date.parse(String(body.expires_at));\n if (Number.isNaN(ms)) {\n return { handled: true, response: this.error('Invalid expires_at: must be a parseable date', 400) };\n }\n if (ms <= Date.now()) {\n return { handled: true, response: this.error('Invalid expires_at: must be in the future', 400) };\n }\n expiresAt = new Date(ms).toISOString();\n }\n\n const ql = (await this.getObjectQLService(context.environmentId))\n ?? (await this.resolveService('objectql', context.environmentId));\n if (!ql || typeof ql.insert !== 'function') {\n return { handled: true, response: this.error('Data service not available', 503) };\n }\n\n // Generate AFTER validation so we never mint on a rejected request.\n const generated = generateApiKey();\n\n // Server-controlled row. user_id is pinned to the caller; only the hash\n // is persisted. NOTHING from the body can set key/id/user_id/revoked.\n const row: Record<string, unknown> = {\n name,\n key: generated.hash,\n prefix: generated.prefix,\n user_id: ec.userId,\n revoked: false,\n };\n if (expiresAt) row.expires_at = expiresAt;\n\n let inserted: any;\n try {\n inserted = await ql.insert('sys_api_key', row, { context: { isSystem: true } });\n } catch {\n // Never surface the underlying error (could echo row contents).\n return { handled: true, response: this.error('Failed to create API key', 500) };\n }\n const id = inserted?.id ?? (Array.isArray(inserted) ? inserted[0]?.id : undefined);\n\n // Raw key returned ONCE. Do not log it.\n return {\n handled: true,\n response: {\n status: 201,\n body: {\n success: true,\n data: {\n id,\n name,\n prefix: generated.prefix,\n key: generated.raw,\n ...(expiresAt ? { expires_at: expiresAt } : {}),\n },\n },\n },\n };\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 * Attach the dispatcher's parsing hints for the host's\n * {@link KernelResolver} (ADR-0006 Phase 5).\n *\n * Environment RESOLUTION (hostname / x-environment-id / session /\n * org-default / single-env-default → environment + driver) is owned by\n * the host's resolver — the dispatcher no longer touches an environment\n * registry. What stays here is pure URL parsing (the dispatcher's own\n * routing convention): the scoped-path environment-id candidate and the\n * cleaned route path, both UNVALIDATED.\n */\n private prepareResolverHints(context: HttpProtocolContext, path: string): void {\n context.routePath = path;\n const urlEnvironmentId = this.extractEnvironmentIdFromPath(path)\n ?? context.request?.params?.environmentId;\n if (urlEnvironmentId) context.urlEnvironmentId = String(urlEnvironmentId);\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 // Public share-link resolve/messages — the token IS the authorisation,\n // so never gate them on project membership (a signed-in non-member\n // opening a public link must not be 403'd before the token handler runs).\n if (/(^|\\/)share-links\\/[^/]+\\/(resolve|messages)$/.test(path)) 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 // MCP (Streamable HTTP) is opt-in per env — only advertised\n // when OS_MCP_SERVER_ENABLED=true so the surface isn't exposed\n // by default. The objectui Integrations page reads this.\n mcp: HttpDispatcher.isMcpEnabled() ? `${prefix}/mcp` : 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 // ADR-0033 draft-overlay preview: `?preview=draft` makes the\n // detail read prefer a pending draft (falling back to active).\n // Admin gating is layered on top in a follow-up (step 2).\n const previewDrafts = query?.preview === 'draft';\n const data = await protocol.getMetaItem({ type: singularType, name, packageId, organizationId, previewDrafts });\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 // ADR-0048 — thread `?package=` so single-item resolution is\n // package-scoped (prefer-local), matching list resolution.\n const data = await (metaSvc as any).getItem(singularType, name, packageId);\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 // ADR-0033 draft-overlay preview: `?preview=draft` overlays\n // pending drafts on the active list so an (admin) reviewer can\n // render the console off drafts before publishing.\n const previewDrafts = query?.preview === 'draft';\n const data = await protocol.getMetaItems({ type: typeOrName, packageId, organizationId, previewDrafts });\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(this.slimDocList(typeOrName, data, query)) };\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: this.slimDocList(typeOrName, items, query) }) };\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. A\n // registered KernelResolver marks this host as multi-tenant (ADR-0006\n // Phase 5 — previously signalled by the env-registry service): a\n // data-plane request that the resolver did not attach to an\n // environment must not silently fall through to the host kernel.\n if (!_context.dataDriver && this.kernelResolver) {\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 // Publishing a `seed` draft is what actually loads its\n // rows. The objectql protocol now batch-applies seeds\n // inside `publishPackageDrafts` itself (so EVERY publish\n // path — incl. the per-ref REST publish — materializes\n // data) and reports under `seedApplied`. Only fall back\n // to the route-level apply for custom protocols that\n // don't self-apply — never run both, or an externalId-less\n // seed would double-insert.\n if ((result as any)?.seedApplied === undefined) {\n try {\n const seedNames = ((result as any)?.published ?? [])\n .filter((p: any) => p?.type === 'seed')\n .map((p: any) => p.name as string);\n if (seedNames.length > 0) {\n (result as any).seedApplied = await this.applyPublishedSeeds(\n seedNames,\n organizationId,\n _context,\n );\n }\n } catch (e: any) {\n (result as any).seedApplied = { success: false, error: e?.message ?? 'seed apply failed' };\n }\n }\n // ADR-0045: \"Publish\" makes the package live AND visible.\n // A materialized (additive) build has no drafts left to\n // promote — its app sits at `hidden: true` awaiting the\n // visibility flip. Unhide every hidden app bound to this\n // package so ONE publish verb serves both regimes (the\n // caller never needs to know how the package was built).\n // Best-effort: a custom protocol without the meta\n // primitives keeps plain draft-publish semantics.\n try {\n if (\n typeof (protocol as any).getMetaItems === 'function' &&\n typeof (protocol as any).saveMetaItem === 'function'\n ) {\n const appsRes = await (protocol as any).getMetaItems({\n type: 'app',\n packageId: id,\n ...(organizationId ? { organizationId } : {}),\n });\n const apps: any[] = Array.isArray(appsRes)\n ? appsRes\n : Array.isArray((appsRes as any)?.items) ? (appsRes as any).items : [];\n const unhidden: string[] = [];\n for (const app of apps) {\n if (app && typeof app === 'object' && app.hidden === true && typeof app.name === 'string') {\n await (protocol as any).saveMetaItem({\n type: 'app',\n name: app.name,\n item: { ...app, hidden: false },\n packageId: id,\n ...(organizationId ? { organizationId } : {}),\n ...(body?.actor ? { actor: body.actor } : {}),\n });\n unhidden.push(app.name);\n }\n }\n if (unhidden.length > 0) (result as any).unhiddenApps = unhidden;\n }\n } catch (e: any) {\n (result as any).unhideError = e?.message ?? 'visibility flip failed';\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/discard-drafts → drop every pending DRAFT bound\n // to the package, reverting it to its last published baseline\n // (\"abandon all my changes\"). NON-destructive: active metadata and\n // physical tables are untouched. Routes through the sys_metadata\n // path (no metadata-service dependency, unlike /revert below).\n if (parts.length === 2 && parts[1] === 'discard-drafts' && m === 'POST') {\n const id = decodeURIComponent(parts[0]);\n const protocol = await this.resolveService('protocol');\n if (protocol && typeof (protocol as any).discardPackageDrafts === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const result = await (protocol as any).discardPackageDrafts({\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 discarding 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 → delete the package. Unregisters it from the\n // in-memory registry AND removes its persisted sys_metadata rows\n // (active + draft), tearing down each object's physical table by\n // default. `?keepData=true` preserves object tables (metadata-only\n // delete). Use case: \"I don't want this package anymore.\"\n if (parts.length === 1 && m === 'DELETE') {\n const id = decodeURIComponent(parts[0]);\n const registryRemoved = registry.uninstallPackage(id);\n\n // Persisted removal (AI/runtime packages live in sys_metadata, not\n // just the in-memory registry — the registry uninstall alone would\n // leave the rows and tables behind).\n let persisted: unknown = undefined;\n const protocol = await this.resolveService('protocol');\n if (protocol && typeof (protocol as any).deletePackage === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const keepData = query?.keepData === 'true' || query?.keepData === '1';\n persisted = await (protocol as any).deletePackage({\n packageId: id,\n ...(organizationId ? { organizationId } : {}),\n ...(keepData ? { keepData: true } : {}),\n });\n } catch (e: any) {\n return { handled: true, response: this.error(e.message, e.statusCode || 500) };\n }\n }\n\n const deletedCount = (persisted as any)?.deletedCount ?? 0;\n if (!registryRemoved && deletedCount === 0) {\n return { handled: true, response: this.error(`Package '${id}' not found`, 404) };\n }\n return { handled: true, response: this.success({ success: true, registryRemoved, persisted }) };\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 * Apply just-published `seed` metadata: load each seed's rows into its\n * target object so publishing a seed draft makes the data live (the runtime\n * counterpart to staging it). Reads each seed body via the protocol, then\n * runs the {@link SeedLoaderService} for the active org. Best-effort and\n * idempotent (upsert) — callers must never let this fail the publish.\n *\n * Lives at the runtime layer (not in the objectql publish primitive)\n * because the seed loader needs the data engine + metadata service, which\n * objectql cannot depend on without a layering cycle.\n */\n private async applyPublishedSeeds(\n names: string[],\n organizationId: string | undefined,\n _context: HttpProtocolContext,\n ): Promise<{ success: boolean; inserted?: number; updated?: number; errors?: unknown[]; error?: string }> {\n const protocol: any = await this.resolveService('protocol');\n const metadata: any = await this.getService(CoreServiceName.enum.metadata);\n const ql: any = await this.resolveService('objectql');\n if (!protocol || typeof protocol.getMetaItem !== 'function' || !ql || !metadata) {\n return { success: false, error: 'seed apply: required services unavailable' };\n }\n const datasets: any[] = [];\n const readErrors: string[] = [];\n for (const name of names) {\n // Read the just-published seed body. Try the active org first, then\n // fall back to an env-wide read — a workspace seed is often stored\n // org-wide (organization_id IS NULL), and resolving the wrong scope\n // here is what silently produced \"0 rows loaded\".\n const attempts = organizationId\n ? [{ type: 'seed', name, organizationId }, { type: 'seed', name }]\n : [{ type: 'seed', name }];\n let item: any;\n for (const args of attempts) {\n try {\n item = await protocol.getMetaItem(args);\n if (item) break;\n } catch (e) {\n readErrors.push(`read ${name}: ${(e as Error)?.message ?? String(e)}`);\n }\n }\n // protocol.getMetaItem (called directly, unlike the HTTP endpoint\n // which unwraps) returns a WRAPPER: `{ type, name, item, lock,\n // editable, … }` — the seed body (object/records) lives under\n // `.item`. Tolerate the wrapper (`.item`) plus the body-direct and\n // `.metadata`/`.body` shapes other protocols may return.\n const seed = item?.object && Array.isArray(item?.records)\n ? item\n : (item?.item ?? item?.metadata ?? item?.body);\n if (seed?.object && Array.isArray(seed?.records)) {\n datasets.push(seed);\n } else {\n readErrors.push(`seed \"${name}\" body unreadable (keys: ${item ? Object.keys(item).join(',') : 'none'})`);\n }\n }\n // Seeds were published but none could be read back → surface it (do NOT\n // report success with 0 rows, which hides the failure).\n if (datasets.length === 0) {\n return { success: false, inserted: 0, updated: 0, error: 'seed apply: no readable seed bodies', errors: readErrors };\n }\n\n const { SeedLoaderService } = await import('./seed-loader.js');\n const { SeedLoaderRequestSchema } = await import('@objectstack/spec/data');\n const loader = new SeedLoaderService(ql, metadata, (this as any).logger ?? console);\n const request = SeedLoaderRequestSchema.parse({\n seeds: datasets,\n config: {\n defaultMode: 'upsert',\n multiPass: true,\n ...(organizationId ? { organizationId } : {}),\n },\n });\n const r = await loader.load(request);\n return {\n success: r.success,\n inserted: r.summary.totalInserted,\n updated: r.summary.totalUpdated,\n errors: [...readErrors, ...(r.errors ?? [])],\n };\n }\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). Routed via the\n // host's KernelResolver (ADR-0006 Phase 5) — same seam as handle().\n let projectQl: any = null;\n if (this.kernelResolver && _context.environmentId && _context.environmentId !== 'platform') {\n try {\n const projectKernel: any = await this.kernelResolver.resolveKernel(_context, this.defaultKernel);\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 * Share-link capability tokens — \"anyone with the link\" publication of a\n * single record (ADR-0047). Mirrors the per-env service-dispatch pattern\n * used by {@link handleI18n} / {@link handleAI}: the `shareLinks` service\n * is resolved from the request's environment kernel, so links live in (and\n * resolve against) the same per-environment database that owns the record.\n * This branch owns URL parsing and the auth/public split.\n *\n * POST /share-links → create a link (authenticated)\n * GET /share-links?object&recordId → list the caller's links (authenticated)\n * DELETE /share-links/:idOrToken → revoke (authenticated)\n * GET /share-links/:token/resolve → resolve token → record (PUBLIC)\n * GET /share-links/:token/messages → ai_conversations messages (PUBLIC)\n *\n * The resolve / messages routes are intentionally public — the token IS\n * the authorisation. The underlying record is fetched with a SYSTEM\n * context (per-env RLS is bypassed because the token gates access), and\n * `redactFields` are stripped before the record leaves the server.\n */\n async handleShareLinks(\n subPath: string,\n method: string,\n body: any,\n query: any,\n context: HttpProtocolContext,\n ): Promise<HttpDispatcherResult> {\n const svc: any = await this.resolveService('shareLinks', context.environmentId);\n if (!svc) {\n return { handled: true, response: this.error('Sharing is not configured for this environment', 501) };\n }\n\n const SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n const m = method.toUpperCase();\n const parts = subPath.replace(/^\\/+/, '').split('/').filter(Boolean);\n const ec: any = context.executionContext;\n const callerCtx = { userId: ec?.userId as string | undefined, tenantId: ec?.tenantId as string | undefined };\n\n const headerOf = (name: string): string | undefined => {\n const h = context.request?.headers;\n if (!h) return undefined;\n const v = typeof h.get === 'function' ? h.get(name) : (h[name] ?? h[name.toLowerCase()]);\n return Array.isArray(v) ? v[0] : (v ?? undefined);\n };\n const sendErr = (status: number, code: string, msg: string): HttpDispatcherResult => ({\n handled: true,\n response: this.error(msg, status, { code }),\n });\n // Engine for fetching the shared record + token probes — the same\n // per-env ObjectQL the shareLinks service is bound to.\n const getEngine = async (): Promise<any> => {\n // Read objectql from the request's RESOLVED (per-env) kernel — the\n // same engine SharingServicePlugin bound the shareLinks service to,\n // so the shared record + messages live in the SAME store as\n // sys_share_link. `resolveService('objectql', env)` can hand back a\n // different (host/scoped) engine that lacks the per-env rows.\n try {\n const k: any = this.kernel;\n const e = typeof k?.getServiceAsync === 'function'\n ? await k.getServiceAsync('objectql')\n : k?.getService?.('objectql');\n if (e) return e;\n } catch { /* fall through to scoped resolution */ }\n return this.resolveService('objectql', context.environmentId);\n };\n const asArray = (rows: any): any[] => (Array.isArray(rows) ? rows : Array.isArray(rows?.value) ? rows.value : []);\n const applyRedaction = (record: any, redactFields: string[]): any => {\n if (!record || typeof record !== 'object' || redactFields.length === 0) return record;\n const out: any = {};\n for (const [k, v] of Object.entries(record)) {\n if (redactFields.includes(k)) continue;\n out[k] = v;\n }\n return out;\n };\n\n try {\n // ── PUBLIC: resolve a token → record ──────────────────────────\n if (parts.length === 2 && parts[1] === 'resolve' && m === 'GET') {\n const token = decodeURIComponent(parts[0]);\n const signedInUserId = ec?.userId;\n const recipientEmail = typeof query?.email === 'string' ? query.email : undefined;\n const providedPassword =\n typeof query?.password === 'string' ? (query.password as string) : headerOf('x-share-password');\n\n const resolved = await svc.resolveToken(token, { signedInUserId, recipientEmail, providedPassword });\n if (!resolved) {\n // Probe the row to return a more useful status (401 vs 410 vs 404).\n const engine = await getEngine();\n const probe = engine\n ? asArray(await engine.find('sys_share_link', { where: { token }, limit: 1, context: SYSTEM_CTX } as any))\n : [];\n const row = probe[0] ?? null;\n const live = row && !row.revoked_at && (!row.expires_at || Date.parse(row.expires_at) > Date.now());\n if (live && row.password_hash) {\n return sendErr(401, providedPassword ? 'WRONG_PASSWORD' : 'NEEDS_PASSWORD',\n providedPassword ? 'Incorrect password' : 'This link requires a password');\n }\n if (live && row.audience === 'signed_in' && !signedInUserId) {\n return sendErr(401, 'SIGN_IN_REQUIRED', 'Please sign in to view this link');\n }\n if (row && (row.revoked_at || (row.expires_at && Date.parse(row.expires_at) <= Date.now()))) {\n return sendErr(410, 'EXPIRED_OR_REVOKED', 'Share link has expired or been revoked');\n }\n return sendErr(404, 'INVALID_OR_EXPIRED', 'Share link is invalid, expired, or revoked');\n }\n\n const engine = await getEngine();\n const rows = engine\n ? asArray(await engine.find(resolved.link.object_name, { where: { id: resolved.link.record_id }, limit: 1, context: SYSTEM_CTX } as any))\n : [];\n const record = rows[0] ?? null;\n if (!record) return sendErr(410, 'RECORD_GONE', 'The shared record no longer exists');\n\n return {\n handled: true,\n response: this.success({\n record: applyRedaction(record, resolved.redactFields),\n link: {\n id: resolved.link.id,\n token: resolved.link.token,\n object_name: resolved.link.object_name,\n record_id: resolved.link.record_id,\n permission: resolved.link.permission,\n audience: resolved.link.audience,\n expires_at: resolved.link.expires_at,\n label: resolved.link.label,\n created_at: resolved.link.created_at,\n },\n redactFields: resolved.redactFields,\n }),\n };\n }\n\n // ── PUBLIC: ai_conversations messages for a resolved token ────\n if (parts.length === 2 && parts[1] === 'messages' && m === 'GET') {\n const token = decodeURIComponent(parts[0]);\n const providedPassword =\n typeof query?.password === 'string' ? (query.password as string) : headerOf('x-share-password');\n const resolved = await svc.resolveToken(token, { signedInUserId: ec?.userId, providedPassword });\n if (!resolved) return sendErr(404, 'NOT_FOUND', 'Share link not found');\n if (resolved.link.object_name !== 'ai_conversations') {\n return sendErr(400, 'UNSUPPORTED', 'This share link does not expose messages');\n }\n const engine = await getEngine();\n const rows = engine\n ? asArray(await engine.find('ai_messages', {\n where: { conversation_id: resolved.link.record_id },\n sort: [{ field: 'created_at', order: 'asc' }],\n limit: 500,\n context: SYSTEM_CTX,\n } as any))\n : [];\n return { handled: true, response: this.success(rows) };\n }\n\n // ── AUTHENTICATED: create / list / revoke ─────────────────────\n if (!callerCtx.userId) return sendErr(401, 'UNAUTHENTICATED', 'Sign in to manage share links');\n\n // POST /share-links → create\n if (parts.length === 0 && m === 'POST') {\n const b: any = body ?? {};\n if (!b.object || !b.recordId) return sendErr(400, 'VALIDATION_FAILED', 'object and recordId are required');\n const link = await svc.createLink(\n {\n object: b.object,\n recordId: b.recordId,\n permission: b.permission,\n audience: b.audience,\n expiresAt: b.expiresAt ?? null,\n emailAllowlist: b.emailAllowlist,\n password: b.password,\n redactFields: b.redactFields,\n label: b.label,\n },\n callerCtx,\n );\n return { handled: true, response: { status: 201, body: { success: true, data: link, link } } };\n }\n\n // GET /share-links?object&recordId → list the caller's own links\n if (parts.length === 0 && m === 'GET') {\n const links = await svc.listLinks(\n {\n object: typeof query?.object === 'string' ? query.object : undefined,\n recordId: typeof query?.recordId === 'string' ? query.recordId : undefined,\n // Constrain to links the caller created so a guessed\n // recordId can never enumerate another user's tokens.\n createdBy: callerCtx.userId,\n includeRevoked: query?.includeRevoked === 'true' || query?.includeRevoked === '1',\n },\n callerCtx,\n );\n return { handled: true, response: { status: 200, body: { success: true, data: links, links } } };\n }\n\n // DELETE /share-links/:idOrToken → revoke\n if (parts.length === 1 && m === 'DELETE') {\n await svc.revokeLink(decodeURIComponent(parts[0]), callerCtx);\n return { handled: true, response: this.success({ ok: true }) };\n }\n\n return { handled: true, response: this.routeNotFound(`/share-links${subPath}`) };\n } catch (err: any) {\n return sendErr(err?.status ?? 500, err?.code ?? 'INTERNAL', err?.message ?? 'Share link request failed');\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 + Multi-Kernel Routing (ADR-0006 Phase 5) ──\n // The host's KernelResolver owns the whole step: it resolves the\n // request to an environment (hostname / header / session / defaults —\n // strategy lives in the cloud distribution), SETS\n // `context.environmentId` (+ `dataDriver`), and returns the kernel to\n // serve from. The dispatcher only contributes parsing hints. No\n // resolver registered → single-environment: every request serves from\n // `defaultKernel` with no environment context.\n this.prepareResolverHints(context, cleanPath);\n if (this.kernelResolver) {\n this.kernel = (await this.kernelResolver.resolveKernel(context, this.defaultKernel)) ?? this.defaultKernel;\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 === '/mcp' || cleanPath.startsWith('/mcp/') || cleanPath.startsWith('/mcp?')) {\n return this.handleMcp(body, context);\n }\n\n if (cleanPath === '/keys' || cleanPath.startsWith('/keys/') || cleanPath.startsWith('/keys?')) {\n return this.handleKeys(method, body, 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 // Share links — capability-token record sharing, dispatched to the\n // per-env `shareLinks` service (links + record live in the same kernel).\n if (cleanPath === '/share-links' || cleanPath.startsWith('/share-links/')) {\n return this.handleShareLinks(cleanPath.substring('/share-links'.length), 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 * Object-level API exposure gate (ADR-0049, #1889).\n *\n * Objects declare `apiEnabled` (default true) and an optional `apiMethods`\n * whitelist, but the HTTP/MCP data dispatch previously ignored both — an object\n * could not actually be hidden from the API, nor could its allowed operations\n * be restricted. This module decides, for a given data action, whether the\n * object's declared exposure permits it.\n *\n * Both fields are *additive restrictions* over a default-allow surface\n * (`apiEnabled` defaults true; absent `apiMethods` means \"all operations\").\n * Therefore an unresolvable object definition fails OPEN here — that matches\n * the schema defaults and avoids breaking traffic when metadata is briefly\n * unavailable. The gate is a no-op for system/internal contexts (callers pass\n * `isSystem` and skip this check entirely).\n */\n\n/** The exposure-relevant slice of an object definition. */\nexport interface ObjectApiDef {\n apiEnabled?: boolean;\n apiMethods?: string[] | null;\n}\n\nexport interface ApiExposureDecision {\n allowed: boolean;\n /** HTTP status to return when denied (404 hides, 405 = method not allowed). */\n status?: number;\n reason?: string;\n}\n\n/**\n * Map an internal `callData` action onto the spec `ApiMethod` vocabulary\n * (`object.zod.ts` → `ApiMethod`). Actions with no mapping are not gated by\n * `apiMethods` (they still respect `apiEnabled`).\n */\nconst ACTION_TO_API_METHOD: Record<string, string> = {\n create: 'create',\n get: 'get',\n update: 'update',\n delete: 'delete',\n query: 'list',\n find: 'list',\n batch: 'bulk',\n};\n\nexport function checkApiExposure(def: ObjectApiDef | null | undefined, action: string): ApiExposureDecision {\n // Unresolvable definition → fall open to the schema defaults.\n if (!def) return { allowed: true };\n\n // `apiEnabled: false` hides the object from the API entirely → 404.\n if (def.apiEnabled === false) {\n return { allowed: false, status: 404, reason: 'object is not exposed via the API' };\n }\n\n // `apiMethods` whitelist (when present and non-empty) restricts operations.\n const whitelist = def.apiMethods;\n if (Array.isArray(whitelist) && whitelist.length > 0) {\n const method = ACTION_TO_API_METHOD[action];\n // Only gate actions that map to a known ApiMethod; unmapped actions pass.\n if (method && !whitelist.includes(method)) {\n return {\n allowed: false,\n status: 405,\n reason: `API operation '${method}' is not allowed for this object`,\n };\n }\n }\n\n return { allowed: true };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * api-key — re-export of the shared `sys_api_key` primitives + verifier.\n *\n * The implementation now lives in `@objectstack/core/security` so BOTH inbound\n * surfaces — this runtime's dispatcher/MCP path (`resolveExecutionContext`) and\n * the REST data API (`@objectstack/rest`) — verify keys through the exact same\n * code, with no drift. (`rest` cannot import `runtime` — `runtime` depends on\n * `rest` — so the shared home must be a lower package both depend on: `core`.)\n *\n * This file preserves the historical `@objectstack/runtime` import surface.\n */\n\nexport {\n API_KEY_PREFIX,\n hashApiKey,\n generateApiKey,\n extractApiKey,\n parseScopes,\n isExpired,\n resolveApiKeyPrincipal,\n type GeneratedApiKey,\n type ApiKeyPrincipal,\n} from '@objectstack/core';\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>`) — a\n * hand-rolled check that hashes the inbound key and looks it up against the\n * `sys_api_key` system object by its at-rest hash, rejecting revoked or\n * expired keys. (better-auth 1.6.x ships no apiKey plugin.)\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\nimport { resolveApiKeyPrincipal } from './api-key.js';\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\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/** True for a valid IANA timezone name (e.g. `America/New_York`, `UTC`). */\nfunction isValidTimeZone(tz: string): boolean {\n try {\n new Intl.DateTimeFormat('en-US', { timeZone: tz });\n return true;\n } catch {\n return false;\n }\n}\n\n/** Coerce a stored preference/setting value to a valid IANA zone, or undefined. */\nfunction coerceTimeZone(value: unknown): string | undefined {\n const s = typeof value === 'string' ? value.trim() : value != null ? String(value).trim() : '';\n return s && isValidTimeZone(s) ? s : undefined;\n}\n\n/** Coerce a stored locale value to a non-empty BCP-47-ish string, or undefined. */\nfunction coerceLocale(value: unknown): string | undefined {\n const s = typeof value === 'string' ? value.trim() : value != null ? String(value).trim() : '';\n return s || undefined;\n}\n\n/**\n * Resolve the workspace localization defaults onto the ExecutionContext\n * (ADR-0053 Phase 2): reference `timezone` and `locale`.\n *\n * Canonical path is the `localization` SettingsManifest via the `settings`\n * service, whose cascade is platform default → global → tenant (ADR-0002: one\n * org per physical tenant; per-user overrides are intentionally out of scope\n * for v1). When the settings service or its namespace is unavailable (e.g. a\n * minimal deployment), fall back to a direct tenant-scoped `sys_setting` read,\n * then to the built-ins `UTC` / `en-US`.\n *\n * Every read is defensive — localization never blocks auth, and an invalid\n * zone falls through to the built-in.\n */\nasync function resolveLocalization(\n opts: ResolveOptions,\n ql: any,\n sctx: { tenantId?: string; userId?: string },\n): Promise<{ timezone: string; locale: string }> {\n // 1. Canonical — the `localization` manifest via the settings service.\n try {\n const settings: any = await opts.getService('settings');\n if (settings && typeof settings.get === 'function') {\n const [tzRes, localeRes] = await Promise.all([\n settings.get('localization', 'timezone', sctx).catch(() => undefined),\n settings.get('localization', 'locale', sctx).catch(() => undefined),\n ]);\n const tz = coerceTimeZone(tzRes?.value);\n const locale = coerceLocale(localeRes?.value);\n // A resolved value (incl. the manifest default) means the namespace is\n // live — trust it and skip the legacy direct read.\n if (tz || locale) return { timezone: tz ?? 'UTC', locale: locale ?? 'en-US' };\n }\n } catch {\n // settings service unavailable → fall through to the direct read\n }\n\n // 2. Fallback — direct tenant-scoped `sys_setting` rows (no settings service\n // registered, or namespace not loaded).\n const tzRows = await tryFind(ql, 'sys_setting', { namespace: 'localization', key: 'timezone', scope: 'tenant' }, 1);\n const localeRows = await tryFind(ql, 'sys_setting', { namespace: 'localization', key: 'locale', scope: 'tenant' }, 1);\n return {\n timezone: coerceTimeZone(tzRows[0]?.value) ?? 'UTC',\n locale: coerceLocale(localeRows[0]?.value) ?? 'en-US',\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 //\n // better-auth 1.6.x ships no apiKey plugin, so this is a hand-rolled\n // check: hash the inbound key, look it up against `sys_api_key` by the\n // at-rest hash, and reject revoked or expired keys. The raw key is never\n // stored or logged. Once resolved, the principal flows through the exact\n // same role/permission/RLS resolution as the session path below.\n // Verification is delegated to the shared `resolveApiKeyPrincipal`\n // (@objectstack/core), the SAME verifier the REST data API uses, so the\n // two surfaces never drift.\n const keyPrincipal = await resolveApiKeyPrincipal(await opts.getQl(), headers);\n if (keyPrincipal) {\n userId = keyPrincipal.userId;\n tenantId = keyPrincipal.tenantId;\n for (const scope of keyPrincipal.scopes) {\n if (!ctx.permissions!.includes(scope)) ctx.permissions!.push(scope);\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 // 4. Localization (ADR-0053 Phase 2) — reference timezone + locale resolved\n // once per request from the `localization` settings and carried on the\n // context. Consumers: formula today()/datetime, analytics date buckets,\n // email rendering. Absent config → UTC / en-US keeps current behavior.\n const localization = await resolveLocalization(opts, ql, { tenantId, userId });\n ctx.timezone = localization.timezone;\n ctx.locale = localization.locale;\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 // Discovery reflects MUTABLE runtime config (which routes/services\n // are live — e.g. `mcp` only when OS_MCP_SERVER_ENABLED=true). It\n // must never be cached by an edge/CDN, or a config change (enable\n // MCP) leaves clients reading a stale payload that still says the\n // route is absent — the Integrations UI then shows \"MCP not\n // enabled\" against a live server (cloud#152). The body is computed\n // fresh per request; the only staleness is the HTTP cache layer.\n res.header('Cache-Control', 'no-store');\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 // See the .well-known handler above: discovery must not be cached\n // (mutable runtime config; cloud#152 stale `routes.mcp`).\n res.header('Cache-Control', 'no-store');\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 // ── MCP (Streamable HTTP) + API keys (ADR-0036) ─────────────\n // Mounted explicitly (there is no catch-all) and routed through\n // dispatch() so the host's project-aware kernel swap + execution\n // context resolution run first. /mcp accepts POST (JSON-RPC), GET\n // (SSE) and DELETE (session end) — the transport reads the method\n // from the request, the dispatcher gates on OS_MCP_SERVER_ENABLED\n // and the resolved principal. NOTE: the dispatch() branches alone\n // are unreachable over HTTP without these registrations.\n const mountMcp = (method: 'GET' | 'POST' | 'DELETE') => {\n const register = method === 'GET' ? server.get : method === 'DELETE' ? server.delete : server.post;\n register.call(server, `${prefix}/mcp`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch(method, '/mcp', req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n };\n mountMcp('POST');\n mountMcp('GET');\n mountMcp('DELETE');\n\n server.post(`${prefix}/keys`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', '/keys', 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\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":["dirname","wrapped","resolvePath","mkdirSync","readEnvWithDeprecation","DriverPlugin","AppPlugin","ObjectKernel","resolvePath","existsSync","mkdirSync","writeFileSync","safeJsonParse","protocol","labels","SeedLoaderService","engine","result","generateRequestId","generateRequestId","ctx","readEnvWithDeprecation"]}
|
|
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/index.ts","../src/runtime.ts","../src/default-host.ts","../src/external-validation-plugin.ts","../src/http-dispatcher.ts","../src/api-exposure.ts","../src/security/api-key.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/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//\n// MOVED: SeedLoaderService now lives in @objectstack/objectql so the protocol's\n// `publishMetaItem` can materialize published `seed` metadata into rows on EVERY\n// publish path (per-ref REST publish, package publish-drafts, dispatcher) —\n// packages/rest cannot depend on runtime (runtime → rest), and objectql is the\n// layer that owns both the engine and the publish primitive. This shim keeps\n// the historical runtime import path working.\nexport { SeedLoaderService } from '@objectstack/objectql';\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 // Shared, per-invocation transaction state. `ctx.api.transaction(fn)` opens\n // it (routing subsequent ctx.api ops through the tx-scoped context) and\n // closes it on commit/rollback. The execute() finally consults it to roll\n // back a transaction the body left open (threw mid-tx, or timed out before\n // its commit/rollback settled).\n const txState: TxState = { api: null, handle: null, open: false };\n\n try {\n this.installCtx(vm, args.ctx, new Set(args.capabilities), args.origin, txState);\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 host promises settle)\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 // Drive the script's async continuations to completion. Each iteration\n // yields to the host event loop (so in-flight host promises settle and\n // resolve their VM-side deferred handles) and then drains the QuickJS job\n // queue. The ONLY bound on how long we wait is the deadline: a slow but\n // progressing script — many sequential host writes, or one write that\n // synchronously drives a downstream record-change automation — must be\n // allowed to finish within its timeout, and a stuck / never-settling host\n // call is cut off here (the QuickJS interrupt handler can't fire while we\n // are parked on a host promise, so this deadline check is the backstop).\n // The previous fixed `pumps < 1000` cap fired in ~tens of ms on legitimate\n // work and surfaced as \"did not resolve after 1000 pump iterations\".\n let pumps = 0;\n for (;;) {\n // Yield to host event loop so any in-flight 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 (after ${pumps} pump iterations)`,\n );\n }\n pumps++;\n }\n } finally {\n // If the body left a transaction open — it threw between begin and\n // commit/rollback, or the deadline cut the pump loop off while a tx was\n // live — roll it back before tearing down the VM, so the driver\n // connection isn't leaked with a half-applied transaction. Best-effort:\n // the script result (success or the original error) is already decided;\n // a rollback failure here must not mask it.\n if (txState.open && txState.handle != null) {\n const apiTx = args.ctx.api as Record<string, unknown> | undefined;\n const rollback = apiTx?.rollbackTransaction;\n if (typeof rollback === 'function') {\n try {\n await (rollback as (h: unknown) => Promise<void>).call(apiTx, txState.handle);\n } catch {\n /* best-effort cleanup — swallow so the real outcome surfaces */\n }\n }\n }\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 as deferred-promise functions (see\n * {@link installApiMethod}) so they may return Promises (real ObjectQL\n * `find/count/insert/...` are async) without asyncify's single-unwind limit.\n */\n private installCtx(\n vm: QuickJSAsyncContext,\n ctx: ScriptContext,\n caps: Set<HookBodyCapability>,\n origin: ScriptOrigin,\n txState: TxState,\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, txState);\n for (const m of WRITE) installApiMethod(vm, wrap, m, objectName, ctx, caps, 'api.write', origin, txState);\n return wrap;\n });\n vm.setProp(apiObj, 'object', objectFn);\n objectFn.dispose();\n\n // Transaction control. The VM-facing surface is a single `ctx.api.transaction(fn)`\n // (defined as JS sugar below); under the hood it drives three host leaves so\n // begin / commit / rollback each settle through the same deferred-promise +\n // pump mechanism every other host call uses (asyncify can't unwind twice).\n //\n // The handle is threaded EXPLICITLY through `txState` rather than via the\n // engine's ambient AsyncLocalStorage: the body runs across many host\n // event-loop turns, and ALS context does not survive those `setImmediate`\n // boundaries. While a tx is open, `installApiMethod` resolves its repository\n // from `txState.api` (the tx-scoped ScopedContext) so every op reuses the\n // one connection.\n const apiTx = ctx.api as Record<string, unknown> | undefined;\n const installTxLeaf = (name: string, run: () => Promise<void>): void => {\n const fn = vm.newFunction(name, () => {\n if (!caps.has('api.transaction')) {\n throw new SandboxError(\n `capability 'api.transaction' not granted to ${origin.kind} '${origin.name}' (called ctx.api.transaction)`,\n );\n }\n const deferred = vm.newPromise();\n void (async () => {\n try {\n await run();\n if (!vm.alive) return;\n deferred.resolve(vm.undefined);\n } catch (err) {\n if (!vm.alive) return;\n const errH =\n err instanceof Error\n ? vm.newError({ name: err.name || 'Error', message: err.message })\n : vm.newError({ name: 'Error', message: String(err) });\n deferred.reject(errH);\n errH.dispose();\n }\n })();\n return deferred.handle;\n });\n vm.setProp(apiObj, name, fn);\n fn.dispose();\n };\n\n installTxLeaf('__txBegin', async () => {\n if (txState.open) throw new SandboxError('nested ctx.api.transaction is not supported');\n const begin = apiTx?.beginTransaction;\n if (typeof begin === 'function') {\n const r = (await (begin as () => Promise<{ ctx: unknown; handle: unknown } | null>).call(apiTx)) ?? null;\n if (r) {\n txState.api = r.ctx as Record<string, unknown>;\n txState.handle = r.handle;\n }\n }\n // else (or null result): driver without tx support → degrade to\n // non-transactional execution, same as ScopedContext.transaction().\n txState.open = true;\n });\n\n installTxLeaf('__txCommit', async () => {\n const { handle, open } = txState;\n txState.api = null;\n txState.handle = null;\n txState.open = false;\n const commit = apiTx?.commitTransaction;\n if (open && handle != null && typeof commit === 'function') {\n await (commit as (h: unknown) => Promise<void>).call(apiTx, handle);\n }\n });\n\n installTxLeaf('__txRollback', async () => {\n const { handle, open } = txState;\n txState.api = null;\n txState.handle = null;\n txState.open = false;\n const rollback = apiTx?.rollbackTransaction;\n if (open && handle != null && typeof rollback === 'function') {\n await (rollback as (h: unknown) => Promise<void>).call(apiTx, handle);\n }\n });\n\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 // VM-side sugar: `ctx.api.transaction(async () => { … })`. Begin runs\n // OUTSIDE the try so a begin failure (e.g. missing capability) propagates\n // without attempting a rollback there is no transaction for. The body's\n // return value is forwarded; any throw triggers rollback then re-throws,\n // so the caller observes the original error.\n const sugar = vm.evalCode(\n `__ctx.api.transaction = async function (fn) {\n await __ctx.api.__txBegin();\n try {\n var r = await fn();\n await __ctx.api.__txCommit();\n return r;\n } catch (e) {\n await __ctx.api.__txRollback();\n throw e;\n }\n };`,\n );\n if (sugar.error) {\n const msg = vm.dump(sugar.error);\n sugar.error.dispose();\n throw new SandboxError(`failed to install ctx.api.transaction: ${formatErr(msg)}`);\n }\n sugar.value.dispose();\n }\n}\n\n/**\n * Per-invocation transaction state shared between {@link QuickJSScriptRunner.execute}\n * (which rolls back a tx the body left open) and the `ctx.api.transaction`\n * host leaves (which open/close it). `api` is the tx-scoped ScopedContext that\n * `installApiMethod` routes repository ops through while a tx is live; `handle`\n * is the driver transaction handle; `open` guards against nesting and tells the\n * finally block whether cleanup is owed.\n */\ninterface TxState {\n api: Record<string, unknown> | null;\n handle: unknown;\n open: boolean;\n}\n\n/**\n * Host-bound API method, exposed to the VM as an async function.\n *\n * IMPORTANT: this deliberately does NOT use `newAsyncifiedFunction`. Asyncify\n * unwinds the WASM stack while a host call is in flight, and the engine forbids\n * one asyncified call from running while another is unwound (\"the stack cannot\n * be unwound twice\"). A script that awaits two host calls in sequence — e.g. the\n * real `lead_apply_convert` action doing `findOne()` then `update()` — trips\n * exactly that: the second call is driven from a resumed continuation inside\n * `executePendingJobs` (a non-async frame), which corrupted the wasm heap\n * (`memory access out of bounds` / `p->ref_count == 0`) and, when it limped\n * along, blew the pump budget (\"did not resolve after 1000 pump iterations\").\n *\n * Instead we hand the VM a real QuickJS promise (a deferred) and settle it from\n * the host event loop. Sequential `await`s are then ordinary promises with no\n * stack unwinding, so any number of host calls compose safely; the pump loop in\n * {@link QuickJSScriptRunner.execute} drains the resulting jobs.\n *\n * The capability check runs synchronously at call time and surfaces inside the\n * 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 txState: TxState,\n): void {\n const fn = vm.newFunction(method, (...argHandles) => {\n // Capability gate — throw synchronously so the VM sees a normal exception at\n // the call site (mirrors ctx.log / ctx.crypto gating).\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 // Dump args now, while the handles are alive — they are freed when this\n // function returns, long before the async work below runs.\n const args = argHandles.map((h) => vm.dump(h));\n\n const deferred = vm.newPromise();\n void (async () => {\n try {\n // While a transaction is open, resolve the repository from the\n // tx-scoped context so this op reuses the transaction's connection;\n // otherwise use the base ctx.api. Read `txState` HERE (at call time,\n // inside the async body) — the tx may have opened after this method\n // was installed.\n const source = (txState.api ?? apiAny) as Record<string, unknown>;\n const proxy = (source.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 if (!vm.alive) return; // VM disposed (e.g. timed out) before we settled.\n const h = jsonToHandle(vm, ret);\n deferred.resolve(h);\n h.dispose();\n } catch (err) {\n if (!vm.alive) return;\n const errH =\n err instanceof Error\n ? vm.newError({ name: err.name || 'Error', message: err.message })\n : vm.newError({ name: 'Error', message: String(err) });\n deferred.reject(errH);\n errH.dispose();\n }\n })();\n // The pump loop is the sole driver of executePendingJobs, so the resolution\n // propagates into the VM on a subsequent pump iteration — no nudge here, to\n // avoid any re-entrant executePendingJobs.\n return deferred.handle;\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 { 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 'docs', 'books',\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 // No seed identity is provisioned. The platform never mints a\n // placeholder `usr_system`: seeds leave `owner_id` unset (or use\n // `cel`os.user.id``, which the loader resolves to NULL since the\n // owning admin does not exist yet), and the first-admin handoff\n // (`claimSeedOwnership`) re-owns those NULL rows to the promoted\n // admin. `os.org` is still derived from `organizationId` inside the\n // loader, independent of this.\n const seedIdentity = undefined;\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 seeds: datasetsNow,\n config: {\n defaultMode: 'upsert',\n multiPass: true,\n organizationId,\n // `os.org` is derived from organizationId inside\n // the loader. `seedIdentity` (os.user) is undefined\n // unless a seed embeds `cel`os.user.id`` — see the\n // lazy guard where it is resolved.\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 seeds: ${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 seeds: 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 * 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","// 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';\n// ADR-0006 generic kernel-resolution seam (retained framework contract; the\n// multi-tenant implementation lives in cloud `@objectstack/objectos-runtime`).\nexport type { KernelResolver } 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// Multi-tenant / cloud-operations code is NOT part of the framework\n// (ADR-0006). The MULTI-TENANT runtime — createObjectOSStack, the kernel\n// manager, environment registries, artifact fetching, the auth proxy,\n// per-environment kernel construction, platform SSO, marketplace\n// browse/install, the runtime-config endpoint — lives in the cloud\n// distribution (`@objectstack/objectos-runtime`). Phase 4 removed the\n// framework's duplicate cloud plugins (= cloud ADR-0007 ⑤); Phase 5\n// converged the dispatcher's environment resolution + kernel routing into\n// the single generic `KernelResolver` seam (exported above with\n// HttpDispatcher) — the only multi-tenant contract the framework retains.\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 { setPackageDisabled } from './package-state-store.js';\nimport { checkApiExposure } from './api-exposure.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';\nimport { generateApiKey } from './security/api-key.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 (set by the host's KernelResolver)\n dataDriver?: any; // IDataDriver - Resolved environment-scoped driver (set by the host's KernelResolver)\n /**\n * Dispatcher-provided hint for the host's {@link KernelResolver}: the\n * cleaned route path (API prefix stripped). Lets the resolver apply its\n * own path policy (e.g. skip env resolution for control-plane routes)\n * without re-deriving the dispatcher's URL handling.\n */\n routePath?: string;\n /**\n * Dispatcher-provided hint for the host's {@link KernelResolver}: the\n * UNVALIDATED environment-id candidate parsed from the scoped URL form\n * (`/environments/:id/...`) or the router's `params.environmentId`.\n * URL parsing is the dispatcher's routing convention, so it stays here;\n * validation (registry lookup) is the resolver's job.\n */\n urlEnvironmentId?: string;\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 * ADR-0006 generic kernel-resolution seam.\n *\n * A host (e.g. ObjectStack Cloud) injects a resolver to own per-request\n * kernel selection. The framework ships NO multi-tenant implementation — all\n * hostname→env strategy, the per-env kernel cache, and the control plane live\n * in the host distribution (`@objectstack/objectos-runtime`). When no resolver\n * is injected the dispatcher serves every request from its single\n * `defaultKernel` (single-environment mode).\n *\n * Returning `undefined` routes the request to `defaultKernel` — resolvers use\n * this for control-plane / unscoped / single-environment requests.\n *\n * As of ADR-0006 Phase 5 the resolver owns the ENTIRE per-request environment\n * resolution, not just kernel selection: the dispatcher no longer performs any\n * hostname / header / session → environment lookup of its own. The dispatcher\n * provides parsing hints on the context (`routePath`, `urlEnvironmentId`) and\n * expects the resolver to SET `context.environmentId` (and optionally\n * `context.dataDriver`) for scoped requests — downstream dispatcher stages\n * (project-membership enforcement, scope TTL touch, scoped service resolution)\n * key off `context.environmentId`.\n */\nexport interface KernelResolver {\n resolveKernel(\n context: HttpProtocolContext,\n defaultKernel: ObjectKernel,\n ): Promise<ObjectKernel | undefined> | ObjectKernel | undefined;\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 generic kernel-resolution seam (ADR-0006). The SOLE\n * multi-tenant hook: the host's resolver owns env resolution + kernel\n * selection per request (see {@link KernelResolver}). Falls back to\n * `resolveService('kernel-resolver')`. Hosts that register none run\n * single-environment on `defaultKernel`. (The legacy `kernelManager`\n * option and the dispatcher's built-in hostname/header/session\n * resolution were removed in ADR-0006 Phase 5 — that strategy lives in\n * the cloud distribution's resolver now.)\n */\n kernelResolver?: KernelResolver;\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 defaultProject?: { environmentId: string; orgId?: string };\n private kernelResolver?: KernelResolver;\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 /**\n * @param _envRegistryIgnored — RETIRED (ADR-0006 Phase 5). Environment\n * resolution moved behind the host's {@link KernelResolver}; the\n * positional parameter is kept so existing 3-arg callers keep compiling,\n * but its value is ignored.\n */\n constructor(kernel: ObjectKernel, _envRegistryIgnored?: unknown, 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.enforceMembership = options?.enforceProjectMembership ?? true;\n // ADR-0006 kernel-resolution seam — the host's resolver owns env\n // resolution + kernel selection. Optional service so single-environment\n // hosts that register none are unchanged.\n this.kernelResolver = options?.kernelResolver ?? resolveService('kernel-resolver');\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 * ADR-0046: `doc` list responses omit `content` by default — manuals\n * are the one metadata payload that grows unbounded, and the list\n * surface only needs `name` + `label`. `?include=content` opts back in\n * (single-item GET /metadata/doc/:name always returns the full body).\n */\n private slimDocList(type: string, data: any, query?: Record<string, string>): any {\n if (type !== 'doc' || query?.include === 'content') return data;\n const strip = (items: any[]) =>\n items.map((i) => {\n if (!i || typeof i !== 'object') return i;\n const { content: _content, ...rest } = i as Record<string, unknown>;\n return rest;\n });\n if (Array.isArray(data)) return strip(data);\n if (data && Array.isArray(data.items)) return { ...data, items: strip(data.items) };\n return data;\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 // ── Object-level API exposure gate (ADR-0049, #1889) ─────\n // Honour the object's `apiEnabled` / `apiMethods` declarations for\n // external traffic. System/internal contexts bypass — these flags\n // govern API *exposure*, not internal engine self-writes.\n if (!executionContext?.isSystem && params?.object) {\n let def: any;\n try {\n const meta = await this.resolveService('metadata', scopeId);\n def = await (meta as any)?.getObject?.(params.object);\n } catch {\n def = undefined; // fall open to schema defaults (apiEnabled=true)\n }\n const gate = checkApiExposure(def, action);\n if (!gate.allowed) {\n throw { statusCode: gate.status ?? 403, message: gate.reason ?? 'API access denied' };\n }\n }\n\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 * Handle an MCP request over the Streamable HTTP transport (`/mcp`).\n *\n * Gating + auth (fail-closed):\n * - **opt-in**: only served when `OS_MCP_SERVER_ENABLED=true` (single-env\n * runtime). Multi-tenant cloud overrides this gate per env. When off we\n * return 404 so the surface isn't advertised.\n * - **auth**: requires a principal already resolved by\n * `resolveExecutionContext` (the `sys_api_key` Bearer/header path or a\n * session). Anonymous → 401.\n *\n * Execution: the MCP runtime builds a stateless per-request server whose\n * object-CRUD tools run through {@link callData} bound to THIS request's\n * ExecutionContext — i.e. the exact permission + RLS path the REST API\n * uses. An external agent can never exceed the key's authority.\n */\n async handleMcp(body: any, context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n if (!HttpDispatcher.isMcpEnabled()) {\n return { handled: true, response: this.error('MCP server is not enabled for this environment', 404) };\n }\n\n const mcp: any = await this.resolveService('mcp', context.environmentId);\n if (!mcp || typeof mcp.handleHttpRequest !== 'function') {\n return { handled: true, response: this.error('MCP server is not available', 501) };\n }\n\n const ec = context.executionContext;\n if (!ec || (!ec.userId && !ec.isSystem)) {\n return { handled: true, response: this.error('Unauthorized: a valid API key is required', 401) };\n }\n\n // The MCP transport needs a Web-standard Request. The runtime HTTP\n // adapter may hand us a node/Hono-style req (plain `headers` object,\n // path-only `url`), so normalise it.\n const webRequest = this.toMcpWebRequest(context.request, body);\n if (!webRequest) {\n return { handled: true, response: this.error('MCP transport requires a standard HTTP request', 400) };\n }\n\n const bridge = this.buildMcpBridge(context);\n let webRes: Response;\n try {\n webRes = await mcp.handleHttpRequest(webRequest, { bridge, parsedBody: body });\n } catch (err: any) {\n return { handled: true, response: this.error(err?.message ?? 'MCP request failed', 500) };\n }\n\n // Convert the transport's buffered Web Response into the dispatcher's\n // `{ status, headers, body }` shape (JSON-response mode → fully buffered).\n const headers: Record<string, string> = {};\n try { webRes.headers.forEach((v, k) => { headers[k] = v; }); } catch { /* no headers */ }\n const text = await webRes.text().catch(() => '');\n let responseBody: any = null;\n if (text) {\n const ct = headers['content-type'] ?? '';\n if (ct.includes('application/json')) {\n try { responseBody = JSON.parse(text); } catch { responseBody = text; }\n } else {\n responseBody = text;\n }\n }\n return { handled: true, response: { status: webRes.status, headers, body: responseBody } };\n }\n\n /** Whether the MCP HTTP surface is opted in for this single-env runtime. */\n private static isMcpEnabled(): boolean {\n return typeof process !== 'undefined' && process.env?.OS_MCP_SERVER_ENABLED === 'true';\n }\n\n /**\n * Normalise the inbound request into a Web-standard `Request` for the MCP\n * transport. Accepts an already-Web `Request`, or a node/Hono-style req\n * (plain `headers` object, path-only `url`). Returns undefined only if the\n * shape is unusable. The body is carried separately via `parsedBody`, so a\n * GET/DELETE (no body) and a POST (JSON-RPC) both normalise cleanly.\n */\n private toMcpWebRequest(raw: any, parsedBody: any): Request | undefined {\n if (!raw) return undefined;\n // Already a Web Request.\n if (typeof raw.headers?.get === 'function' && typeof raw.url === 'string' && typeof raw.method === 'string') {\n return raw as Request;\n }\n try {\n const method = String(raw.method ?? 'POST').toUpperCase();\n\n // Normalise headers (plain object or Headers-like).\n const headers = new Headers();\n const h = raw.headers;\n if (h) {\n if (typeof h.forEach === 'function') {\n h.forEach((v: any, k: any) => { if (v != null) headers.set(String(k), String(v)); });\n } else {\n for (const k of Object.keys(h)) {\n const v = (h as any)[k];\n if (v != null) headers.set(k, Array.isArray(v) ? v.join(',') : String(v));\n }\n }\n }\n\n // Build an absolute URL (node req.url is path-only).\n let url: string;\n try {\n url = new URL(String(raw.url)).toString();\n } catch {\n const host = headers.get('host') || 'mcp.local';\n const path = typeof raw.url === 'string' && raw.url ? raw.url : '/api/v1/mcp';\n url = `https://${host}${path.startsWith('/') ? path : `/${path}`}`;\n }\n\n const init: { method: string; headers: Headers; body?: string } = { method, headers };\n if (method !== 'GET' && method !== 'HEAD' && method !== 'DELETE') {\n init.body = typeof parsedBody === 'string' ? parsedBody : JSON.stringify(parsedBody ?? {});\n }\n return new Request(url, init);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Build a principal-bound {@link McpDataBridge}: every method runs AS the\n * request's ExecutionContext through {@link callData} (RLS/permissions) and\n * the per-env metadata service. Keeps the MCP tool layer free of any direct\n * engine access.\n */\n private buildMcpBridge(context: HttpProtocolContext): any {\n const ec = context.executionContext;\n const envId = context.environmentId;\n const driver = (context as any).dataDriver;\n const callData = this.callData.bind(this);\n const getMeta = () => this.resolveService('metadata', envId);\n\n return {\n listObjects: async () => {\n const meta: any = await getMeta();\n const objs: any[] = (await meta?.listObjects?.()) ?? [];\n return objs.map((o) => ({\n name: o.name,\n label: o.label ?? o.name,\n fieldCount: o.fields ? Object.keys(o.fields).length : undefined,\n }));\n },\n describeObject: async (name: string) => {\n const meta: any = await getMeta();\n const def: any = await meta?.getObject?.(name);\n if (!def) return null;\n const fields = def.fields ?? {};\n return {\n name: def.name,\n label: def.label ?? def.name,\n fields: Object.entries(fields).map(([k, f]: [string, any]) => ({\n name: k,\n type: f?.type,\n label: f?.label ?? k,\n required: f?.required ?? false,\n })),\n enableFeatures: def.enable ?? {},\n };\n },\n query: async (object: string, o: any) => {\n const query: any = {};\n if (o?.where) query.where = o.where;\n if (o?.fields) query.fields = o.fields;\n if (typeof o?.limit === 'number') query.limit = o.limit;\n if (typeof o?.offset === 'number') query.offset = o.offset;\n if (o?.orderBy) query.orderBy = o.orderBy;\n return await callData('query', { object, query }, driver, envId, ec);\n },\n get: async (object: string, id: string) => {\n const res: any = await callData('get', { object, id }, driver, envId, ec);\n return res?.record ?? res ?? null;\n },\n create: async (object: string, data: any) =>\n await callData('create', { object, data }, driver, envId, ec),\n update: async (object: string, id: string, data: any) =>\n await callData('update', { object, id, data }, driver, envId, ec),\n remove: async (object: string, id: string) =>\n await callData('delete', { object, id }, driver, envId, ec),\n };\n }\n\n /**\n * Generate a `sys_api_key` and return the raw secret EXACTLY ONCE\n * (`POST /keys`). This is the only mint path — the raw key is never stored\n * (only its sha256 hash) and never re-displayable.\n *\n * Security (zero-tolerance):\n * - Requires an authenticated principal; `user_id` is PINNED to that\n * caller and is NEVER read from the request body (no impersonation).\n * - Body is whitelisted to `name` (+ optional `expires_at`); any\n * `key` / `id` / `user_id` / `revoked` in the body is ignored, so a\n * caller cannot forge a known-secret or escalate.\n * - `scopes` are intentionally NOT accepted from the body in v1: the\n * verify path ADDS scopes to the principal's permissions, so honouring\n * arbitrary body scopes would be an escalation vector. A generated key\n * therefore acts exactly AS the caller (via `user_id` resolution).\n * Narrowing/scoped keys need subset-enforcement — deferred.\n * - The raw key and its hash never enter logs or error messages.\n * - The row is written with an elevated `{ isSystem: true }` context\n * because `sys_api_key` is protection-locked; safe because the row's\n * contents are fully server-controlled (user_id pinned to caller).\n */\n async handleKeys(method: string, body: any, context: HttpProtocolContext): Promise<HttpDispatcherResult> {\n if (method !== 'POST') {\n return { handled: true, response: this.error('Method not allowed', 405) };\n }\n\n const ec = context.executionContext;\n if (!ec || !ec.userId) {\n return { handled: true, response: this.error('Unauthorized: sign in to generate an API key', 401) };\n }\n\n // ── Whitelist the body. Only `name` and optional `expires_at`. ──\n const rawName = typeof body?.name === 'string' ? body.name.trim() : '';\n const name = rawName || 'API Key';\n\n let expiresAt: string | undefined;\n if (body?.expires_at != null && body.expires_at !== '') {\n const ms = typeof body.expires_at === 'number'\n ? (body.expires_at < 1e12 ? body.expires_at * 1000 : body.expires_at)\n : Date.parse(String(body.expires_at));\n if (Number.isNaN(ms)) {\n return { handled: true, response: this.error('Invalid expires_at: must be a parseable date', 400) };\n }\n if (ms <= Date.now()) {\n return { handled: true, response: this.error('Invalid expires_at: must be in the future', 400) };\n }\n expiresAt = new Date(ms).toISOString();\n }\n\n const ql = (await this.getObjectQLService(context.environmentId))\n ?? (await this.resolveService('objectql', context.environmentId));\n if (!ql || typeof ql.insert !== 'function') {\n return { handled: true, response: this.error('Data service not available', 503) };\n }\n\n // Generate AFTER validation so we never mint on a rejected request.\n const generated = generateApiKey();\n\n // Server-controlled row. user_id is pinned to the caller; only the hash\n // is persisted. NOTHING from the body can set key/id/user_id/revoked.\n const row: Record<string, unknown> = {\n name,\n key: generated.hash,\n prefix: generated.prefix,\n user_id: ec.userId,\n revoked: false,\n };\n if (expiresAt) row.expires_at = expiresAt;\n\n let inserted: any;\n try {\n inserted = await ql.insert('sys_api_key', row, { context: { isSystem: true } });\n } catch {\n // Never surface the underlying error (could echo row contents).\n return { handled: true, response: this.error('Failed to create API key', 500) };\n }\n const id = inserted?.id ?? (Array.isArray(inserted) ? inserted[0]?.id : undefined);\n\n // Raw key returned ONCE. Do not log it.\n return {\n handled: true,\n response: {\n status: 201,\n body: {\n success: true,\n data: {\n id,\n name,\n prefix: generated.prefix,\n key: generated.raw,\n ...(expiresAt ? { expires_at: expiresAt } : {}),\n },\n },\n },\n };\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 * Attach the dispatcher's parsing hints for the host's\n * {@link KernelResolver} (ADR-0006 Phase 5).\n *\n * Environment RESOLUTION (hostname / x-environment-id / session /\n * org-default / single-env-default → environment + driver) is owned by\n * the host's resolver — the dispatcher no longer touches an environment\n * registry. What stays here is pure URL parsing (the dispatcher's own\n * routing convention): the scoped-path environment-id candidate and the\n * cleaned route path, both UNVALIDATED.\n */\n private prepareResolverHints(context: HttpProtocolContext, path: string): void {\n context.routePath = path;\n const urlEnvironmentId = this.extractEnvironmentIdFromPath(path)\n ?? context.request?.params?.environmentId;\n if (urlEnvironmentId) context.urlEnvironmentId = String(urlEnvironmentId);\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 // Public share-link resolve/messages — the token IS the authorisation,\n // so never gate them on project membership (a signed-in non-member\n // opening a public link must not be 403'd before the token handler runs).\n if (/(^|\\/)share-links\\/[^/]+\\/(resolve|messages)$/.test(path)) 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 // MCP (Streamable HTTP) is opt-in per env — only advertised\n // when OS_MCP_SERVER_ENABLED=true so the surface isn't exposed\n // by default. The objectui Integrations page reads this.\n mcp: HttpDispatcher.isMcpEnabled() ? `${prefix}/mcp` : 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 // ADR-0033 draft-overlay preview: `?preview=draft` makes the\n // detail read prefer a pending draft (falling back to active).\n // Admin gating is layered on top in a follow-up (step 2).\n const previewDrafts = query?.preview === 'draft';\n const data = await protocol.getMetaItem({ type: singularType, name, packageId, organizationId, previewDrafts });\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 // ADR-0048 — thread `?package=` so single-item resolution is\n // package-scoped (prefer-local), matching list resolution.\n const data = await (metaSvc as any).getItem(singularType, name, packageId);\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 // ADR-0033 draft-overlay preview: `?preview=draft` overlays\n // pending drafts on the active list so an (admin) reviewer can\n // render the console off drafts before publishing.\n const previewDrafts = query?.preview === 'draft';\n const data = await protocol.getMetaItems({ type: typeOrName, packageId, organizationId, previewDrafts });\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(this.slimDocList(typeOrName, data, query)) };\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: this.slimDocList(typeOrName, items, query) }) };\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. A\n // registered KernelResolver marks this host as multi-tenant (ADR-0006\n // Phase 5 — previously signalled by the env-registry service): a\n // data-plane request that the resolver did not attach to an\n // environment must not silently fall through to the host kernel.\n if (!_context.dataDriver && this.kernelResolver) {\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 // Publishing a `seed` draft is what actually loads its\n // rows. The objectql protocol now batch-applies seeds\n // inside `publishPackageDrafts` itself (so EVERY publish\n // path — incl. the per-ref REST publish — materializes\n // data) and reports under `seedApplied`. Only fall back\n // to the route-level apply for custom protocols that\n // don't self-apply — never run both, or an externalId-less\n // seed would double-insert.\n if ((result as any)?.seedApplied === undefined) {\n try {\n const seedNames = ((result as any)?.published ?? [])\n .filter((p: any) => p?.type === 'seed')\n .map((p: any) => p.name as string);\n if (seedNames.length > 0) {\n (result as any).seedApplied = await this.applyPublishedSeeds(\n seedNames,\n organizationId,\n _context,\n );\n }\n } catch (e: any) {\n (result as any).seedApplied = { success: false, error: e?.message ?? 'seed apply failed' };\n }\n }\n // ADR-0045: \"Publish\" makes the package live AND visible.\n // A materialized (additive) build has no drafts left to\n // promote — its app sits at `hidden: true` awaiting the\n // visibility flip. Unhide every hidden app bound to this\n // package so ONE publish verb serves both regimes (the\n // caller never needs to know how the package was built).\n // Best-effort: a custom protocol without the meta\n // primitives keeps plain draft-publish semantics.\n try {\n if (\n typeof (protocol as any).getMetaItems === 'function' &&\n typeof (protocol as any).saveMetaItem === 'function'\n ) {\n const appsRes = await (protocol as any).getMetaItems({\n type: 'app',\n packageId: id,\n ...(organizationId ? { organizationId } : {}),\n });\n const apps: any[] = Array.isArray(appsRes)\n ? appsRes\n : Array.isArray((appsRes as any)?.items) ? (appsRes as any).items : [];\n const unhidden: string[] = [];\n for (const app of apps) {\n if (app && typeof app === 'object' && app.hidden === true && typeof app.name === 'string') {\n await (protocol as any).saveMetaItem({\n type: 'app',\n name: app.name,\n item: { ...app, hidden: false },\n packageId: id,\n ...(organizationId ? { organizationId } : {}),\n ...(body?.actor ? { actor: body.actor } : {}),\n });\n unhidden.push(app.name);\n }\n }\n if (unhidden.length > 0) (result as any).unhiddenApps = unhidden;\n }\n } catch (e: any) {\n (result as any).unhideError = e?.message ?? 'visibility flip failed';\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/discard-drafts → drop every pending DRAFT bound\n // to the package, reverting it to its last published baseline\n // (\"abandon all my changes\"). NON-destructive: active metadata and\n // physical tables are untouched. Routes through the sys_metadata\n // path (no metadata-service dependency, unlike /revert below).\n if (parts.length === 2 && parts[1] === 'discard-drafts' && m === 'POST') {\n const id = decodeURIComponent(parts[0]);\n const protocol = await this.resolveService('protocol');\n if (protocol && typeof (protocol as any).discardPackageDrafts === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const result = await (protocol as any).discardPackageDrafts({\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 discarding 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 → delete the package. Unregisters it from the\n // in-memory registry AND removes its persisted sys_metadata rows\n // (active + draft), tearing down each object's physical table by\n // default. `?keepData=true` preserves object tables (metadata-only\n // delete). Use case: \"I don't want this package anymore.\"\n if (parts.length === 1 && m === 'DELETE') {\n const id = decodeURIComponent(parts[0]);\n const registryRemoved = registry.uninstallPackage(id);\n\n // Persisted removal (AI/runtime packages live in sys_metadata, not\n // just the in-memory registry — the registry uninstall alone would\n // leave the rows and tables behind).\n let persisted: unknown = undefined;\n const protocol = await this.resolveService('protocol');\n if (protocol && typeof (protocol as any).deletePackage === 'function') {\n try {\n const organizationId = await this.resolveActiveOrganizationId(_context);\n const keepData = query?.keepData === 'true' || query?.keepData === '1';\n persisted = await (protocol as any).deletePackage({\n packageId: id,\n ...(organizationId ? { organizationId } : {}),\n ...(keepData ? { keepData: true } : {}),\n });\n } catch (e: any) {\n return { handled: true, response: this.error(e.message, e.statusCode || 500) };\n }\n }\n\n const deletedCount = (persisted as any)?.deletedCount ?? 0;\n if (!registryRemoved && deletedCount === 0) {\n return { handled: true, response: this.error(`Package '${id}' not found`, 404) };\n }\n return { handled: true, response: this.success({ success: true, registryRemoved, persisted }) };\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 * Apply just-published `seed` metadata: load each seed's rows into its\n * target object so publishing a seed draft makes the data live (the runtime\n * counterpart to staging it). Reads each seed body via the protocol, then\n * runs the {@link SeedLoaderService} for the active org. Best-effort and\n * idempotent (upsert) — callers must never let this fail the publish.\n *\n * Lives at the runtime layer (not in the objectql publish primitive)\n * because the seed loader needs the data engine + metadata service, which\n * objectql cannot depend on without a layering cycle.\n */\n private async applyPublishedSeeds(\n names: string[],\n organizationId: string | undefined,\n _context: HttpProtocolContext,\n ): Promise<{ success: boolean; inserted?: number; updated?: number; errors?: unknown[]; error?: string }> {\n const protocol: any = await this.resolveService('protocol');\n const metadata: any = await this.getService(CoreServiceName.enum.metadata);\n const ql: any = await this.resolveService('objectql');\n if (!protocol || typeof protocol.getMetaItem !== 'function' || !ql || !metadata) {\n return { success: false, error: 'seed apply: required services unavailable' };\n }\n const datasets: any[] = [];\n const readErrors: string[] = [];\n for (const name of names) {\n // Read the just-published seed body. Try the active org first, then\n // fall back to an env-wide read — a workspace seed is often stored\n // org-wide (organization_id IS NULL), and resolving the wrong scope\n // here is what silently produced \"0 rows loaded\".\n const attempts = organizationId\n ? [{ type: 'seed', name, organizationId }, { type: 'seed', name }]\n : [{ type: 'seed', name }];\n let item: any;\n for (const args of attempts) {\n try {\n item = await protocol.getMetaItem(args);\n if (item) break;\n } catch (e) {\n readErrors.push(`read ${name}: ${(e as Error)?.message ?? String(e)}`);\n }\n }\n // protocol.getMetaItem (called directly, unlike the HTTP endpoint\n // which unwraps) returns a WRAPPER: `{ type, name, item, lock,\n // editable, … }` — the seed body (object/records) lives under\n // `.item`. Tolerate the wrapper (`.item`) plus the body-direct and\n // `.metadata`/`.body` shapes other protocols may return.\n const seed = item?.object && Array.isArray(item?.records)\n ? item\n : (item?.item ?? item?.metadata ?? item?.body);\n if (seed?.object && Array.isArray(seed?.records)) {\n datasets.push(seed);\n } else {\n readErrors.push(`seed \"${name}\" body unreadable (keys: ${item ? Object.keys(item).join(',') : 'none'})`);\n }\n }\n // Seeds were published but none could be read back → surface it (do NOT\n // report success with 0 rows, which hides the failure).\n if (datasets.length === 0) {\n return { success: false, inserted: 0, updated: 0, error: 'seed apply: no readable seed bodies', errors: readErrors };\n }\n\n const { SeedLoaderService } = await import('./seed-loader.js');\n const { SeedLoaderRequestSchema } = await import('@objectstack/spec/data');\n const loader = new SeedLoaderService(ql, metadata, (this as any).logger ?? console);\n const request = SeedLoaderRequestSchema.parse({\n seeds: datasets,\n config: {\n defaultMode: 'upsert',\n multiPass: true,\n ...(organizationId ? { organizationId } : {}),\n },\n });\n const r = await loader.load(request);\n return {\n success: r.success,\n inserted: r.summary.totalInserted,\n updated: r.summary.totalUpdated,\n errors: [...readErrors, ...(r.errors ?? [])],\n };\n }\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). Routed via the\n // host's KernelResolver (ADR-0006 Phase 5) — same seam as handle().\n let projectQl: any = null;\n if (this.kernelResolver && _context.environmentId && _context.environmentId !== 'platform') {\n try {\n const projectKernel: any = await this.kernelResolver.resolveKernel(_context, this.defaultKernel);\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 * Share-link capability tokens — \"anyone with the link\" publication of a\n * single record (ADR-0047). Mirrors the per-env service-dispatch pattern\n * used by {@link handleI18n} / {@link handleAI}: the `shareLinks` service\n * is resolved from the request's environment kernel, so links live in (and\n * resolve against) the same per-environment database that owns the record.\n * This branch owns URL parsing and the auth/public split.\n *\n * POST /share-links → create a link (authenticated)\n * GET /share-links?object&recordId → list the caller's links (authenticated)\n * DELETE /share-links/:idOrToken → revoke (authenticated)\n * GET /share-links/:token/resolve → resolve token → record (PUBLIC)\n * GET /share-links/:token/messages → ai_conversations messages (PUBLIC)\n *\n * The resolve / messages routes are intentionally public — the token IS\n * the authorisation. The underlying record is fetched with a SYSTEM\n * context (per-env RLS is bypassed because the token gates access), and\n * `redactFields` are stripped before the record leaves the server.\n */\n async handleShareLinks(\n subPath: string,\n method: string,\n body: any,\n query: any,\n context: HttpProtocolContext,\n ): Promise<HttpDispatcherResult> {\n const svc: any = await this.resolveService('shareLinks', context.environmentId);\n if (!svc) {\n return { handled: true, response: this.error('Sharing is not configured for this environment', 501) };\n }\n\n const SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;\n const m = method.toUpperCase();\n const parts = subPath.replace(/^\\/+/, '').split('/').filter(Boolean);\n const ec: any = context.executionContext;\n const callerCtx = { userId: ec?.userId as string | undefined, tenantId: ec?.tenantId as string | undefined };\n\n const headerOf = (name: string): string | undefined => {\n const h = context.request?.headers;\n if (!h) return undefined;\n const v = typeof h.get === 'function' ? h.get(name) : (h[name] ?? h[name.toLowerCase()]);\n return Array.isArray(v) ? v[0] : (v ?? undefined);\n };\n const sendErr = (status: number, code: string, msg: string): HttpDispatcherResult => ({\n handled: true,\n response: this.error(msg, status, { code }),\n });\n // Engine for fetching the shared record + token probes — the same\n // per-env ObjectQL the shareLinks service is bound to.\n const getEngine = async (): Promise<any> => {\n // Read objectql from the request's RESOLVED (per-env) kernel — the\n // same engine SharingServicePlugin bound the shareLinks service to,\n // so the shared record + messages live in the SAME store as\n // sys_share_link. `resolveService('objectql', env)` can hand back a\n // different (host/scoped) engine that lacks the per-env rows.\n try {\n const k: any = this.kernel;\n const e = typeof k?.getServiceAsync === 'function'\n ? await k.getServiceAsync('objectql')\n : k?.getService?.('objectql');\n if (e) return e;\n } catch { /* fall through to scoped resolution */ }\n return this.resolveService('objectql', context.environmentId);\n };\n const asArray = (rows: any): any[] => (Array.isArray(rows) ? rows : Array.isArray(rows?.value) ? rows.value : []);\n const applyRedaction = (record: any, redactFields: string[]): any => {\n if (!record || typeof record !== 'object' || redactFields.length === 0) return record;\n const out: any = {};\n for (const [k, v] of Object.entries(record)) {\n if (redactFields.includes(k)) continue;\n out[k] = v;\n }\n return out;\n };\n\n try {\n // ── PUBLIC: resolve a token → record ──────────────────────────\n if (parts.length === 2 && parts[1] === 'resolve' && m === 'GET') {\n const token = decodeURIComponent(parts[0]);\n const signedInUserId = ec?.userId;\n const recipientEmail = typeof query?.email === 'string' ? query.email : undefined;\n const providedPassword =\n typeof query?.password === 'string' ? (query.password as string) : headerOf('x-share-password');\n\n const resolved = await svc.resolveToken(token, { signedInUserId, recipientEmail, providedPassword });\n if (!resolved) {\n // Probe the row to return a more useful status (401 vs 410 vs 404).\n const engine = await getEngine();\n const probe = engine\n ? asArray(await engine.find('sys_share_link', { where: { token }, limit: 1, context: SYSTEM_CTX } as any))\n : [];\n const row = probe[0] ?? null;\n const live = row && !row.revoked_at && (!row.expires_at || Date.parse(row.expires_at) > Date.now());\n if (live && row.password_hash) {\n return sendErr(401, providedPassword ? 'WRONG_PASSWORD' : 'NEEDS_PASSWORD',\n providedPassword ? 'Incorrect password' : 'This link requires a password');\n }\n if (live && row.audience === 'signed_in' && !signedInUserId) {\n return sendErr(401, 'SIGN_IN_REQUIRED', 'Please sign in to view this link');\n }\n if (row && (row.revoked_at || (row.expires_at && Date.parse(row.expires_at) <= Date.now()))) {\n return sendErr(410, 'EXPIRED_OR_REVOKED', 'Share link has expired or been revoked');\n }\n return sendErr(404, 'INVALID_OR_EXPIRED', 'Share link is invalid, expired, or revoked');\n }\n\n const engine = await getEngine();\n const rows = engine\n ? asArray(await engine.find(resolved.link.object_name, { where: { id: resolved.link.record_id }, limit: 1, context: SYSTEM_CTX } as any))\n : [];\n const record = rows[0] ?? null;\n if (!record) return sendErr(410, 'RECORD_GONE', 'The shared record no longer exists');\n\n return {\n handled: true,\n response: this.success({\n record: applyRedaction(record, resolved.redactFields),\n link: {\n id: resolved.link.id,\n token: resolved.link.token,\n object_name: resolved.link.object_name,\n record_id: resolved.link.record_id,\n permission: resolved.link.permission,\n audience: resolved.link.audience,\n expires_at: resolved.link.expires_at,\n label: resolved.link.label,\n created_at: resolved.link.created_at,\n },\n redactFields: resolved.redactFields,\n }),\n };\n }\n\n // ── PUBLIC: ai_conversations messages for a resolved token ────\n if (parts.length === 2 && parts[1] === 'messages' && m === 'GET') {\n const token = decodeURIComponent(parts[0]);\n const providedPassword =\n typeof query?.password === 'string' ? (query.password as string) : headerOf('x-share-password');\n const resolved = await svc.resolveToken(token, { signedInUserId: ec?.userId, providedPassword });\n if (!resolved) return sendErr(404, 'NOT_FOUND', 'Share link not found');\n if (resolved.link.object_name !== 'ai_conversations') {\n return sendErr(400, 'UNSUPPORTED', 'This share link does not expose messages');\n }\n const engine = await getEngine();\n const rows = engine\n ? asArray(await engine.find('ai_messages', {\n where: { conversation_id: resolved.link.record_id },\n sort: [{ field: 'created_at', order: 'asc' }],\n limit: 500,\n context: SYSTEM_CTX,\n } as any))\n : [];\n return { handled: true, response: this.success(rows) };\n }\n\n // ── AUTHENTICATED: create / list / revoke ─────────────────────\n if (!callerCtx.userId) return sendErr(401, 'UNAUTHENTICATED', 'Sign in to manage share links');\n\n // POST /share-links → create\n if (parts.length === 0 && m === 'POST') {\n const b: any = body ?? {};\n if (!b.object || !b.recordId) return sendErr(400, 'VALIDATION_FAILED', 'object and recordId are required');\n const link = await svc.createLink(\n {\n object: b.object,\n recordId: b.recordId,\n permission: b.permission,\n audience: b.audience,\n expiresAt: b.expiresAt ?? null,\n emailAllowlist: b.emailAllowlist,\n password: b.password,\n redactFields: b.redactFields,\n label: b.label,\n },\n callerCtx,\n );\n return { handled: true, response: { status: 201, body: { success: true, data: link, link } } };\n }\n\n // GET /share-links?object&recordId → list the caller's own links\n if (parts.length === 0 && m === 'GET') {\n const links = await svc.listLinks(\n {\n object: typeof query?.object === 'string' ? query.object : undefined,\n recordId: typeof query?.recordId === 'string' ? query.recordId : undefined,\n // Constrain to links the caller created so a guessed\n // recordId can never enumerate another user's tokens.\n createdBy: callerCtx.userId,\n includeRevoked: query?.includeRevoked === 'true' || query?.includeRevoked === '1',\n },\n callerCtx,\n );\n return { handled: true, response: { status: 200, body: { success: true, data: links, links } } };\n }\n\n // DELETE /share-links/:idOrToken → revoke\n if (parts.length === 1 && m === 'DELETE') {\n await svc.revokeLink(decodeURIComponent(parts[0]), callerCtx);\n return { handled: true, response: this.success({ ok: true }) };\n }\n\n return { handled: true, response: this.routeNotFound(`/share-links${subPath}`) };\n } catch (err: any) {\n return sendErr(err?.status ?? 500, err?.code ?? 'INTERNAL', err?.message ?? 'Share link request failed');\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 + Multi-Kernel Routing (ADR-0006 Phase 5) ──\n // The host's KernelResolver owns the whole step: it resolves the\n // request to an environment (hostname / header / session / defaults —\n // strategy lives in the cloud distribution), SETS\n // `context.environmentId` (+ `dataDriver`), and returns the kernel to\n // serve from. The dispatcher only contributes parsing hints. No\n // resolver registered → single-environment: every request serves from\n // `defaultKernel` with no environment context.\n this.prepareResolverHints(context, cleanPath);\n if (this.kernelResolver) {\n this.kernel = (await this.kernelResolver.resolveKernel(context, this.defaultKernel)) ?? this.defaultKernel;\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 === '/mcp' || cleanPath.startsWith('/mcp/') || cleanPath.startsWith('/mcp?')) {\n return this.handleMcp(body, context);\n }\n\n if (cleanPath === '/keys' || cleanPath.startsWith('/keys/') || cleanPath.startsWith('/keys?')) {\n return this.handleKeys(method, body, 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 // Share links — capability-token record sharing, dispatched to the\n // per-env `shareLinks` service (links + record live in the same kernel).\n if (cleanPath === '/share-links' || cleanPath.startsWith('/share-links/')) {\n return this.handleShareLinks(cleanPath.substring('/share-links'.length), 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 * Object-level API exposure gate (ADR-0049, #1889).\n *\n * Objects declare `apiEnabled` (default true) and an optional `apiMethods`\n * whitelist, but the HTTP/MCP data dispatch previously ignored both — an object\n * could not actually be hidden from the API, nor could its allowed operations\n * be restricted. This module decides, for a given data action, whether the\n * object's declared exposure permits it.\n *\n * Both fields are *additive restrictions* over a default-allow surface\n * (`apiEnabled` defaults true; absent `apiMethods` means \"all operations\").\n * Therefore an unresolvable object definition fails OPEN here — that matches\n * the schema defaults and avoids breaking traffic when metadata is briefly\n * unavailable. The gate is a no-op for system/internal contexts (callers pass\n * `isSystem` and skip this check entirely).\n */\n\n/** The exposure-relevant slice of an object definition. */\nexport interface ObjectApiDef {\n apiEnabled?: boolean;\n apiMethods?: string[] | null;\n}\n\nexport interface ApiExposureDecision {\n allowed: boolean;\n /** HTTP status to return when denied (404 hides, 405 = method not allowed). */\n status?: number;\n reason?: string;\n}\n\n/**\n * Map an internal `callData` action onto the spec `ApiMethod` vocabulary\n * (`object.zod.ts` → `ApiMethod`). Actions with no mapping are not gated by\n * `apiMethods` (they still respect `apiEnabled`).\n */\nconst ACTION_TO_API_METHOD: Record<string, string> = {\n create: 'create',\n get: 'get',\n update: 'update',\n delete: 'delete',\n query: 'list',\n find: 'list',\n batch: 'bulk',\n};\n\nexport function checkApiExposure(def: ObjectApiDef | null | undefined, action: string): ApiExposureDecision {\n // Unresolvable definition → fall open to the schema defaults.\n if (!def) return { allowed: true };\n\n // `apiEnabled: false` hides the object from the API entirely → 404.\n if (def.apiEnabled === false) {\n return { allowed: false, status: 404, reason: 'object is not exposed via the API' };\n }\n\n // `apiMethods` whitelist (when present and non-empty) restricts operations.\n const whitelist = def.apiMethods;\n if (Array.isArray(whitelist) && whitelist.length > 0) {\n const method = ACTION_TO_API_METHOD[action];\n // Only gate actions that map to a known ApiMethod; unmapped actions pass.\n if (method && !whitelist.includes(method)) {\n return {\n allowed: false,\n status: 405,\n reason: `API operation '${method}' is not allowed for this object`,\n };\n }\n }\n\n return { allowed: true };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * api-key — re-export of the shared `sys_api_key` primitives + verifier.\n *\n * The implementation now lives in `@objectstack/core/security` so BOTH inbound\n * surfaces — this runtime's dispatcher/MCP path (`resolveExecutionContext`) and\n * the REST data API (`@objectstack/rest`) — verify keys through the exact same\n * code, with no drift. (`rest` cannot import `runtime` — `runtime` depends on\n * `rest` — so the shared home must be a lower package both depend on: `core`.)\n *\n * This file preserves the historical `@objectstack/runtime` import surface.\n */\n\nexport {\n API_KEY_PREFIX,\n hashApiKey,\n generateApiKey,\n extractApiKey,\n parseScopes,\n isExpired,\n resolveApiKeyPrincipal,\n type GeneratedApiKey,\n type ApiKeyPrincipal,\n} from '@objectstack/core';\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>`) — a\n * hand-rolled check that hashes the inbound key and looks it up against the\n * `sys_api_key` system object by its at-rest hash, rejecting revoked or\n * expired keys. (better-auth 1.6.x ships no apiKey plugin.)\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\nimport { resolveApiKeyPrincipal } from './api-key.js';\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\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/** True for a valid IANA timezone name (e.g. `America/New_York`, `UTC`). */\nfunction isValidTimeZone(tz: string): boolean {\n try {\n new Intl.DateTimeFormat('en-US', { timeZone: tz });\n return true;\n } catch {\n return false;\n }\n}\n\n/** Coerce a stored preference/setting value to a valid IANA zone, or undefined. */\nfunction coerceTimeZone(value: unknown): string | undefined {\n const s = typeof value === 'string' ? value.trim() : value != null ? String(value).trim() : '';\n return s && isValidTimeZone(s) ? s : undefined;\n}\n\n/** Coerce a stored locale value to a non-empty BCP-47-ish string, or undefined. */\nfunction coerceLocale(value: unknown): string | undefined {\n const s = typeof value === 'string' ? value.trim() : value != null ? String(value).trim() : '';\n return s || undefined;\n}\n\n/**\n * Resolve the workspace localization defaults onto the ExecutionContext\n * (ADR-0053 Phase 2): reference `timezone` and `locale`.\n *\n * Canonical path is the `localization` SettingsManifest via the `settings`\n * service, whose cascade is platform default → global → tenant (ADR-0002: one\n * org per physical tenant; per-user overrides are intentionally out of scope\n * for v1). When the settings service or its namespace is unavailable (e.g. a\n * minimal deployment), fall back to a direct tenant-scoped `sys_setting` read,\n * then to the built-ins `UTC` / `en-US`.\n *\n * Every read is defensive — localization never blocks auth, and an invalid\n * zone falls through to the built-in.\n */\nasync function resolveLocalization(\n opts: ResolveOptions,\n ql: any,\n sctx: { tenantId?: string; userId?: string },\n): Promise<{ timezone: string; locale: string }> {\n // 1. Canonical — the `localization` manifest via the settings service.\n try {\n const settings: any = await opts.getService('settings');\n if (settings && typeof settings.get === 'function') {\n const [tzRes, localeRes] = await Promise.all([\n settings.get('localization', 'timezone', sctx).catch(() => undefined),\n settings.get('localization', 'locale', sctx).catch(() => undefined),\n ]);\n const tz = coerceTimeZone(tzRes?.value);\n const locale = coerceLocale(localeRes?.value);\n // A resolved value (incl. the manifest default) means the namespace is\n // live — trust it and skip the legacy direct read.\n if (tz || locale) return { timezone: tz ?? 'UTC', locale: locale ?? 'en-US' };\n }\n } catch {\n // settings service unavailable → fall through to the direct read\n }\n\n // 2. Fallback — direct tenant-scoped `sys_setting` rows (no settings service\n // registered, or namespace not loaded).\n const tzRows = await tryFind(ql, 'sys_setting', { namespace: 'localization', key: 'timezone', scope: 'tenant' }, 1);\n const localeRows = await tryFind(ql, 'sys_setting', { namespace: 'localization', key: 'locale', scope: 'tenant' }, 1);\n return {\n timezone: coerceTimeZone(tzRows[0]?.value) ?? 'UTC',\n locale: coerceLocale(localeRows[0]?.value) ?? 'en-US',\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 //\n // better-auth 1.6.x ships no apiKey plugin, so this is a hand-rolled\n // check: hash the inbound key, look it up against `sys_api_key` by the\n // at-rest hash, and reject revoked or expired keys. The raw key is never\n // stored or logged. Once resolved, the principal flows through the exact\n // same role/permission/RLS resolution as the session path below.\n // Verification is delegated to the shared `resolveApiKeyPrincipal`\n // (@objectstack/core), the SAME verifier the REST data API uses, so the\n // two surfaces never drift.\n const keyPrincipal = await resolveApiKeyPrincipal(await opts.getQl(), headers);\n if (keyPrincipal) {\n userId = keyPrincipal.userId;\n tenantId = keyPrincipal.tenantId;\n for (const scope of keyPrincipal.scopes) {\n if (!ctx.permissions!.includes(scope)) ctx.permissions!.push(scope);\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 // 4. Localization (ADR-0053 Phase 2) — reference timezone + locale resolved\n // once per request from the `localization` settings and carried on the\n // context. Consumers: formula today()/datetime, analytics date buckets,\n // email rendering. Absent config → UTC / en-US keeps current behavior.\n const localization = await resolveLocalization(opts, ql, { tenantId, userId });\n ctx.timezone = localization.timezone;\n ctx.locale = localization.locale;\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 // Discovery reflects MUTABLE runtime config (which routes/services\n // are live — e.g. `mcp` only when OS_MCP_SERVER_ENABLED=true). It\n // must never be cached by an edge/CDN, or a config change (enable\n // MCP) leaves clients reading a stale payload that still says the\n // route is absent — the Integrations UI then shows \"MCP not\n // enabled\" against a live server (cloud#152). The body is computed\n // fresh per request; the only staleness is the HTTP cache layer.\n res.header('Cache-Control', 'no-store');\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 // See the .well-known handler above: discovery must not be cached\n // (mutable runtime config; cloud#152 stale `routes.mcp`).\n res.header('Cache-Control', 'no-store');\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 // ── MCP (Streamable HTTP) + API keys (ADR-0036) ─────────────\n // Mounted explicitly (there is no catch-all) and routed through\n // dispatch() so the host's project-aware kernel swap + execution\n // context resolution run first. /mcp accepts POST (JSON-RPC), GET\n // (SSE) and DELETE (session end) — the transport reads the method\n // from the request, the dispatcher gates on OS_MCP_SERVER_ENABLED\n // and the resolved principal. NOTE: the dispatch() branches alone\n // are unreachable over HTTP without these registrations.\n const mountMcp = (method: 'GET' | 'POST' | 'DELETE') => {\n const register = method === 'GET' ? server.get : method === 'DELETE' ? server.delete : server.post;\n register.call(server, `${prefix}/mcp`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch(method, '/mcp', req.body, req.query, { request: req });\n sendResult(result, res);\n } catch (err: any) {\n errorResponse(err, res);\n }\n });\n };\n mountMcp('POST');\n mountMcp('GET');\n mountMcp('DELETE');\n\n server.post(`${prefix}/keys`, async (req: any, res: any) => {\n try {\n const result = await dispatcher.dispatch('POST', '/keys', 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\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":["dirname","wrapped","resolvePath","mkdirSync","readEnvWithDeprecation","DriverPlugin","AppPlugin","ObjectKernel","resolvePath","existsSync","mkdirSync","writeFileSync","safeJsonParse","protocol","labels","SeedLoaderService","engine","result","generateRequestId","generateRequestId","ctx","readEnvWithDeprecation"]}
|