@opengeni/worker-bundle 1.0.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/activities/agent-turn/codex.d.ts +1 -1
  2. package/dist/activities/agent-turn/compaction-prep.d.ts +1 -5
  3. package/dist/activities/agent-turn/errors.d.ts +31 -5
  4. package/dist/activities/agent-turn/finalization-monitor.d.ts +17 -0
  5. package/dist/activities/agent-turn/finalization.d.ts +1 -1
  6. package/dist/activities/agent-turn/governance-model.d.ts +0 -2
  7. package/dist/activities/agent-turn/quiescence.d.ts +1 -0
  8. package/dist/activities/agent-turn/recovery-warning.d.ts +8 -0
  9. package/dist/activities/agent-turn/run-credentials.d.ts +0 -1
  10. package/dist/activities/agent-turn/sandbox-establish.d.ts +1 -1
  11. package/dist/activities/agent-turn/sandbox-route.d.ts +0 -20
  12. package/dist/activities/agent-turn/sandbox-runtime.d.ts +1 -1
  13. package/dist/activities/agent-turn/skill-remove.d.ts +14 -0
  14. package/dist/activities/agent-turn/skill-search.d.ts +1 -1
  15. package/dist/activities/agent-turn/stream-attempt.d.ts +1 -0
  16. package/dist/activities/agent-turn/tool-environment.d.ts +0 -4
  17. package/dist/activities/agent-turn/turn-context.d.ts +2 -0
  18. package/dist/activities/agent-turn/turn-sandbox-access.d.ts +3 -0
  19. package/dist/activities/codex-capacity.d.ts +6 -1
  20. package/dist/activities/codex-rotation.d.ts +1 -1
  21. package/dist/activities/context-compaction.d.ts +7 -1
  22. package/dist/activities/mcp-account-routes.d.ts +22 -0
  23. package/dist/activities/mcp-credentials.d.ts +12 -13
  24. package/dist/activities/mcp-operation-authority.d.ts +0 -5
  25. package/dist/activities/rig-verification.d.ts +2 -3
  26. package/dist/activities/sandbox-images.d.ts +1 -1
  27. package/dist/activities/sandbox-lease.d.ts +4 -3
  28. package/dist/activities/session-state.d.ts +57 -2
  29. package/dist/activities/types.d.ts +12 -3
  30. package/dist/{activities-control-HMFGSKC5.js → activities-control-BOLIY3H4.js} +366 -187
  31. package/dist/activities-control-BOLIY3H4.js.map +1 -0
  32. package/dist/activities-control.d.ts +110 -2
  33. package/dist/{activities-turn-AP67JADS.js → activities-turn-2B3WMHBB.js} +767 -471
  34. package/dist/activities-turn-2B3WMHBB.js.map +1 -0
  35. package/dist/activities.d.ts +110 -2
  36. package/dist/artifact-materializer-entry.js +5 -2
  37. package/dist/artifact-materializer-entry.js.map +1 -1
  38. package/dist/artifact-outbox-entry.js +2 -2
  39. package/dist/artifact-outbox-entry.js.map +1 -1
  40. package/dist/{chunk-A4XQWVZK.js → chunk-I7HKKMUJ.js} +77 -1
  41. package/dist/chunk-I7HKKMUJ.js.map +1 -0
  42. package/dist/{chunk-CYITU5UH.js → chunk-TVEE2UUC.js} +275 -146
  43. package/dist/chunk-TVEE2UUC.js.map +1 -0
  44. package/dist/editable-artifact-materializer-service.d.ts +2 -2
  45. package/dist/editable-artifact-outbox-service.d.ts +2 -2
  46. package/dist/index.d.ts +55 -1
  47. package/dist/index.js +4 -3
  48. package/dist/index.js.map +1 -1
  49. package/dist/observability-metrics.d.ts +11 -3
  50. package/dist/retained-process-diagnostics.d.ts +4 -0
  51. package/dist/sandbox-resume.d.ts +2 -12
  52. package/dist/sandbox-routing.d.ts +5 -3
  53. package/dist/sandbox-snapshot-diagnostics.d.ts +20 -0
  54. package/dist/warm-capture-holder.d.ts +3 -0
  55. package/dist/workflow-bundle.js +51 -11
  56. package/package.json +15 -15
  57. package/src/activities/agent-turn/agent-build.ts +42 -5
  58. package/src/activities/agent-turn/claim.ts +12 -0
  59. package/src/activities/agent-turn/codex-capacity.ts +26 -4
  60. package/src/activities/agent-turn/codex.ts +6 -2
  61. package/src/activities/agent-turn/compaction-prep.ts +53 -72
  62. package/src/activities/agent-turn/errors.ts +98 -10
  63. package/src/activities/agent-turn/failure-settlement.ts +49 -28
  64. package/src/activities/agent-turn/finalization-monitor.ts +121 -0
  65. package/src/activities/agent-turn/finalization.ts +79 -21
  66. package/src/activities/agent-turn/governance-model.ts +15 -19
  67. package/src/activities/agent-turn/history.ts +24 -10
  68. package/src/activities/agent-turn/quiescence.ts +3 -0
  69. package/src/activities/agent-turn/recovery-warning.ts +18 -0
  70. package/src/activities/agent-turn/run-credentials.ts +3 -7
  71. package/src/activities/agent-turn/run.ts +68 -52
  72. package/src/activities/agent-turn/sandbox-establish.ts +10 -2
  73. package/src/activities/agent-turn/sandbox-route.ts +0 -20
  74. package/src/activities/agent-turn/sandbox-runtime.ts +40 -7
  75. package/src/activities/agent-turn/skill-remove.ts +46 -0
  76. package/src/activities/agent-turn/skill-save.ts +1 -1
  77. package/src/activities/agent-turn/skill-search.ts +1 -1
  78. package/src/activities/agent-turn/skill-selection.ts +2 -0
  79. package/src/activities/agent-turn/skill-tools.ts +10 -5
  80. package/src/activities/agent-turn/stream-attempt.ts +38 -15
  81. package/src/activities/agent-turn/tool-environment.ts +44 -29
  82. package/src/activities/agent-turn/turn-context.ts +3 -0
  83. package/src/activities/agent-turn/turn-sandbox-access.ts +7 -1
  84. package/src/activities/capabilities.ts +17 -2
  85. package/src/activities/codex-capacity.ts +38 -9
  86. package/src/activities/codex-rotation.ts +18 -5
  87. package/src/activities/context-compaction.ts +26 -4
  88. package/src/activities/goals.ts +1 -0
  89. package/src/activities/google-drive-publication.ts +1 -3
  90. package/src/activities/mcp-account-routes.ts +139 -0
  91. package/src/activities/mcp-credentials.ts +83 -194
  92. package/src/activities/mcp-operation-authority.ts +16 -41
  93. package/src/activities/parent-wake.ts +8 -0
  94. package/src/activities/rig-verification.ts +38 -37
  95. package/src/activities/run-input.ts +25 -16
  96. package/src/activities/sandbox-images.ts +0 -1
  97. package/src/activities/sandbox-lease.ts +177 -44
  98. package/src/activities/scheduled-tasks.ts +118 -93
  99. package/src/activities/session-state.ts +83 -3
  100. package/src/activities/types.ts +18 -2
  101. package/src/activities/workflow-wake.ts +2 -17
  102. package/src/editable-artifact-materializer-service.ts +7 -3
  103. package/src/editable-artifact-outbox-service.ts +4 -4
  104. package/src/github-rest-mcp.ts +0 -1
  105. package/src/index.ts +2 -1
  106. package/src/observability-metrics.ts +105 -2
  107. package/src/personal-github-git-credentials.ts +0 -1
  108. package/src/pr-review-credentials.ts +0 -2
  109. package/src/retained-process-diagnostics.ts +50 -0
  110. package/src/sandbox-resume.ts +58 -73
  111. package/src/sandbox-routing.ts +44 -19
  112. package/src/sandbox-snapshot-diagnostics.ts +112 -0
  113. package/src/warm-capture-holder.ts +15 -0
  114. package/src/workflows/session.ts +64 -2
  115. package/dist/activities/agent-turn/knowledge-sources.d.ts +0 -20
  116. package/dist/activities/packs.d.ts +0 -55
  117. package/dist/activities-control-HMFGSKC5.js.map +0 -1
  118. package/dist/activities-turn-AP67JADS.js.map +0 -1
  119. package/dist/chunk-A4XQWVZK.js.map +0 -1
  120. package/dist/chunk-CYITU5UH.js.map +0 -1
  121. package/src/activities/agent-turn/knowledge-sources.ts +0 -86
  122. package/src/activities/packs.ts +0 -166
@@ -3,7 +3,7 @@ import "./chunk-PZ5AY32C.js";
3
3
  // src/editable-artifact-outbox-service.ts
4
4
  import {
5
5
  dbSearchPath,
6
- getSettings,
6
+ getArtifactOutboxSettings,
7
7
  resolveNatsControlPlaneAuth
8
8
  } from "@opengeni/config";
9
9
  import { createObservability } from "@opengeni/observability";
@@ -597,7 +597,7 @@ function readEditableArtifactOutboxSidecarEnvironment(environment = process.env)
597
597
  async function createOutboxSidecarFromEnvironment(environment = process.env) {
598
598
  const sidecar = readEditableArtifactOutboxSidecarEnvironment(environment);
599
599
  if (!sidecar) return null;
600
- const settings = getSettings();
600
+ const settings = getArtifactOutboxSettings(environment);
601
601
  const controlPlaneAuth = resolveNatsControlPlaneAuth(settings);
602
602
  const natsAuth = controlPlaneAuth ? {
603
603
  kind: "user-password",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/editable-artifact-outbox-service.ts","../src/editable-artifact-outbox-dispatcher.ts","../src/editable-artifact-hint-broker.ts","../src/artifact-outbox-entry.ts"],"sourcesContent":["import {\n dbSearchPath,\n getSettings,\n resolveNatsControlPlaneAuth,\n type Settings,\n} from \"@opengeni/config\";\nimport type { EditableArtifactOutboxDispatchSummary } from \"@opengeni/core\";\nimport { createObservability, type Observability } from \"@opengeni/observability\";\n\nimport {\n EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV,\n EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE,\n createEditableArtifactOutboxWorker,\n type EditableArtifactOutboxWorkerRuntime,\n} from \"./editable-artifact-outbox-dispatcher\";\nimport type { EditableArtifactHintNatsAuth } from \"./editable-artifact-hint-broker\";\n\nexport type EditableArtifactOutboxServiceState =\n | \"starting\"\n | \"ready\"\n | \"draining\"\n | \"stopped\"\n | \"failed\";\n\nexport interface EditableArtifactOutboxRuntimePort {\n start(): Promise<void>;\n drain(): boolean;\n stop(): Promise<void>;\n check(signal?: AbortSignal): Promise<void>;\n readonly dispatcher: Readonly<{\n dispatchOnce(): Promise<EditableArtifactOutboxDispatchSummary>;\n }>;\n}\n\nexport type EditableArtifactOutboxService = Readonly<{\n state(): EditableArtifactOutboxServiceState;\n run(): Promise<void>;\n drain(reason?: string): boolean;\n close(): Promise<void>;\n dispatchOnce(): Promise<EditableArtifactOutboxDispatchSummary>;\n fetch(request: Request): Promise<Response>;\n}>;\n\nexport type CreateEditableArtifactOutboxServiceInput = Readonly<{\n runtime: EditableArtifactOutboxRuntimePort;\n observability: Observability;\n serviceName: string;\n environment: string;\n deploymentRevision?: string;\n readinessTimeoutMs?: number;\n}>;\n\nexport type ProductionEditableArtifactOutboxServiceOptions = Readonly<{\n settings: Settings;\n databaseUrl: string;\n declaredDatabaseRole: string;\n natsUrl: string;\n natsAuth: EditableArtifactHintNatsAuth;\n owner: string;\n databasePoolSize?: number;\n batchSize?: number;\n concurrency?: number;\n leaseDurationMs?: number;\n leaseRenewIntervalMs?: number;\n pollIntervalMs?: number;\n publishTimeoutMs?: number;\n retryBaseMs?: number;\n retryMaxMs?: number;\n}>;\n\n/** Compose the independently supervised production outbox dispatcher. */\nexport async function createProductionEditableArtifactOutboxService(\n options: ProductionEditableArtifactOutboxServiceOptions,\n): Promise<EditableArtifactOutboxService> {\n if (options.declaredDatabaseRole !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE) {\n throw new Error(\"Artifact outbox dispatcher database role declaration is invalid\");\n }\n const observability = createObservability(options.settings, {\n component: \"artifact-outbox-dispatcher\",\n });\n const databaseSearchPath = dbSearchPath(options.settings);\n const runtime = await createEditableArtifactOutboxWorker({\n dispatcherDatabaseUrl: options.databaseUrl,\n ...(databaseSearchPath ? { databaseSearchPath } : {}),\n ...(options.databasePoolSize === undefined\n ? {}\n : { databasePoolSize: options.databasePoolSize }),\n natsUrl: options.natsUrl,\n natsAuth: options.natsAuth,\n owner: options.owner,\n dispatcher: {\n ...(options.batchSize === undefined ? {} : { batchSize: options.batchSize }),\n ...(options.concurrency === undefined ? {} : { concurrency: options.concurrency }),\n ...(options.leaseDurationMs === undefined\n ? {}\n : { leaseDurationMs: options.leaseDurationMs }),\n ...(options.leaseRenewIntervalMs === undefined\n ? {}\n : { leaseRenewIntervalMs: options.leaseRenewIntervalMs }),\n ...(options.pollIntervalMs === undefined ? {} : { pollIntervalMs: options.pollIntervalMs }),\n ...(options.publishTimeoutMs === undefined\n ? {}\n : { publishTimeoutMs: options.publishTimeoutMs }),\n ...(options.retryBaseMs === undefined ? {} : { retryBaseMs: options.retryBaseMs }),\n ...(options.retryMaxMs === undefined ? {} : { retryMaxMs: options.retryMaxMs }),\n },\n metrics: {\n increment(outcome, count = 1) {\n observability.incrementCounter({\n name: \"opengeni_artifact_outbox_dispatch_total\",\n help: \"Editable artifact outbox dispatch actions by closed outcome.\",\n labels: { outcome },\n amount: count,\n });\n },\n observePublishSeconds(outcome, seconds) {\n observability.observeHistogram({\n name: \"opengeni_artifact_outbox_publish_seconds\",\n help: \"Editable artifact broker publication latency by closed outcome.\",\n labels: { outcome },\n value: seconds,\n });\n },\n },\n logger: {\n warn(message, attributes) {\n observability.warn(message, {\n errorClass: \"WorkerOperationError\",\n errorCode: \"worker_operation_failed\",\n origin: \"worker\",\n outcome: typeof attributes.code === \"string\" ? attributes.code : \"unknown\",\n });\n },\n },\n });\n return createEditableArtifactOutboxService({\n runtime,\n observability,\n serviceName: options.settings.serviceName,\n environment: options.settings.environment,\n deploymentRevision: options.settings.deploymentRevision,\n });\n}\n\nexport function createEditableArtifactOutboxService(\n input: CreateEditableArtifactOutboxServiceInput,\n): EditableArtifactOutboxService {\n let state: EditableArtifactOutboxServiceState = \"starting\";\n let runPromise: Promise<void> | null = null;\n let closePromise: Promise<void> | null = null;\n let readinessPromise: Promise<void> | null = null;\n const readinessTimeoutMs = input.readinessTimeoutMs ?? 2_000;\n\n const ready = (): Promise<void> => {\n if (readinessPromise) return readinessPromise;\n const abort = new AbortController();\n const check = withTimeout(input.runtime.check(abort.signal), readinessTimeoutMs, abort);\n readinessPromise = check;\n void check.then(\n () => {\n if (readinessPromise === check) readinessPromise = null;\n },\n () => {\n if (readinessPromise === check) readinessPromise = null;\n },\n );\n return check;\n };\n\n const run = (): Promise<void> => {\n if (runPromise) return runPromise;\n if (state !== \"starting\") {\n return Promise.reject(new Error(\"Artifact outbox dispatcher service cannot be restarted\"));\n }\n runPromise = (async () => {\n try {\n await ready();\n if ((state as EditableArtifactOutboxServiceState) === \"draining\") {\n state = \"stopped\";\n return;\n }\n const running = input.runtime.start();\n state = \"ready\";\n await running;\n const exitWasDraining = (state as EditableArtifactOutboxServiceState) === \"draining\";\n state = exitWasDraining ? \"stopped\" : \"failed\";\n if (!exitWasDraining) {\n throw new Error(\"Artifact outbox dispatcher exited without a drain request\");\n }\n } catch (error) {\n const caughtState = state as EditableArtifactOutboxServiceState;\n if (caughtState !== \"draining\" && caughtState !== \"stopped\") state = \"failed\";\n throw error;\n }\n })();\n return runPromise;\n };\n\n const drain = (_reason = \"shutdown\"): boolean => {\n if (state === \"draining\" || state === \"stopped\" || state === \"failed\") return false;\n state = \"draining\";\n input.runtime.drain();\n return true;\n };\n\n const close = (): Promise<void> => {\n if (closePromise) return closePromise;\n closePromise = (async () => {\n drain(\"close\");\n if (runPromise) await runPromise.catch(() => undefined);\n await input.runtime.stop();\n if (state !== \"failed\") state = \"stopped\";\n })();\n return closePromise;\n };\n\n const fetch = async (request: Request): Promise<Response> => {\n const url = new URL(request.url);\n if (request.method !== \"GET\") {\n return Response.json({ error: \"method_not_allowed\" }, { status: 405 });\n }\n if (url.pathname === \"/healthz\") {\n const ok = state !== \"failed\" && state !== \"stopped\";\n return Response.json(\n {\n service: input.serviceName,\n component: \"artifact-outbox-dispatcher\",\n environment: input.environment,\n ...(input.deploymentRevision ? { deploymentRevision: input.deploymentRevision } : {}),\n state,\n ok,\n },\n { status: ok ? 200 : 503 },\n );\n }\n if (url.pathname === \"/readyz\") {\n if (state !== \"ready\") {\n return Response.json(\n {\n ok: false,\n state,\n checks: { databaseRole: { ok: false }, nats: { ok: false } },\n },\n { status: 503 },\n );\n }\n try {\n await ready();\n return Response.json({\n ok: true,\n state,\n checks: { databaseRole: { ok: true }, nats: { ok: true } },\n });\n } catch {\n return Response.json(\n {\n ok: false,\n state,\n checks: { databaseRole: { ok: false }, nats: { ok: false } },\n },\n { status: 503 },\n );\n }\n }\n if (url.pathname === \"/metrics\") {\n return new Response(await input.observability.prometheusMetrics(), {\n status: 200,\n headers: { \"content-type\": \"text/plain; version=0.0.4; charset=utf-8\" },\n });\n }\n return Response.json({ error: \"not_found\" }, { status: 404 });\n };\n\n return Object.freeze({\n state: () => state,\n run,\n drain,\n close,\n dispatchOnce: async () => await input.runtime.dispatcher.dispatchOnce(),\n fetch,\n });\n}\n\nexport type EditableArtifactOutboxSidecarEnvironment = Readonly<{\n databaseUrl: string;\n declaredDatabaseRole: string;\n owner: string;\n httpPort: number;\n databasePoolSize: number;\n batchSize: number;\n concurrency: number;\n leaseDurationMs: number;\n leaseRenewIntervalMs: number;\n pollIntervalMs: number;\n publishTimeoutMs: number;\n retryBaseMs: number;\n retryMaxMs: number;\n}>;\n\nexport function readEditableArtifactOutboxSidecarEnvironment(\n environment: NodeJS.ProcessEnv = process.env,\n): EditableArtifactOutboxSidecarEnvironment | null {\n if (environment.OPENGENI_ARTIFACT_OUTBOX_ENABLED !== \"true\") return null;\n const declaredDatabaseRole = required(environment, \"OPENGENI_ARTIFACT_OUTBOX_DATABASE_ROLE\");\n if (declaredDatabaseRole !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_DATABASE_ROLE is invalid\");\n }\n const result = {\n databaseUrl: required(environment, EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV),\n declaredDatabaseRole,\n owner:\n environment.OPENGENI_ARTIFACT_OUTBOX_OWNER?.trim() ||\n `artifact-outbox-${process.pid}-${crypto.randomUUID()}`,\n httpPort: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_HTTP_PORT\", 9466, 1, 65_535),\n databasePoolSize: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_DB_POOL_SIZE\", 4, 1, 8),\n batchSize: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_BATCH_SIZE\", 32, 1, 1_000),\n concurrency: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_CONCURRENCY\", 8, 1, 128),\n leaseDurationMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_LEASE_MS\",\n 30_000,\n 1_000,\n 86_400_000,\n ),\n leaseRenewIntervalMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_RENEW_MS\",\n 10_000,\n 100,\n 43_199_999,\n ),\n pollIntervalMs: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_POLL_MS\", 500, 10, 60_000),\n publishTimeoutMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_PUBLISH_TIMEOUT_MS\",\n 5_000,\n 100,\n 60_000,\n ),\n retryBaseMs: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_RETRY_BASE_MS\", 500, 10, 60_000),\n retryMaxMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_RETRY_MAX_MS\",\n 60_000,\n 10,\n 86_400_000,\n ),\n } as const;\n if (result.leaseRenewIntervalMs >= result.leaseDurationMs) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_RENEW_MS must be less than lease duration\");\n }\n if (result.retryBaseMs > result.retryMaxMs) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_RETRY_BASE_MS must not exceed retry max\");\n }\n return Object.freeze(result);\n}\n\nexport async function createOutboxSidecarFromEnvironment(\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<Readonly<{ service: EditableArtifactOutboxService; httpPort: number }> | null> {\n const sidecar = readEditableArtifactOutboxSidecarEnvironment(environment);\n if (!sidecar) return null;\n const settings = getSettings();\n const controlPlaneAuth = resolveNatsControlPlaneAuth(settings);\n const natsAuth: EditableArtifactHintNatsAuth = controlPlaneAuth\n ? {\n kind: \"user-password\",\n user: controlPlaneAuth.user,\n pass: controlPlaneAuth.password,\n }\n : { kind: \"anonymous\" };\n const service = await createProductionEditableArtifactOutboxService({\n settings,\n databaseUrl: sidecar.databaseUrl,\n declaredDatabaseRole: sidecar.declaredDatabaseRole,\n natsUrl: settings.natsUrl,\n natsAuth,\n owner: sidecar.owner,\n databasePoolSize: sidecar.databasePoolSize,\n batchSize: sidecar.batchSize,\n concurrency: sidecar.concurrency,\n leaseDurationMs: sidecar.leaseDurationMs,\n leaseRenewIntervalMs: sidecar.leaseRenewIntervalMs,\n pollIntervalMs: sidecar.pollIntervalMs,\n publishTimeoutMs: sidecar.publishTimeoutMs,\n retryBaseMs: sidecar.retryBaseMs,\n retryMaxMs: sidecar.retryMaxMs,\n });\n return Object.freeze({ service, httpPort: sidecar.httpPort });\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n milliseconds: number,\n abort: AbortController,\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n abort.abort();\n reject(new Error(\"readiness check timed out\"));\n }, milliseconds);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\nfunction required(environment: NodeJS.ProcessEnv, name: string): string {\n const value = environment[name]?.trim();\n if (!value) throw new Error(`${name} is required when artifact outbox dispatch is enabled`);\n return value;\n}\n\nfunction integer(\n environment: NodeJS.ProcessEnv,\n name: string,\n fallback: number,\n minimum: number,\n maximum: number,\n): number {\n const raw = environment[name];\n const value = raw === undefined ? fallback : Number(raw);\n if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {\n throw new Error(`${name} is outside its allowed range`);\n }\n return value;\n}\n\n// Compile-time assurance that production composition satisfies the service port.\nconst _runtimePort: EditableArtifactOutboxRuntimePort | undefined = undefined as\n | EditableArtifactOutboxWorkerRuntime\n | undefined;\nvoid _runtimePort;\n","import {\n EditableArtifactLiveOutboxDispatcher,\n MathEditableArtifactOutboxRandom,\n SystemEditableArtifactLiveClock,\n SystemEditableArtifactLiveScheduler,\n type EditableArtifactOutboxDispatcherOptions,\n type EditableArtifactOutboxLoggerPort,\n type EditableArtifactOutboxMetricsPort,\n type EditableArtifactOutboxDispatcherStorePort,\n type EditableArtifactLiveOutboxRecord,\n} from \"@opengeni/core\";\nimport {\n PostgresEditableArtifactStore,\n createDb,\n dbSql,\n type Database,\n type DbClient,\n} from \"@opengeni/db\";\n\nimport {\n connectEditableArtifactHintBroker,\n type ConfirmedNatsEditableArtifactHintBroker,\n type EditableArtifactHintNatsAuth,\n} from \"./editable-artifact-hint-broker\";\n\nexport const EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE =\n \"opengeni_artifact_outbox_dispatcher\";\nexport const EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV = \"OPENGENI_ARTIFACT_OUTBOX_DATABASE_URL\";\n\nexport type EditableArtifactOutboxWorkerOptions = Readonly<{\n /** Must authenticate as the dedicated dispatcher role, never the generic app role. */\n dispatcherDatabaseUrl: string;\n databaseSearchPath?: string;\n databasePoolSize?: number;\n natsUrl: string;\n natsAuth: EditableArtifactHintNatsAuth;\n owner?: string;\n dispatcher?: Omit<EditableArtifactOutboxDispatcherOptions, \"owner\">;\n metrics?: EditableArtifactOutboxMetricsPort;\n logger?: EditableArtifactOutboxLoggerPort;\n}>;\n\n/** Explicit lifecycle handle; hosts supervise `start()` and await `stop()` on drain. */\nexport class EditableArtifactOutboxWorkerRuntime {\n private readonly abort = new AbortController();\n private running: Promise<void> | null = null;\n private closing: Promise<void> | null = null;\n\n constructor(\n readonly dispatcher: EditableArtifactLiveOutboxDispatcher,\n private readonly broker: ConfirmedNatsEditableArtifactHintBroker,\n private readonly database: DbClient,\n ) {}\n\n start(): Promise<void> {\n if (this.closing) return Promise.reject(new Error(\"Artifact outbox worker is stopping\"));\n this.running ??= this.dispatcher.run(this.abort.signal);\n return this.running;\n }\n\n drain(): boolean {\n if (this.abort.signal.aborted) return false;\n this.abort.abort();\n return true;\n }\n\n async check(signal?: AbortSignal): Promise<void> {\n if (this.abort.signal.aborted || this.closing) {\n throw new Error(\"Artifact outbox worker is stopping\");\n }\n await Promise.all([\n assertDedicatedOutboxDispatcherDatabaseRole(this.database.db),\n this.broker.check(signal),\n ]);\n }\n\n stop(): Promise<void> {\n if (this.closing) return this.closing;\n this.closing = this.stopOnce();\n return this.closing;\n }\n\n private async stopOnce(): Promise<void> {\n this.drain();\n const running = this.running ? await Promise.allSettled([this.running]) : [];\n const cleanup = await Promise.allSettled([this.broker.close(), this.database.close()]);\n const failure = [...running, ...cleanup].find(\n (result): result is PromiseRejectedResult => result.status === \"rejected\",\n );\n if (failure) throw failure.reason;\n }\n}\n\n/**\n * Production composition. DB grants make the role a narrow capability: it can\n * execute only lease-fenced dispatcher functions and cannot read artifact rows.\n */\nexport async function createEditableArtifactOutboxWorker(\n options: EditableArtifactOutboxWorkerOptions,\n): Promise<EditableArtifactOutboxWorkerRuntime> {\n const dispatcherDatabaseUrl = dedicatedDispatcherDatabaseUrl(options.dispatcherDatabaseUrl);\n const databasePoolSize = options.databasePoolSize ?? 2;\n if (!Number.isSafeInteger(databasePoolSize) || databasePoolSize < 1 || databasePoolSize > 8) {\n throw new TypeError(\"Artifact outbox dispatcher DB pool size must be 1-8\");\n }\n const database = createDb(dispatcherDatabaseUrl, {\n max: databasePoolSize,\n ...(options.databaseSearchPath ? { searchPath: options.databaseSearchPath } : {}),\n });\n let broker: ConfirmedNatsEditableArtifactHintBroker;\n try {\n await assertDedicatedOutboxDispatcherDatabaseRole(database.db);\n broker = await connectEditableArtifactHintBroker({\n natsUrl: options.natsUrl,\n auth: options.natsAuth,\n });\n } catch (error) {\n await database.close();\n throw error;\n }\n const persistence = new PostgresEditableArtifactStore(database.db);\n const store = dispatcherStore(persistence);\n const dispatcher = new EditableArtifactLiveOutboxDispatcher(\n {\n store,\n broker,\n clock: new SystemEditableArtifactLiveClock(),\n scheduler: new SystemEditableArtifactLiveScheduler(),\n random: new MathEditableArtifactOutboxRandom(),\n ...(options.metrics ? { metrics: options.metrics } : {}),\n ...(options.logger ? { logger: options.logger } : {}),\n },\n {\n owner: options.owner ?? `artifact-outbox:${crypto.randomUUID()}`,\n ...options.dispatcher,\n },\n );\n return new EditableArtifactOutboxWorkerRuntime(dispatcher, broker, database);\n}\n\n/**\n * Verify the database identity and its negative capability at runtime. A DSN\n * username check alone is insufficient because PostgreSQL role inheritance,\n * SET ROLE, or a mis-provisioned grant could otherwise widen this worker.\n */\nexport async function assertDedicatedOutboxDispatcherDatabaseRole(db: Database): Promise<void> {\n const raw = await db.execute<{\n current_role: string;\n session_role: string;\n can_access_any_relation: boolean;\n can_access_any_sequence: boolean;\n }>(dbSql`\n select\n current_user::text as current_role,\n session_user::text as session_role,\n exists (\n select 1\n from pg_catalog.pg_class relation_row\n join pg_catalog.pg_namespace namespace_row\n on namespace_row.oid = relation_row.relnamespace\n where namespace_row.nspname = current_schema()\n and relation_row.relkind in ('r', 'p', 'v', 'm', 'f')\n and (\n has_table_privilege(current_user, relation_row.oid, 'SELECT')\n or has_table_privilege(current_user, relation_row.oid, 'INSERT')\n or has_table_privilege(current_user, relation_row.oid, 'UPDATE')\n or has_table_privilege(current_user, relation_row.oid, 'DELETE')\n or has_table_privilege(current_user, relation_row.oid, 'TRUNCATE')\n or has_table_privilege(current_user, relation_row.oid, 'REFERENCES')\n or has_table_privilege(current_user, relation_row.oid, 'TRIGGER')\n or has_any_column_privilege(current_user, relation_row.oid, 'SELECT')\n or has_any_column_privilege(current_user, relation_row.oid, 'INSERT')\n or has_any_column_privilege(current_user, relation_row.oid, 'UPDATE')\n or has_any_column_privilege(current_user, relation_row.oid, 'REFERENCES')\n )\n ) as can_access_any_relation,\n exists (\n select 1\n from pg_catalog.pg_class sequence_row\n join pg_catalog.pg_namespace namespace_row\n on namespace_row.oid = sequence_row.relnamespace\n where namespace_row.nspname = current_schema()\n and sequence_row.relkind = 'S'\n and (\n has_sequence_privilege(current_user, sequence_row.oid, 'USAGE')\n or has_sequence_privilege(current_user, sequence_row.oid, 'SELECT')\n or has_sequence_privilege(current_user, sequence_row.oid, 'UPDATE')\n )\n ) as can_access_any_sequence\n `);\n const rows = Array.isArray(raw) ? raw : ((raw as unknown as { rows?: unknown[] }).rows ?? []);\n const row = rows[0] as\n | {\n current_role?: unknown;\n session_role?: unknown;\n can_access_any_relation?: unknown;\n can_access_any_sequence?: unknown;\n }\n | undefined;\n if (\n row?.current_role !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE ||\n row.session_role !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE ||\n row.can_access_any_relation !== false ||\n row.can_access_any_sequence !== false\n ) {\n throw new Error(\"Artifact outbox dispatcher database connection has an unsafe role posture\");\n }\n}\n\nfunction dispatcherStore(\n persistence: PostgresEditableArtifactStore,\n): EditableArtifactOutboxDispatcherStorePort {\n return {\n claimLiveOutbox: async (input) =>\n (await persistence.claimLiveOutbox(\n input,\n )) as unknown as readonly EditableArtifactLiveOutboxRecord[],\n renewLiveOutbox: async (input) => await persistence.renewLiveOutbox(input),\n markLiveOutboxPublished: async (input) => await persistence.markLiveOutboxPublished(input),\n retryLiveOutbox: async (input) => await persistence.retryLiveOutbox(input),\n deadLetterLiveOutbox: async (input) => await persistence.deadLetterLiveOutbox(input),\n };\n}\n\nexport function dedicatedDispatcherDatabaseUrl(raw: string): string {\n if (typeof raw !== \"string\" || raw.length > 8_192 || raw.trim() !== raw) {\n throw new TypeError(`${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} is malformed`);\n }\n let url: URL;\n try {\n url = new URL(raw);\n } catch (cause) {\n throw new TypeError(`${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} is malformed`, { cause });\n }\n if (\n (url.protocol !== \"postgres:\" && url.protocol !== \"postgresql:\") ||\n decodeURIComponent(url.username) !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE\n ) {\n throw new TypeError(\n `${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} must authenticate as ${EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE}`,\n );\n }\n return raw;\n}\n","import {\n EDITABLE_ARTIFACT_HINT_MAX_BYTES,\n type EditableArtifactHintBrokerPort,\n} from \"@opengeni/core\";\nimport { connect, type NatsConnection } from \"@opengeni/events\";\n\nconst DEFAULT_CONNECTION_NAME = \"opengeni-editable-artifact-outbox\";\n\nexport type EditableArtifactHintNatsAuth =\n | Readonly<{ kind: \"user-password\"; user: string; pass: string }>\n | Readonly<{ kind: \"token\"; token: string }>\n | Readonly<{ kind: \"anonymous\" }>;\n\nexport type EditableArtifactHintNatsBrokerOptions = Readonly<{\n maxHintBytes?: number;\n}>;\n\nexport type EditableArtifactHintNatsConnection = Pick<\n NatsConnection,\n \"publish\" | \"flush\" | \"drain\" | \"close\" | \"closed\" | \"isClosed\" | \"isDraining\"\n>;\n\n/**\n * Core-NATS adapter for the durable outbox. A publish resolves only after a\n * server round-trip flush ACK. Reconnect buffering may create duplicates after\n * a timeout; hints are intentionally idempotent wakeups for durable gap-fill.\n */\nexport class ConfirmedNatsEditableArtifactHintBroker implements EditableArtifactHintBrokerPort {\n private readonly maxHintBytes: number;\n\n constructor(\n private readonly connection: EditableArtifactHintNatsConnection,\n options: EditableArtifactHintNatsBrokerOptions = {},\n ) {\n this.maxHintBytes = options.maxHintBytes ?? EDITABLE_ARTIFACT_HINT_MAX_BYTES;\n if (\n !Number.isSafeInteger(this.maxHintBytes) ||\n this.maxHintBytes < 1 ||\n this.maxHintBytes > EDITABLE_ARTIFACT_HINT_MAX_BYTES\n ) {\n throw new TypeError(\"Editable artifact NATS hint byte limit is invalid\");\n }\n }\n\n async publish(\n input: Readonly<{\n subject: string;\n payload: Uint8Array;\n signal: AbortSignal;\n }>,\n ): Promise<void> {\n assertSubject(input.subject);\n if (\n !(input.payload instanceof Uint8Array) ||\n input.payload.byteLength < 1 ||\n input.payload.byteLength > this.maxHintBytes\n ) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_backpressure\",\n \"Editable artifact hint exceeds the NATS envelope\",\n );\n }\n if (input.signal.aborted) throw abortedPublish();\n if (this.connection.isClosed() || this.connection.isDraining()) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS connection is closed\",\n );\n }\n try {\n this.connection.publish(input.subject, input.payload);\n await abortable(this.connection.flush(), input.signal);\n } catch (error) {\n if (input.signal.aborted) throw abortedPublish();\n if (error instanceof EditableArtifactNatsHintPublishError) throw error;\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS publish was not acknowledged\",\n { cause: error },\n );\n }\n }\n\n /**\n * A readiness probe must prove the server is reachable, not merely that the\n * client object has not observed closure yet. `flush()` is a bounded NATS\n * round trip and has the same acknowledgement semantics as publication.\n */\n async check(signal: AbortSignal = new AbortController().signal): Promise<void> {\n if (signal.aborted) throw abortedPublish();\n if (this.connection.isClosed() || this.connection.isDraining()) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS connection is unavailable\",\n );\n }\n try {\n await abortable(this.connection.flush(), signal);\n } catch (error) {\n if (error instanceof EditableArtifactNatsHintPublishError) throw error;\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS readiness round trip failed\",\n { cause: error },\n );\n }\n }\n\n async close(drainTimeoutMs = 5_000): Promise<void> {\n if (!Number.isSafeInteger(drainTimeoutMs) || drainTimeoutMs < 1 || drainTimeoutMs > 30_000) {\n throw new TypeError(\"Editable artifact NATS drain timeout is invalid\");\n }\n if (this.connection.isClosed()) return;\n if (this.connection.isDraining()) {\n await this.connection.closed();\n return;\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n const drain = this.connection.drain();\n const outcome = await Promise.race([\n drain.then(\n () => \"drained\" as const,\n () => \"failed\" as const,\n ),\n new Promise<\"timed_out\">((resolve) => {\n timer = setTimeout(() => resolve(\"timed_out\"), drainTimeoutMs);\n }),\n ]);\n if (timer) clearTimeout(timer);\n if (outcome !== \"drained\" && !this.connection.isClosed()) {\n await this.connection.close();\n }\n }\n}\n\nexport class EditableArtifactNatsHintPublishError extends Error {\n constructor(\n readonly code: \"broker_unavailable\" | \"broker_backpressure\",\n message: string,\n options?: ErrorOptions,\n ) {\n super(message, options);\n this.name = \"EditableArtifactNatsHintPublishError\";\n }\n}\n\n/** Opens one resilient dispatcher identity; callers own `broker.close()`. */\nexport async function connectEditableArtifactHintBroker(\n input: Readonly<{\n natsUrl: string;\n auth: EditableArtifactHintNatsAuth;\n name?: string;\n maxHintBytes?: number;\n }>,\n): Promise<ConfirmedNatsEditableArtifactHintBroker> {\n const natsUrl = boundedText(input.natsUrl, \"NATS URL\", 2_048);\n const name = boundedText(input.name ?? DEFAULT_CONNECTION_NAME, \"NATS connection name\", 128);\n const auth = natsAuthOptions(input.auth);\n const connection = await connect({\n servers: natsUrl,\n name,\n reconnect: true,\n maxReconnectAttempts: -1,\n reconnectTimeWait: 2_000,\n reconnectJitter: 1_000,\n reconnectJitterTLS: 1_000,\n waitOnFirstConnect: true,\n pingInterval: 20_000,\n maxPingOut: 3,\n ...auth,\n });\n return new ConfirmedNatsEditableArtifactHintBroker(connection, {\n ...(input.maxHintBytes === undefined ? {} : { maxHintBytes: input.maxHintBytes }),\n });\n}\n\nfunction natsAuthOptions(auth: EditableArtifactHintNatsAuth): {\n user?: string;\n pass?: string;\n token?: string;\n} {\n if (auth.kind === \"anonymous\") return {};\n if (auth.kind === \"token\") return { token: boundedText(auth.token, \"NATS token\", 4_096) };\n return {\n user: boundedText(auth.user, \"NATS user\", 256),\n pass: boundedText(auth.pass, \"NATS password\", 4_096),\n };\n}\n\nfunction assertSubject(subject: string): void {\n const bytes = new TextEncoder().encode(subject).byteLength;\n if (\n bytes < 1 ||\n bytes > 1_024 ||\n subject.startsWith(\".\") ||\n subject.endsWith(\".\") ||\n subject.includes(\"..\") ||\n /[\\s*>]/u.test(subject)\n ) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_backpressure\",\n \"Editable artifact NATS subject is malformed\",\n );\n }\n}\n\nfunction boundedText(value: string, label: string, maxBytes: number): string {\n const bytes = new TextEncoder().encode(value).byteLength;\n if (bytes < 1 || bytes > maxBytes || value.trim() !== value) {\n throw new TypeError(`${label} is malformed`);\n }\n return value;\n}\n\nfunction abortedPublish(): EditableArtifactNatsHintPublishError {\n return new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS publish was aborted\",\n );\n}\n\nasync function abortable(operation: Promise<void>, signal: AbortSignal): Promise<void> {\n if (signal.aborted) throw abortedPublish();\n let remove: () => void = () => undefined;\n const aborted = new Promise<never>((_resolve, reject) => {\n const onAbort = () => reject(abortedPublish());\n signal.addEventListener(\"abort\", onAbort, { once: true });\n remove = () => signal.removeEventListener(\"abort\", onAbort);\n });\n try {\n await Promise.race([operation, aborted]);\n } finally {\n remove();\n }\n}\n","import { createOutboxSidecarFromEnvironment } from \"./editable-artifact-outbox-service\";\n\n/** Dedicated process: no Temporal/control worker is created or imported here. */\nexport async function runEditableArtifactOutboxSidecar(\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<void> {\n const configured = await createOutboxSidecarFromEnvironment(environment);\n if (!configured) throw new Error(\"Editable artifact outbox sidecar is disabled\");\n const server = Bun.serve({\n hostname: \"0.0.0.0\",\n port: configured.httpPort,\n fetch: configured.service.fetch,\n });\n const stop = () => configured.service.drain(\"process signal\");\n process.on(\"SIGTERM\", stop);\n process.on(\"SIGINT\", stop);\n try {\n await configured.service.run();\n } finally {\n process.off(\"SIGTERM\", stop);\n process.off(\"SIGINT\", stop);\n server.stop(true);\n await configured.service.close();\n }\n}\n\nif (import.meta.main) {\n await runEditableArtifactOutboxSidecar();\n}\n"],"mappings":";;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAEP,SAAS,2BAA+C;;;ACPxD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAMK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;;;ACjBP;AAAA,EACE;AAAA,OAEK;AACP,SAAS,eAAoC;AAE7C,IAAM,0BAA0B;AAqBzB,IAAM,0CAAN,MAAwF;AAAA,EAG7F,YACmB,YACjB,UAAiD,CAAC,GAClD;AAFiB;AAGjB,SAAK,eAAe,QAAQ,gBAAgB;AAC5C,QACE,CAAC,OAAO,cAAc,KAAK,YAAY,KACvC,KAAK,eAAe,KACpB,KAAK,eAAe,kCACpB;AACA,YAAM,IAAI,UAAU,mDAAmD;AAAA,IACzE;AAAA,EACF;AAAA,EAdiB;AAAA,EAgBjB,MAAM,QACJ,OAKe;AACf,kBAAc,MAAM,OAAO;AAC3B,QACE,EAAE,MAAM,mBAAmB,eAC3B,MAAM,QAAQ,aAAa,KAC3B,MAAM,QAAQ,aAAa,KAAK,cAChC;AACA,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAI,MAAM,OAAO,QAAS,OAAM,eAAe;AAC/C,QAAI,KAAK,WAAW,SAAS,KAAK,KAAK,WAAW,WAAW,GAAG;AAC9D,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAI;AACF,WAAK,WAAW,QAAQ,MAAM,SAAS,MAAM,OAAO;AACpD,YAAM,UAAU,KAAK,WAAW,MAAM,GAAG,MAAM,MAAM;AAAA,IACvD,SAAS,OAAO;AACd,UAAI,MAAM,OAAO,QAAS,OAAM,eAAe;AAC/C,UAAI,iBAAiB,qCAAsC,OAAM;AACjE,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAM,SAAsB,IAAI,gBAAgB,EAAE,QAAuB;AAC7E,QAAI,OAAO,QAAS,OAAM,eAAe;AACzC,QAAI,KAAK,WAAW,SAAS,KAAK,KAAK,WAAW,WAAW,GAAG;AAC9D,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,QAAI;AACF,YAAM,UAAU,KAAK,WAAW,MAAM,GAAG,MAAM;AAAA,IACjD,SAAS,OAAO;AACd,UAAI,iBAAiB,qCAAsC,OAAM;AACjE,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,iBAAiB,KAAsB;AACjD,QAAI,CAAC,OAAO,cAAc,cAAc,KAAK,iBAAiB,KAAK,iBAAiB,KAAQ;AAC1F,YAAM,IAAI,UAAU,iDAAiD;AAAA,IACvE;AACA,QAAI,KAAK,WAAW,SAAS,EAAG;AAChC,QAAI,KAAK,WAAW,WAAW,GAAG;AAChC,YAAM,KAAK,WAAW,OAAO;AAC7B;AAAA,IACF;AACA,QAAI;AACJ,UAAM,QAAQ,KAAK,WAAW,MAAM;AACpC,UAAM,UAAU,MAAM,QAAQ,KAAK;AAAA,MACjC,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,MACA,IAAI,QAAqB,CAAC,YAAY;AACpC,gBAAQ,WAAW,MAAM,QAAQ,WAAW,GAAG,cAAc;AAAA,MAC/D,CAAC;AAAA,IACH,CAAC;AACD,QAAI,MAAO,cAAa,KAAK;AAC7B,QAAI,YAAY,aAAa,CAAC,KAAK,WAAW,SAAS,GAAG;AACxD,YAAM,KAAK,WAAW,MAAM;AAAA,IAC9B;AAAA,EACF;AACF;AAEO,IAAM,uCAAN,cAAmD,MAAM;AAAA,EAC9D,YACW,MACT,SACA,SACA;AACA,UAAM,SAAS,OAAO;AAJb;AAKT,SAAK,OAAO;AAAA,EACd;AACF;AAGA,eAAsB,kCACpB,OAMkD;AAClD,QAAM,UAAU,YAAY,MAAM,SAAS,YAAY,IAAK;AAC5D,QAAM,OAAO,YAAY,MAAM,QAAQ,yBAAyB,wBAAwB,GAAG;AAC3F,QAAM,OAAO,gBAAgB,MAAM,IAAI;AACvC,QAAM,aAAa,MAAM,QAAQ;AAAA,IAC/B,SAAS;AAAA,IACT;AAAA,IACA,WAAW;AAAA,IACX,sBAAsB;AAAA,IACtB,mBAAmB;AAAA,IACnB,iBAAiB;AAAA,IACjB,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,CAAC;AACD,SAAO,IAAI,wCAAwC,YAAY;AAAA,IAC7D,GAAI,MAAM,iBAAiB,SAAY,CAAC,IAAI,EAAE,cAAc,MAAM,aAAa;AAAA,EACjF,CAAC;AACH;AAEA,SAAS,gBAAgB,MAIvB;AACA,MAAI,KAAK,SAAS,YAAa,QAAO,CAAC;AACvC,MAAI,KAAK,SAAS,QAAS,QAAO,EAAE,OAAO,YAAY,KAAK,OAAO,cAAc,IAAK,EAAE;AACxF,SAAO;AAAA,IACL,MAAM,YAAY,KAAK,MAAM,aAAa,GAAG;AAAA,IAC7C,MAAM,YAAY,KAAK,MAAM,iBAAiB,IAAK;AAAA,EACrD;AACF;AAEA,SAAS,cAAc,SAAuB;AAC5C,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,OAAO,EAAE;AAChD,MACE,QAAQ,KACR,QAAQ,QACR,QAAQ,WAAW,GAAG,KACtB,QAAQ,SAAS,GAAG,KACpB,QAAQ,SAAS,IAAI,KACrB,UAAU,KAAK,OAAO,GACtB;AACA,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,YAAY,OAAe,OAAe,UAA0B;AAC3E,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,KAAK,EAAE;AAC9C,MAAI,QAAQ,KAAK,QAAQ,YAAY,MAAM,KAAK,MAAM,OAAO;AAC3D,UAAM,IAAI,UAAU,GAAG,KAAK,eAAe;AAAA,EAC7C;AACA,SAAO;AACT;AAEA,SAAS,iBAAuD;AAC9D,SAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,UAAU,WAA0B,QAAoC;AACrF,MAAI,OAAO,QAAS,OAAM,eAAe;AACzC,MAAI,SAAqB,MAAM;AAC/B,QAAM,UAAU,IAAI,QAAe,CAAC,UAAU,WAAW;AACvD,UAAM,UAAU,MAAM,OAAO,eAAe,CAAC;AAC7C,WAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AACxD,aAAS,MAAM,OAAO,oBAAoB,SAAS,OAAO;AAAA,EAC5D,CAAC;AACD,MAAI;AACF,UAAM,QAAQ,KAAK,CAAC,WAAW,OAAO,CAAC;AAAA,EACzC,UAAE;AACA,WAAO;AAAA,EACT;AACF;;;ADjNO,IAAM,oDACX;AACK,IAAM,4CAA4C;AAgBlD,IAAM,sCAAN,MAA0C;AAAA,EAK/C,YACW,YACQ,QACA,UACjB;AAHS;AACQ;AACA;AAAA,EAChB;AAAA,EARc,QAAQ,IAAI,gBAAgB;AAAA,EACrC,UAAgC;AAAA,EAChC,UAAgC;AAAA,EAQxC,QAAuB;AACrB,QAAI,KAAK,QAAS,QAAO,QAAQ,OAAO,IAAI,MAAM,oCAAoC,CAAC;AACvF,SAAK,YAAY,KAAK,WAAW,IAAI,KAAK,MAAM,MAAM;AACtD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,QAAiB;AACf,QAAI,KAAK,MAAM,OAAO,QAAS,QAAO;AACtC,SAAK,MAAM,MAAM;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,QAAqC;AAC/C,QAAI,KAAK,MAAM,OAAO,WAAW,KAAK,SAAS;AAC7C,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AACA,UAAM,QAAQ,IAAI;AAAA,MAChB,4CAA4C,KAAK,SAAS,EAAE;AAAA,MAC5D,KAAK,OAAO,MAAM,MAAM;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EAEA,OAAsB;AACpB,QAAI,KAAK,QAAS,QAAO,KAAK;AAC9B,SAAK,UAAU,KAAK,SAAS;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,WAA0B;AACtC,SAAK,MAAM;AACX,UAAM,UAAU,KAAK,UAAU,MAAM,QAAQ,WAAW,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC;AAC3E,UAAM,UAAU,MAAM,QAAQ,WAAW,CAAC,KAAK,OAAO,MAAM,GAAG,KAAK,SAAS,MAAM,CAAC,CAAC;AACrF,UAAM,UAAU,CAAC,GAAG,SAAS,GAAG,OAAO,EAAE;AAAA,MACvC,CAAC,WAA4C,OAAO,WAAW;AAAA,IACjE;AACA,QAAI,QAAS,OAAM,QAAQ;AAAA,EAC7B;AACF;AAMA,eAAsB,mCACpB,SAC8C;AAC9C,QAAM,wBAAwB,+BAA+B,QAAQ,qBAAqB;AAC1F,QAAM,mBAAmB,QAAQ,oBAAoB;AACrD,MAAI,CAAC,OAAO,cAAc,gBAAgB,KAAK,mBAAmB,KAAK,mBAAmB,GAAG;AAC3F,UAAM,IAAI,UAAU,qDAAqD;AAAA,EAC3E;AACA,QAAM,WAAW,SAAS,uBAAuB;AAAA,IAC/C,KAAK;AAAA,IACL,GAAI,QAAQ,qBAAqB,EAAE,YAAY,QAAQ,mBAAmB,IAAI,CAAC;AAAA,EACjF,CAAC;AACD,MAAI;AACJ,MAAI;AACF,UAAM,4CAA4C,SAAS,EAAE;AAC7D,aAAS,MAAM,kCAAkC;AAAA,MAC/C,SAAS,QAAQ;AAAA,MACjB,MAAM,QAAQ;AAAA,IAChB,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,SAAS,MAAM;AACrB,UAAM;AAAA,EACR;AACA,QAAM,cAAc,IAAI,8BAA8B,SAAS,EAAE;AACjE,QAAM,QAAQ,gBAAgB,WAAW;AACzC,QAAM,aAAa,IAAI;AAAA,IACrB;AAAA,MACE;AAAA,MACA;AAAA,MACA,OAAO,IAAI,gCAAgC;AAAA,MAC3C,WAAW,IAAI,oCAAoC;AAAA,MACnD,QAAQ,IAAI,iCAAiC;AAAA,MAC7C,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;AAAA,MACtD,GAAI,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,IACrD;AAAA,IACA;AAAA,MACE,OAAO,QAAQ,SAAS,mBAAmB,OAAO,WAAW,CAAC;AAAA,MAC9D,GAAG,QAAQ;AAAA,IACb;AAAA,EACF;AACA,SAAO,IAAI,oCAAoC,YAAY,QAAQ,QAAQ;AAC7E;AAOA,eAAsB,4CAA4C,IAA6B;AAC7F,QAAM,MAAM,MAAM,GAAG,QAKlB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAsCF;AACD,QAAM,OAAO,MAAM,QAAQ,GAAG,IAAI,MAAQ,IAAwC,QAAQ,CAAC;AAC3F,QAAM,MAAM,KAAK,CAAC;AAQlB,MACE,KAAK,iBAAiB,qDACtB,IAAI,iBAAiB,qDACrB,IAAI,4BAA4B,SAChC,IAAI,4BAA4B,OAChC;AACA,UAAM,IAAI,MAAM,2EAA2E;AAAA,EAC7F;AACF;AAEA,SAAS,gBACP,aAC2C;AAC3C,SAAO;AAAA,IACL,iBAAiB,OAAO,UACrB,MAAM,YAAY;AAAA,MACjB;AAAA,IACF;AAAA,IACF,iBAAiB,OAAO,UAAU,MAAM,YAAY,gBAAgB,KAAK;AAAA,IACzE,yBAAyB,OAAO,UAAU,MAAM,YAAY,wBAAwB,KAAK;AAAA,IACzF,iBAAiB,OAAO,UAAU,MAAM,YAAY,gBAAgB,KAAK;AAAA,IACzE,sBAAsB,OAAO,UAAU,MAAM,YAAY,qBAAqB,KAAK;AAAA,EACrF;AACF;AAEO,SAAS,+BAA+B,KAAqB;AAClE,MAAI,OAAO,QAAQ,YAAY,IAAI,SAAS,QAAS,IAAI,KAAK,MAAM,KAAK;AACvE,UAAM,IAAI,UAAU,GAAG,yCAAyC,eAAe;AAAA,EACjF;AACA,MAAI;AACJ,MAAI;AACF,UAAM,IAAI,IAAI,GAAG;AAAA,EACnB,SAAS,OAAO;AACd,UAAM,IAAI,UAAU,GAAG,yCAAyC,iBAAiB,EAAE,MAAM,CAAC;AAAA,EAC5F;AACA,MACG,IAAI,aAAa,eAAe,IAAI,aAAa,iBAClD,mBAAmB,IAAI,QAAQ,MAAM,mDACrC;AACA,UAAM,IAAI;AAAA,MACR,GAAG,yCAAyC,yBAAyB,iDAAiD;AAAA,IACxH;AAAA,EACF;AACA,SAAO;AACT;;;AD5KA,eAAsB,8CACpB,SACwC;AACxC,MAAI,QAAQ,yBAAyB,mDAAmD;AACtF,UAAM,IAAI,MAAM,iEAAiE;AAAA,EACnF;AACA,QAAM,gBAAgB,oBAAoB,QAAQ,UAAU;AAAA,IAC1D,WAAW;AAAA,EACb,CAAC;AACD,QAAM,qBAAqB,aAAa,QAAQ,QAAQ;AACxD,QAAM,UAAU,MAAM,mCAAmC;AAAA,IACvD,uBAAuB,QAAQ;AAAA,IAC/B,GAAI,qBAAqB,EAAE,mBAAmB,IAAI,CAAC;AAAA,IACnD,GAAI,QAAQ,qBAAqB,SAC7B,CAAC,IACD,EAAE,kBAAkB,QAAQ,iBAAiB;AAAA,IACjD,SAAS,QAAQ;AAAA,IACjB,UAAU,QAAQ;AAAA,IAClB,OAAO,QAAQ;AAAA,IACf,YAAY;AAAA,MACV,GAAI,QAAQ,cAAc,SAAY,CAAC,IAAI,EAAE,WAAW,QAAQ,UAAU;AAAA,MAC1E,GAAI,QAAQ,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,QAAQ,YAAY;AAAA,MAChF,GAAI,QAAQ,oBAAoB,SAC5B,CAAC,IACD,EAAE,iBAAiB,QAAQ,gBAAgB;AAAA,MAC/C,GAAI,QAAQ,yBAAyB,SACjC,CAAC,IACD,EAAE,sBAAsB,QAAQ,qBAAqB;AAAA,MACzD,GAAI,QAAQ,mBAAmB,SAAY,CAAC,IAAI,EAAE,gBAAgB,QAAQ,eAAe;AAAA,MACzF,GAAI,QAAQ,qBAAqB,SAC7B,CAAC,IACD,EAAE,kBAAkB,QAAQ,iBAAiB;AAAA,MACjD,GAAI,QAAQ,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,QAAQ,YAAY;AAAA,MAChF,GAAI,QAAQ,eAAe,SAAY,CAAC,IAAI,EAAE,YAAY,QAAQ,WAAW;AAAA,IAC/E;AAAA,IACA,SAAS;AAAA,MACP,UAAU,SAAS,QAAQ,GAAG;AAC5B,sBAAc,iBAAiB;AAAA,UAC7B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,QAAQ,EAAE,QAAQ;AAAA,UAClB,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,MACA,sBAAsB,SAAS,SAAS;AACtC,sBAAc,iBAAiB;AAAA,UAC7B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,QAAQ,EAAE,QAAQ;AAAA,UAClB,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,KAAK,SAAS,YAAY;AACxB,sBAAc,KAAK,SAAS;AAAA,UAC1B,YAAY;AAAA,UACZ,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,SAAS,OAAO,WAAW,SAAS,WAAW,WAAW,OAAO;AAAA,QACnE,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AACD,SAAO,oCAAoC;AAAA,IACzC;AAAA,IACA;AAAA,IACA,aAAa,QAAQ,SAAS;AAAA,IAC9B,aAAa,QAAQ,SAAS;AAAA,IAC9B,oBAAoB,QAAQ,SAAS;AAAA,EACvC,CAAC;AACH;AAEO,SAAS,oCACd,OAC+B;AAC/B,MAAI,QAA4C;AAChD,MAAI,aAAmC;AACvC,MAAI,eAAqC;AACzC,MAAI,mBAAyC;AAC7C,QAAM,qBAAqB,MAAM,sBAAsB;AAEvD,QAAM,QAAQ,MAAqB;AACjC,QAAI,iBAAkB,QAAO;AAC7B,UAAM,QAAQ,IAAI,gBAAgB;AAClC,UAAM,QAAQ,YAAY,MAAM,QAAQ,MAAM,MAAM,MAAM,GAAG,oBAAoB,KAAK;AACtF,uBAAmB;AACnB,SAAK,MAAM;AAAA,MACT,MAAM;AACJ,YAAI,qBAAqB,MAAO,oBAAmB;AAAA,MACrD;AAAA,MACA,MAAM;AACJ,YAAI,qBAAqB,MAAO,oBAAmB;AAAA,MACrD;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,MAAqB;AAC/B,QAAI,WAAY,QAAO;AACvB,QAAI,UAAU,YAAY;AACxB,aAAO,QAAQ,OAAO,IAAI,MAAM,wDAAwD,CAAC;AAAA,IAC3F;AACA,kBAAc,YAAY;AACxB,UAAI;AACF,cAAM,MAAM;AACZ,YAAK,UAAiD,YAAY;AAChE,kBAAQ;AACR;AAAA,QACF;AACA,cAAM,UAAU,MAAM,QAAQ,MAAM;AACpC,gBAAQ;AACR,cAAM;AACN,cAAM,kBAAmB,UAAiD;AAC1E,gBAAQ,kBAAkB,YAAY;AACtC,YAAI,CAAC,iBAAiB;AACpB,gBAAM,IAAI,MAAM,2DAA2D;AAAA,QAC7E;AAAA,MACF,SAAS,OAAO;AACd,cAAM,cAAc;AACpB,YAAI,gBAAgB,cAAc,gBAAgB,UAAW,SAAQ;AACrE,cAAM;AAAA,MACR;AAAA,IACF,GAAG;AACH,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,CAAC,UAAU,eAAwB;AAC/C,QAAI,UAAU,cAAc,UAAU,aAAa,UAAU,SAAU,QAAO;AAC9E,YAAQ;AACR,UAAM,QAAQ,MAAM;AACpB,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,MAAqB;AACjC,QAAI,aAAc,QAAO;AACzB,oBAAgB,YAAY;AAC1B,YAAM,OAAO;AACb,UAAI,WAAY,OAAM,WAAW,MAAM,MAAM,MAAS;AACtD,YAAM,MAAM,QAAQ,KAAK;AACzB,UAAI,UAAU,SAAU,SAAQ;AAAA,IAClC,GAAG;AACH,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,OAAO,YAAwC;AAC3D,UAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,QAAI,QAAQ,WAAW,OAAO;AAC5B,aAAO,SAAS,KAAK,EAAE,OAAO,qBAAqB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACvE;AACA,QAAI,IAAI,aAAa,YAAY;AAC/B,YAAM,KAAK,UAAU,YAAY,UAAU;AAC3C,aAAO,SAAS;AAAA,QACd;AAAA,UACE,SAAS,MAAM;AAAA,UACf,WAAW;AAAA,UACX,aAAa,MAAM;AAAA,UACnB,GAAI,MAAM,qBAAqB,EAAE,oBAAoB,MAAM,mBAAmB,IAAI,CAAC;AAAA,UACnF;AAAA,UACA;AAAA,QACF;AAAA,QACA,EAAE,QAAQ,KAAK,MAAM,IAAI;AAAA,MAC3B;AAAA,IACF;AACA,QAAI,IAAI,aAAa,WAAW;AAC9B,UAAI,UAAU,SAAS;AACrB,eAAO,SAAS;AAAA,UACd;AAAA,YACE,IAAI;AAAA,YACJ;AAAA,YACA,QAAQ,EAAE,cAAc,EAAE,IAAI,MAAM,GAAG,MAAM,EAAE,IAAI,MAAM,EAAE;AAAA,UAC7D;AAAA,UACA,EAAE,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AACA,UAAI;AACF,cAAM,MAAM;AACZ,eAAO,SAAS,KAAK;AAAA,UACnB,IAAI;AAAA,UACJ;AAAA,UACA,QAAQ,EAAE,cAAc,EAAE,IAAI,KAAK,GAAG,MAAM,EAAE,IAAI,KAAK,EAAE;AAAA,QAC3D,CAAC;AAAA,MACH,QAAQ;AACN,eAAO,SAAS;AAAA,UACd;AAAA,YACE,IAAI;AAAA,YACJ;AAAA,YACA,QAAQ,EAAE,cAAc,EAAE,IAAI,MAAM,GAAG,MAAM,EAAE,IAAI,MAAM,EAAE;AAAA,UAC7D;AAAA,UACA,EAAE,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AACA,QAAI,IAAI,aAAa,YAAY;AAC/B,aAAO,IAAI,SAAS,MAAM,MAAM,cAAc,kBAAkB,GAAG;AAAA,QACjE,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,2CAA2C;AAAA,MACxE,CAAC;AAAA,IACH;AACA,WAAO,SAAS,KAAK,EAAE,OAAO,YAAY,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC9D;AAEA,SAAO,OAAO,OAAO;AAAA,IACnB,OAAO,MAAM;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,YAAY,MAAM,MAAM,QAAQ,WAAW,aAAa;AAAA,IACtE;AAAA,EACF,CAAC;AACH;AAkBO,SAAS,6CACd,cAAiC,QAAQ,KACQ;AACjD,MAAI,YAAY,qCAAqC,OAAQ,QAAO;AACpE,QAAM,uBAAuB,SAAS,aAAa,wCAAwC;AAC3F,MAAI,yBAAyB,mDAAmD;AAC9E,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACrE;AACA,QAAM,SAAS;AAAA,IACb,aAAa,SAAS,aAAa,yCAAyC;AAAA,IAC5E;AAAA,IACA,OACE,YAAY,gCAAgC,KAAK,KACjD,mBAAmB,QAAQ,GAAG,IAAI,OAAO,WAAW,CAAC;AAAA,IACvD,UAAU,QAAQ,aAAa,sCAAsC,MAAM,GAAG,KAAM;AAAA,IACpF,kBAAkB,QAAQ,aAAa,yCAAyC,GAAG,GAAG,CAAC;AAAA,IACvF,WAAW,QAAQ,aAAa,uCAAuC,IAAI,GAAG,GAAK;AAAA,IACnF,aAAa,QAAQ,aAAa,wCAAwC,GAAG,GAAG,GAAG;AAAA,IACnF,iBAAiB;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,sBAAsB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,gBAAgB,QAAQ,aAAa,oCAAoC,KAAK,IAAI,GAAM;AAAA,IACxF,kBAAkB;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,aAAa,QAAQ,aAAa,0CAA0C,KAAK,IAAI,GAAM;AAAA,IAC3F,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,OAAO,wBAAwB,OAAO,iBAAiB;AACzD,UAAM,IAAI,MAAM,oEAAoE;AAAA,EACtF;AACA,MAAI,OAAO,cAAc,OAAO,YAAY;AAC1C,UAAM,IAAI,MAAM,kEAAkE;AAAA,EACpF;AACA,SAAO,OAAO,OAAO,MAAM;AAC7B;AAEA,eAAsB,mCACpB,cAAiC,QAAQ,KAC+C;AACxF,QAAM,UAAU,6CAA6C,WAAW;AACxE,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,WAAW,YAAY;AAC7B,QAAM,mBAAmB,4BAA4B,QAAQ;AAC7D,QAAM,WAAyC,mBAC3C;AAAA,IACE,MAAM;AAAA,IACN,MAAM,iBAAiB;AAAA,IACvB,MAAM,iBAAiB;AAAA,EACzB,IACA,EAAE,MAAM,YAAY;AACxB,QAAM,UAAU,MAAM,8CAA8C;AAAA,IAClE;AAAA,IACA,aAAa,QAAQ;AAAA,IACrB,sBAAsB,QAAQ;AAAA,IAC9B,SAAS,SAAS;AAAA,IAClB;AAAA,IACA,OAAO,QAAQ;AAAA,IACf,kBAAkB,QAAQ;AAAA,IAC1B,WAAW,QAAQ;AAAA,IACnB,aAAa,QAAQ;AAAA,IACrB,iBAAiB,QAAQ;AAAA,IACzB,sBAAsB,QAAQ;AAAA,IAC9B,gBAAgB,QAAQ;AAAA,IACxB,kBAAkB,QAAQ;AAAA,IAC1B,aAAa,QAAQ;AAAA,IACrB,YAAY,QAAQ;AAAA,EACtB,CAAC;AACD,SAAO,OAAO,OAAO,EAAE,SAAS,UAAU,QAAQ,SAAS,CAAC;AAC9D;AAEA,eAAe,YACb,SACA,cACA,OACY;AACZ,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,QAAQ,KAAK;AAAA,MACxB;AAAA,MACA,IAAI,QAAe,CAAC,UAAU,WAAW;AACvC,gBAAQ,WAAW,MAAM;AACvB,gBAAM,MAAM;AACZ,iBAAO,IAAI,MAAM,2BAA2B,CAAC;AAAA,QAC/C,GAAG,YAAY;AAAA,MACjB,CAAC;AAAA,IACH,CAAC;AAAA,EACH,UAAE;AACA,QAAI,MAAO,cAAa,KAAK;AAAA,EAC/B;AACF;AAEA,SAAS,SAAS,aAAgC,MAAsB;AACtE,QAAM,QAAQ,YAAY,IAAI,GAAG,KAAK;AACtC,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,GAAG,IAAI,uDAAuD;AAC1F,SAAO;AACT;AAEA,SAAS,QACP,aACA,MACA,UACA,SACA,SACQ;AACR,QAAM,MAAM,YAAY,IAAI;AAC5B,QAAM,QAAQ,QAAQ,SAAY,WAAW,OAAO,GAAG;AACvD,MAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,WAAW,QAAQ,SAAS;AACtE,UAAM,IAAI,MAAM,GAAG,IAAI,+BAA+B;AAAA,EACxD;AACA,SAAO;AACT;;;AG5aA,eAAsB,iCACpB,cAAiC,QAAQ,KAC1B;AACf,QAAM,aAAa,MAAM,mCAAmC,WAAW;AACvE,MAAI,CAAC,WAAY,OAAM,IAAI,MAAM,8CAA8C;AAC/E,QAAM,SAAS,IAAI,MAAM;AAAA,IACvB,UAAU;AAAA,IACV,MAAM,WAAW;AAAA,IACjB,OAAO,WAAW,QAAQ;AAAA,EAC5B,CAAC;AACD,QAAM,OAAO,MAAM,WAAW,QAAQ,MAAM,gBAAgB;AAC5D,UAAQ,GAAG,WAAW,IAAI;AAC1B,UAAQ,GAAG,UAAU,IAAI;AACzB,MAAI;AACF,UAAM,WAAW,QAAQ,IAAI;AAAA,EAC/B,UAAE;AACA,YAAQ,IAAI,WAAW,IAAI;AAC3B,YAAQ,IAAI,UAAU,IAAI;AAC1B,WAAO,KAAK,IAAI;AAChB,UAAM,WAAW,QAAQ,MAAM;AAAA,EACjC;AACF;AAEA,IAAI,YAAY,MAAM;AACpB,QAAM,iCAAiC;AACzC;","names":[]}
1
+ {"version":3,"sources":["../src/editable-artifact-outbox-service.ts","../src/editable-artifact-outbox-dispatcher.ts","../src/editable-artifact-hint-broker.ts","../src/artifact-outbox-entry.ts"],"sourcesContent":["import {\n dbSearchPath,\n getArtifactOutboxSettings,\n resolveNatsControlPlaneAuth,\n type ArtifactOutboxSettings,\n} from \"@opengeni/config\";\nimport type { EditableArtifactOutboxDispatchSummary } from \"@opengeni/core\";\nimport { createObservability, type Observability } from \"@opengeni/observability\";\n\nimport {\n EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV,\n EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE,\n createEditableArtifactOutboxWorker,\n type EditableArtifactOutboxWorkerRuntime,\n} from \"./editable-artifact-outbox-dispatcher\";\nimport type { EditableArtifactHintNatsAuth } from \"./editable-artifact-hint-broker\";\n\nexport type EditableArtifactOutboxServiceState =\n | \"starting\"\n | \"ready\"\n | \"draining\"\n | \"stopped\"\n | \"failed\";\n\nexport interface EditableArtifactOutboxRuntimePort {\n start(): Promise<void>;\n drain(): boolean;\n stop(): Promise<void>;\n check(signal?: AbortSignal): Promise<void>;\n readonly dispatcher: Readonly<{\n dispatchOnce(): Promise<EditableArtifactOutboxDispatchSummary>;\n }>;\n}\n\nexport type EditableArtifactOutboxService = Readonly<{\n state(): EditableArtifactOutboxServiceState;\n run(): Promise<void>;\n drain(reason?: string): boolean;\n close(): Promise<void>;\n dispatchOnce(): Promise<EditableArtifactOutboxDispatchSummary>;\n fetch(request: Request): Promise<Response>;\n}>;\n\nexport type CreateEditableArtifactOutboxServiceInput = Readonly<{\n runtime: EditableArtifactOutboxRuntimePort;\n observability: Observability;\n serviceName: string;\n environment: string;\n deploymentRevision?: string;\n readinessTimeoutMs?: number;\n}>;\n\nexport type ProductionEditableArtifactOutboxServiceOptions = Readonly<{\n settings: ArtifactOutboxSettings;\n databaseUrl: string;\n declaredDatabaseRole: string;\n natsUrl: string;\n natsAuth: EditableArtifactHintNatsAuth;\n owner: string;\n databasePoolSize?: number;\n batchSize?: number;\n concurrency?: number;\n leaseDurationMs?: number;\n leaseRenewIntervalMs?: number;\n pollIntervalMs?: number;\n publishTimeoutMs?: number;\n retryBaseMs?: number;\n retryMaxMs?: number;\n}>;\n\n/** Compose the independently supervised production outbox dispatcher. */\nexport async function createProductionEditableArtifactOutboxService(\n options: ProductionEditableArtifactOutboxServiceOptions,\n): Promise<EditableArtifactOutboxService> {\n if (options.declaredDatabaseRole !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE) {\n throw new Error(\"Artifact outbox dispatcher database role declaration is invalid\");\n }\n const observability = createObservability(options.settings, {\n component: \"artifact-outbox-dispatcher\",\n });\n const databaseSearchPath = dbSearchPath(options.settings);\n const runtime = await createEditableArtifactOutboxWorker({\n dispatcherDatabaseUrl: options.databaseUrl,\n ...(databaseSearchPath ? { databaseSearchPath } : {}),\n ...(options.databasePoolSize === undefined\n ? {}\n : { databasePoolSize: options.databasePoolSize }),\n natsUrl: options.natsUrl,\n natsAuth: options.natsAuth,\n owner: options.owner,\n dispatcher: {\n ...(options.batchSize === undefined ? {} : { batchSize: options.batchSize }),\n ...(options.concurrency === undefined ? {} : { concurrency: options.concurrency }),\n ...(options.leaseDurationMs === undefined\n ? {}\n : { leaseDurationMs: options.leaseDurationMs }),\n ...(options.leaseRenewIntervalMs === undefined\n ? {}\n : { leaseRenewIntervalMs: options.leaseRenewIntervalMs }),\n ...(options.pollIntervalMs === undefined ? {} : { pollIntervalMs: options.pollIntervalMs }),\n ...(options.publishTimeoutMs === undefined\n ? {}\n : { publishTimeoutMs: options.publishTimeoutMs }),\n ...(options.retryBaseMs === undefined ? {} : { retryBaseMs: options.retryBaseMs }),\n ...(options.retryMaxMs === undefined ? {} : { retryMaxMs: options.retryMaxMs }),\n },\n metrics: {\n increment(outcome, count = 1) {\n observability.incrementCounter({\n name: \"opengeni_artifact_outbox_dispatch_total\",\n help: \"Editable artifact outbox dispatch actions by closed outcome.\",\n labels: { outcome },\n amount: count,\n });\n },\n observePublishSeconds(outcome, seconds) {\n observability.observeHistogram({\n name: \"opengeni_artifact_outbox_publish_seconds\",\n help: \"Editable artifact broker publication latency by closed outcome.\",\n labels: { outcome },\n value: seconds,\n });\n },\n },\n logger: {\n warn(message, attributes) {\n observability.warn(message, {\n errorClass: \"WorkerOperationError\",\n errorCode: \"worker_operation_failed\",\n origin: \"worker\",\n outcome: typeof attributes.code === \"string\" ? attributes.code : \"unknown\",\n });\n },\n },\n });\n return createEditableArtifactOutboxService({\n runtime,\n observability,\n serviceName: options.settings.serviceName,\n environment: options.settings.environment,\n deploymentRevision: options.settings.deploymentRevision,\n });\n}\n\nexport function createEditableArtifactOutboxService(\n input: CreateEditableArtifactOutboxServiceInput,\n): EditableArtifactOutboxService {\n let state: EditableArtifactOutboxServiceState = \"starting\";\n let runPromise: Promise<void> | null = null;\n let closePromise: Promise<void> | null = null;\n let readinessPromise: Promise<void> | null = null;\n const readinessTimeoutMs = input.readinessTimeoutMs ?? 2_000;\n\n const ready = (): Promise<void> => {\n if (readinessPromise) return readinessPromise;\n const abort = new AbortController();\n const check = withTimeout(input.runtime.check(abort.signal), readinessTimeoutMs, abort);\n readinessPromise = check;\n void check.then(\n () => {\n if (readinessPromise === check) readinessPromise = null;\n },\n () => {\n if (readinessPromise === check) readinessPromise = null;\n },\n );\n return check;\n };\n\n const run = (): Promise<void> => {\n if (runPromise) return runPromise;\n if (state !== \"starting\") {\n return Promise.reject(new Error(\"Artifact outbox dispatcher service cannot be restarted\"));\n }\n runPromise = (async () => {\n try {\n await ready();\n if ((state as EditableArtifactOutboxServiceState) === \"draining\") {\n state = \"stopped\";\n return;\n }\n const running = input.runtime.start();\n state = \"ready\";\n await running;\n const exitWasDraining = (state as EditableArtifactOutboxServiceState) === \"draining\";\n state = exitWasDraining ? \"stopped\" : \"failed\";\n if (!exitWasDraining) {\n throw new Error(\"Artifact outbox dispatcher exited without a drain request\");\n }\n } catch (error) {\n const caughtState = state as EditableArtifactOutboxServiceState;\n if (caughtState !== \"draining\" && caughtState !== \"stopped\") state = \"failed\";\n throw error;\n }\n })();\n return runPromise;\n };\n\n const drain = (_reason = \"shutdown\"): boolean => {\n if (state === \"draining\" || state === \"stopped\" || state === \"failed\") return false;\n state = \"draining\";\n input.runtime.drain();\n return true;\n };\n\n const close = (): Promise<void> => {\n if (closePromise) return closePromise;\n closePromise = (async () => {\n drain(\"close\");\n if (runPromise) await runPromise.catch(() => undefined);\n await input.runtime.stop();\n if (state !== \"failed\") state = \"stopped\";\n })();\n return closePromise;\n };\n\n const fetch = async (request: Request): Promise<Response> => {\n const url = new URL(request.url);\n if (request.method !== \"GET\") {\n return Response.json({ error: \"method_not_allowed\" }, { status: 405 });\n }\n if (url.pathname === \"/healthz\") {\n const ok = state !== \"failed\" && state !== \"stopped\";\n return Response.json(\n {\n service: input.serviceName,\n component: \"artifact-outbox-dispatcher\",\n environment: input.environment,\n ...(input.deploymentRevision ? { deploymentRevision: input.deploymentRevision } : {}),\n state,\n ok,\n },\n { status: ok ? 200 : 503 },\n );\n }\n if (url.pathname === \"/readyz\") {\n if (state !== \"ready\") {\n return Response.json(\n {\n ok: false,\n state,\n checks: { databaseRole: { ok: false }, nats: { ok: false } },\n },\n { status: 503 },\n );\n }\n try {\n await ready();\n return Response.json({\n ok: true,\n state,\n checks: { databaseRole: { ok: true }, nats: { ok: true } },\n });\n } catch {\n return Response.json(\n {\n ok: false,\n state,\n checks: { databaseRole: { ok: false }, nats: { ok: false } },\n },\n { status: 503 },\n );\n }\n }\n if (url.pathname === \"/metrics\") {\n return new Response(await input.observability.prometheusMetrics(), {\n status: 200,\n headers: { \"content-type\": \"text/plain; version=0.0.4; charset=utf-8\" },\n });\n }\n return Response.json({ error: \"not_found\" }, { status: 404 });\n };\n\n return Object.freeze({\n state: () => state,\n run,\n drain,\n close,\n dispatchOnce: async () => await input.runtime.dispatcher.dispatchOnce(),\n fetch,\n });\n}\n\nexport type EditableArtifactOutboxSidecarEnvironment = Readonly<{\n databaseUrl: string;\n declaredDatabaseRole: string;\n owner: string;\n httpPort: number;\n databasePoolSize: number;\n batchSize: number;\n concurrency: number;\n leaseDurationMs: number;\n leaseRenewIntervalMs: number;\n pollIntervalMs: number;\n publishTimeoutMs: number;\n retryBaseMs: number;\n retryMaxMs: number;\n}>;\n\nexport function readEditableArtifactOutboxSidecarEnvironment(\n environment: NodeJS.ProcessEnv = process.env,\n): EditableArtifactOutboxSidecarEnvironment | null {\n if (environment.OPENGENI_ARTIFACT_OUTBOX_ENABLED !== \"true\") return null;\n const declaredDatabaseRole = required(environment, \"OPENGENI_ARTIFACT_OUTBOX_DATABASE_ROLE\");\n if (declaredDatabaseRole !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_DATABASE_ROLE is invalid\");\n }\n const result = {\n databaseUrl: required(environment, EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV),\n declaredDatabaseRole,\n owner:\n environment.OPENGENI_ARTIFACT_OUTBOX_OWNER?.trim() ||\n `artifact-outbox-${process.pid}-${crypto.randomUUID()}`,\n httpPort: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_HTTP_PORT\", 9466, 1, 65_535),\n databasePoolSize: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_DB_POOL_SIZE\", 4, 1, 8),\n batchSize: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_BATCH_SIZE\", 32, 1, 1_000),\n concurrency: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_CONCURRENCY\", 8, 1, 128),\n leaseDurationMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_LEASE_MS\",\n 30_000,\n 1_000,\n 86_400_000,\n ),\n leaseRenewIntervalMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_RENEW_MS\",\n 10_000,\n 100,\n 43_199_999,\n ),\n pollIntervalMs: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_POLL_MS\", 500, 10, 60_000),\n publishTimeoutMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_PUBLISH_TIMEOUT_MS\",\n 5_000,\n 100,\n 60_000,\n ),\n retryBaseMs: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_RETRY_BASE_MS\", 500, 10, 60_000),\n retryMaxMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_RETRY_MAX_MS\",\n 60_000,\n 10,\n 86_400_000,\n ),\n } as const;\n if (result.leaseRenewIntervalMs >= result.leaseDurationMs) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_RENEW_MS must be less than lease duration\");\n }\n if (result.retryBaseMs > result.retryMaxMs) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_RETRY_BASE_MS must not exceed retry max\");\n }\n return Object.freeze(result);\n}\n\nexport async function createOutboxSidecarFromEnvironment(\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<Readonly<{ service: EditableArtifactOutboxService; httpPort: number }> | null> {\n const sidecar = readEditableArtifactOutboxSidecarEnvironment(environment);\n if (!sidecar) return null;\n const settings = getArtifactOutboxSettings(environment);\n const controlPlaneAuth = resolveNatsControlPlaneAuth(settings);\n const natsAuth: EditableArtifactHintNatsAuth = controlPlaneAuth\n ? {\n kind: \"user-password\",\n user: controlPlaneAuth.user,\n pass: controlPlaneAuth.password,\n }\n : { kind: \"anonymous\" };\n const service = await createProductionEditableArtifactOutboxService({\n settings,\n databaseUrl: sidecar.databaseUrl,\n declaredDatabaseRole: sidecar.declaredDatabaseRole,\n natsUrl: settings.natsUrl,\n natsAuth,\n owner: sidecar.owner,\n databasePoolSize: sidecar.databasePoolSize,\n batchSize: sidecar.batchSize,\n concurrency: sidecar.concurrency,\n leaseDurationMs: sidecar.leaseDurationMs,\n leaseRenewIntervalMs: sidecar.leaseRenewIntervalMs,\n pollIntervalMs: sidecar.pollIntervalMs,\n publishTimeoutMs: sidecar.publishTimeoutMs,\n retryBaseMs: sidecar.retryBaseMs,\n retryMaxMs: sidecar.retryMaxMs,\n });\n return Object.freeze({ service, httpPort: sidecar.httpPort });\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n milliseconds: number,\n abort: AbortController,\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n abort.abort();\n reject(new Error(\"readiness check timed out\"));\n }, milliseconds);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\nfunction required(environment: NodeJS.ProcessEnv, name: string): string {\n const value = environment[name]?.trim();\n if (!value) throw new Error(`${name} is required when artifact outbox dispatch is enabled`);\n return value;\n}\n\nfunction integer(\n environment: NodeJS.ProcessEnv,\n name: string,\n fallback: number,\n minimum: number,\n maximum: number,\n): number {\n const raw = environment[name];\n const value = raw === undefined ? fallback : Number(raw);\n if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {\n throw new Error(`${name} is outside its allowed range`);\n }\n return value;\n}\n\n// Compile-time assurance that production composition satisfies the service port.\nconst _runtimePort: EditableArtifactOutboxRuntimePort | undefined = undefined as\n | EditableArtifactOutboxWorkerRuntime\n | undefined;\nvoid _runtimePort;\n","import {\n EditableArtifactLiveOutboxDispatcher,\n MathEditableArtifactOutboxRandom,\n SystemEditableArtifactLiveClock,\n SystemEditableArtifactLiveScheduler,\n type EditableArtifactOutboxDispatcherOptions,\n type EditableArtifactOutboxLoggerPort,\n type EditableArtifactOutboxMetricsPort,\n type EditableArtifactOutboxDispatcherStorePort,\n type EditableArtifactLiveOutboxRecord,\n} from \"@opengeni/core\";\nimport {\n PostgresEditableArtifactStore,\n createDb,\n dbSql,\n type Database,\n type DbClient,\n} from \"@opengeni/db\";\n\nimport {\n connectEditableArtifactHintBroker,\n type ConfirmedNatsEditableArtifactHintBroker,\n type EditableArtifactHintNatsAuth,\n} from \"./editable-artifact-hint-broker\";\n\nexport const EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE =\n \"opengeni_artifact_outbox_dispatcher\";\nexport const EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV = \"OPENGENI_ARTIFACT_OUTBOX_DATABASE_URL\";\n\nexport type EditableArtifactOutboxWorkerOptions = Readonly<{\n /** Must authenticate as the dedicated dispatcher role, never the generic app role. */\n dispatcherDatabaseUrl: string;\n databaseSearchPath?: string;\n databasePoolSize?: number;\n natsUrl: string;\n natsAuth: EditableArtifactHintNatsAuth;\n owner?: string;\n dispatcher?: Omit<EditableArtifactOutboxDispatcherOptions, \"owner\">;\n metrics?: EditableArtifactOutboxMetricsPort;\n logger?: EditableArtifactOutboxLoggerPort;\n}>;\n\n/** Explicit lifecycle handle; hosts supervise `start()` and await `stop()` on drain. */\nexport class EditableArtifactOutboxWorkerRuntime {\n private readonly abort = new AbortController();\n private running: Promise<void> | null = null;\n private closing: Promise<void> | null = null;\n\n constructor(\n readonly dispatcher: EditableArtifactLiveOutboxDispatcher,\n private readonly broker: ConfirmedNatsEditableArtifactHintBroker,\n private readonly database: DbClient,\n ) {}\n\n start(): Promise<void> {\n if (this.closing) return Promise.reject(new Error(\"Artifact outbox worker is stopping\"));\n this.running ??= this.dispatcher.run(this.abort.signal);\n return this.running;\n }\n\n drain(): boolean {\n if (this.abort.signal.aborted) return false;\n this.abort.abort();\n return true;\n }\n\n async check(signal?: AbortSignal): Promise<void> {\n if (this.abort.signal.aborted || this.closing) {\n throw new Error(\"Artifact outbox worker is stopping\");\n }\n await Promise.all([\n assertDedicatedOutboxDispatcherDatabaseRole(this.database.db),\n this.broker.check(signal),\n ]);\n }\n\n stop(): Promise<void> {\n if (this.closing) return this.closing;\n this.closing = this.stopOnce();\n return this.closing;\n }\n\n private async stopOnce(): Promise<void> {\n this.drain();\n const running = this.running ? await Promise.allSettled([this.running]) : [];\n const cleanup = await Promise.allSettled([this.broker.close(), this.database.close()]);\n const failure = [...running, ...cleanup].find(\n (result): result is PromiseRejectedResult => result.status === \"rejected\",\n );\n if (failure) throw failure.reason;\n }\n}\n\n/**\n * Production composition. DB grants make the role a narrow capability: it can\n * execute only lease-fenced dispatcher functions and cannot read artifact rows.\n */\nexport async function createEditableArtifactOutboxWorker(\n options: EditableArtifactOutboxWorkerOptions,\n): Promise<EditableArtifactOutboxWorkerRuntime> {\n const dispatcherDatabaseUrl = dedicatedDispatcherDatabaseUrl(options.dispatcherDatabaseUrl);\n const databasePoolSize = options.databasePoolSize ?? 2;\n if (!Number.isSafeInteger(databasePoolSize) || databasePoolSize < 1 || databasePoolSize > 8) {\n throw new TypeError(\"Artifact outbox dispatcher DB pool size must be 1-8\");\n }\n const database = createDb(dispatcherDatabaseUrl, {\n max: databasePoolSize,\n ...(options.databaseSearchPath ? { searchPath: options.databaseSearchPath } : {}),\n });\n let broker: ConfirmedNatsEditableArtifactHintBroker;\n try {\n await assertDedicatedOutboxDispatcherDatabaseRole(database.db);\n broker = await connectEditableArtifactHintBroker({\n natsUrl: options.natsUrl,\n auth: options.natsAuth,\n });\n } catch (error) {\n await database.close();\n throw error;\n }\n const persistence = new PostgresEditableArtifactStore(database.db);\n const store = dispatcherStore(persistence);\n const dispatcher = new EditableArtifactLiveOutboxDispatcher(\n {\n store,\n broker,\n clock: new SystemEditableArtifactLiveClock(),\n scheduler: new SystemEditableArtifactLiveScheduler(),\n random: new MathEditableArtifactOutboxRandom(),\n ...(options.metrics ? { metrics: options.metrics } : {}),\n ...(options.logger ? { logger: options.logger } : {}),\n },\n {\n owner: options.owner ?? `artifact-outbox:${crypto.randomUUID()}`,\n ...options.dispatcher,\n },\n );\n return new EditableArtifactOutboxWorkerRuntime(dispatcher, broker, database);\n}\n\n/**\n * Verify the database identity and its negative capability at runtime. A DSN\n * username check alone is insufficient because PostgreSQL role inheritance,\n * SET ROLE, or a mis-provisioned grant could otherwise widen this worker.\n */\nexport async function assertDedicatedOutboxDispatcherDatabaseRole(db: Database): Promise<void> {\n const raw = await db.execute<{\n current_role: string;\n session_role: string;\n can_access_any_relation: boolean;\n can_access_any_sequence: boolean;\n }>(dbSql`\n select\n current_user::text as current_role,\n session_user::text as session_role,\n exists (\n select 1\n from pg_catalog.pg_class relation_row\n join pg_catalog.pg_namespace namespace_row\n on namespace_row.oid = relation_row.relnamespace\n where namespace_row.nspname = current_schema()\n and relation_row.relkind in ('r', 'p', 'v', 'm', 'f')\n and (\n has_table_privilege(current_user, relation_row.oid, 'SELECT')\n or has_table_privilege(current_user, relation_row.oid, 'INSERT')\n or has_table_privilege(current_user, relation_row.oid, 'UPDATE')\n or has_table_privilege(current_user, relation_row.oid, 'DELETE')\n or has_table_privilege(current_user, relation_row.oid, 'TRUNCATE')\n or has_table_privilege(current_user, relation_row.oid, 'REFERENCES')\n or has_table_privilege(current_user, relation_row.oid, 'TRIGGER')\n or has_any_column_privilege(current_user, relation_row.oid, 'SELECT')\n or has_any_column_privilege(current_user, relation_row.oid, 'INSERT')\n or has_any_column_privilege(current_user, relation_row.oid, 'UPDATE')\n or has_any_column_privilege(current_user, relation_row.oid, 'REFERENCES')\n )\n ) as can_access_any_relation,\n exists (\n select 1\n from pg_catalog.pg_class sequence_row\n join pg_catalog.pg_namespace namespace_row\n on namespace_row.oid = sequence_row.relnamespace\n where namespace_row.nspname = current_schema()\n and sequence_row.relkind = 'S'\n and (\n has_sequence_privilege(current_user, sequence_row.oid, 'USAGE')\n or has_sequence_privilege(current_user, sequence_row.oid, 'SELECT')\n or has_sequence_privilege(current_user, sequence_row.oid, 'UPDATE')\n )\n ) as can_access_any_sequence\n `);\n const rows = Array.isArray(raw) ? raw : ((raw as unknown as { rows?: unknown[] }).rows ?? []);\n const row = rows[0] as\n | {\n current_role?: unknown;\n session_role?: unknown;\n can_access_any_relation?: unknown;\n can_access_any_sequence?: unknown;\n }\n | undefined;\n if (\n row?.current_role !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE ||\n row.session_role !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE ||\n row.can_access_any_relation !== false ||\n row.can_access_any_sequence !== false\n ) {\n throw new Error(\"Artifact outbox dispatcher database connection has an unsafe role posture\");\n }\n}\n\nfunction dispatcherStore(\n persistence: PostgresEditableArtifactStore,\n): EditableArtifactOutboxDispatcherStorePort {\n return {\n claimLiveOutbox: async (input) =>\n (await persistence.claimLiveOutbox(\n input,\n )) as unknown as readonly EditableArtifactLiveOutboxRecord[],\n renewLiveOutbox: async (input) => await persistence.renewLiveOutbox(input),\n markLiveOutboxPublished: async (input) => await persistence.markLiveOutboxPublished(input),\n retryLiveOutbox: async (input) => await persistence.retryLiveOutbox(input),\n deadLetterLiveOutbox: async (input) => await persistence.deadLetterLiveOutbox(input),\n };\n}\n\nexport function dedicatedDispatcherDatabaseUrl(raw: string): string {\n if (typeof raw !== \"string\" || raw.length > 8_192 || raw.trim() !== raw) {\n throw new TypeError(`${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} is malformed`);\n }\n let url: URL;\n try {\n url = new URL(raw);\n } catch (cause) {\n throw new TypeError(`${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} is malformed`, { cause });\n }\n if (\n (url.protocol !== \"postgres:\" && url.protocol !== \"postgresql:\") ||\n decodeURIComponent(url.username) !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE\n ) {\n throw new TypeError(\n `${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} must authenticate as ${EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE}`,\n );\n }\n return raw;\n}\n","import {\n EDITABLE_ARTIFACT_HINT_MAX_BYTES,\n type EditableArtifactHintBrokerPort,\n} from \"@opengeni/core\";\nimport { connect, type NatsConnection } from \"@opengeni/events\";\n\nconst DEFAULT_CONNECTION_NAME = \"opengeni-editable-artifact-outbox\";\n\nexport type EditableArtifactHintNatsAuth =\n | Readonly<{ kind: \"user-password\"; user: string; pass: string }>\n | Readonly<{ kind: \"token\"; token: string }>\n | Readonly<{ kind: \"anonymous\" }>;\n\nexport type EditableArtifactHintNatsBrokerOptions = Readonly<{\n maxHintBytes?: number;\n}>;\n\nexport type EditableArtifactHintNatsConnection = Pick<\n NatsConnection,\n \"publish\" | \"flush\" | \"drain\" | \"close\" | \"closed\" | \"isClosed\" | \"isDraining\"\n>;\n\n/**\n * Core-NATS adapter for the durable outbox. A publish resolves only after a\n * server round-trip flush ACK. Reconnect buffering may create duplicates after\n * a timeout; hints are intentionally idempotent wakeups for durable gap-fill.\n */\nexport class ConfirmedNatsEditableArtifactHintBroker implements EditableArtifactHintBrokerPort {\n private readonly maxHintBytes: number;\n\n constructor(\n private readonly connection: EditableArtifactHintNatsConnection,\n options: EditableArtifactHintNatsBrokerOptions = {},\n ) {\n this.maxHintBytes = options.maxHintBytes ?? EDITABLE_ARTIFACT_HINT_MAX_BYTES;\n if (\n !Number.isSafeInteger(this.maxHintBytes) ||\n this.maxHintBytes < 1 ||\n this.maxHintBytes > EDITABLE_ARTIFACT_HINT_MAX_BYTES\n ) {\n throw new TypeError(\"Editable artifact NATS hint byte limit is invalid\");\n }\n }\n\n async publish(\n input: Readonly<{\n subject: string;\n payload: Uint8Array;\n signal: AbortSignal;\n }>,\n ): Promise<void> {\n assertSubject(input.subject);\n if (\n !(input.payload instanceof Uint8Array) ||\n input.payload.byteLength < 1 ||\n input.payload.byteLength > this.maxHintBytes\n ) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_backpressure\",\n \"Editable artifact hint exceeds the NATS envelope\",\n );\n }\n if (input.signal.aborted) throw abortedPublish();\n if (this.connection.isClosed() || this.connection.isDraining()) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS connection is closed\",\n );\n }\n try {\n this.connection.publish(input.subject, input.payload);\n await abortable(this.connection.flush(), input.signal);\n } catch (error) {\n if (input.signal.aborted) throw abortedPublish();\n if (error instanceof EditableArtifactNatsHintPublishError) throw error;\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS publish was not acknowledged\",\n { cause: error },\n );\n }\n }\n\n /**\n * A readiness probe must prove the server is reachable, not merely that the\n * client object has not observed closure yet. `flush()` is a bounded NATS\n * round trip and has the same acknowledgement semantics as publication.\n */\n async check(signal: AbortSignal = new AbortController().signal): Promise<void> {\n if (signal.aborted) throw abortedPublish();\n if (this.connection.isClosed() || this.connection.isDraining()) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS connection is unavailable\",\n );\n }\n try {\n await abortable(this.connection.flush(), signal);\n } catch (error) {\n if (error instanceof EditableArtifactNatsHintPublishError) throw error;\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS readiness round trip failed\",\n { cause: error },\n );\n }\n }\n\n async close(drainTimeoutMs = 5_000): Promise<void> {\n if (!Number.isSafeInteger(drainTimeoutMs) || drainTimeoutMs < 1 || drainTimeoutMs > 30_000) {\n throw new TypeError(\"Editable artifact NATS drain timeout is invalid\");\n }\n if (this.connection.isClosed()) return;\n if (this.connection.isDraining()) {\n await this.connection.closed();\n return;\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n const drain = this.connection.drain();\n const outcome = await Promise.race([\n drain.then(\n () => \"drained\" as const,\n () => \"failed\" as const,\n ),\n new Promise<\"timed_out\">((resolve) => {\n timer = setTimeout(() => resolve(\"timed_out\"), drainTimeoutMs);\n }),\n ]);\n if (timer) clearTimeout(timer);\n if (outcome !== \"drained\" && !this.connection.isClosed()) {\n await this.connection.close();\n }\n }\n}\n\nexport class EditableArtifactNatsHintPublishError extends Error {\n constructor(\n readonly code: \"broker_unavailable\" | \"broker_backpressure\",\n message: string,\n options?: ErrorOptions,\n ) {\n super(message, options);\n this.name = \"EditableArtifactNatsHintPublishError\";\n }\n}\n\n/** Opens one resilient dispatcher identity; callers own `broker.close()`. */\nexport async function connectEditableArtifactHintBroker(\n input: Readonly<{\n natsUrl: string;\n auth: EditableArtifactHintNatsAuth;\n name?: string;\n maxHintBytes?: number;\n }>,\n): Promise<ConfirmedNatsEditableArtifactHintBroker> {\n const natsUrl = boundedText(input.natsUrl, \"NATS URL\", 2_048);\n const name = boundedText(input.name ?? DEFAULT_CONNECTION_NAME, \"NATS connection name\", 128);\n const auth = natsAuthOptions(input.auth);\n const connection = await connect({\n servers: natsUrl,\n name,\n reconnect: true,\n maxReconnectAttempts: -1,\n reconnectTimeWait: 2_000,\n reconnectJitter: 1_000,\n reconnectJitterTLS: 1_000,\n waitOnFirstConnect: true,\n pingInterval: 20_000,\n maxPingOut: 3,\n ...auth,\n });\n return new ConfirmedNatsEditableArtifactHintBroker(connection, {\n ...(input.maxHintBytes === undefined ? {} : { maxHintBytes: input.maxHintBytes }),\n });\n}\n\nfunction natsAuthOptions(auth: EditableArtifactHintNatsAuth): {\n user?: string;\n pass?: string;\n token?: string;\n} {\n if (auth.kind === \"anonymous\") return {};\n if (auth.kind === \"token\") return { token: boundedText(auth.token, \"NATS token\", 4_096) };\n return {\n user: boundedText(auth.user, \"NATS user\", 256),\n pass: boundedText(auth.pass, \"NATS password\", 4_096),\n };\n}\n\nfunction assertSubject(subject: string): void {\n const bytes = new TextEncoder().encode(subject).byteLength;\n if (\n bytes < 1 ||\n bytes > 1_024 ||\n subject.startsWith(\".\") ||\n subject.endsWith(\".\") ||\n subject.includes(\"..\") ||\n /[\\s*>]/u.test(subject)\n ) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_backpressure\",\n \"Editable artifact NATS subject is malformed\",\n );\n }\n}\n\nfunction boundedText(value: string, label: string, maxBytes: number): string {\n const bytes = new TextEncoder().encode(value).byteLength;\n if (bytes < 1 || bytes > maxBytes || value.trim() !== value) {\n throw new TypeError(`${label} is malformed`);\n }\n return value;\n}\n\nfunction abortedPublish(): EditableArtifactNatsHintPublishError {\n return new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS publish was aborted\",\n );\n}\n\nasync function abortable(operation: Promise<void>, signal: AbortSignal): Promise<void> {\n if (signal.aborted) throw abortedPublish();\n let remove: () => void = () => undefined;\n const aborted = new Promise<never>((_resolve, reject) => {\n const onAbort = () => reject(abortedPublish());\n signal.addEventListener(\"abort\", onAbort, { once: true });\n remove = () => signal.removeEventListener(\"abort\", onAbort);\n });\n try {\n await Promise.race([operation, aborted]);\n } finally {\n remove();\n }\n}\n","import { createOutboxSidecarFromEnvironment } from \"./editable-artifact-outbox-service\";\n\n/** Dedicated process: no Temporal/control worker is created or imported here. */\nexport async function runEditableArtifactOutboxSidecar(\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<void> {\n const configured = await createOutboxSidecarFromEnvironment(environment);\n if (!configured) throw new Error(\"Editable artifact outbox sidecar is disabled\");\n const server = Bun.serve({\n hostname: \"0.0.0.0\",\n port: configured.httpPort,\n fetch: configured.service.fetch,\n });\n const stop = () => configured.service.drain(\"process signal\");\n process.on(\"SIGTERM\", stop);\n process.on(\"SIGINT\", stop);\n try {\n await configured.service.run();\n } finally {\n process.off(\"SIGTERM\", stop);\n process.off(\"SIGINT\", stop);\n server.stop(true);\n await configured.service.close();\n }\n}\n\nif (import.meta.main) {\n await runEditableArtifactOutboxSidecar();\n}\n"],"mappings":"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","names":[]}
@@ -272,6 +272,10 @@ function eventAttributeValue(value) {
272
272
  function runtimeMetricsHooksForObservability(observability) {
273
273
  return {
274
274
  onModelCall: ({ provider, outcome, durationSeconds }) => {
275
+ completedOperationSpan(observability, "worker.model.call", durationSeconds, {
276
+ provider,
277
+ outcome
278
+ });
275
279
  observability.incrementCounter({
276
280
  name: "opengeni_model_calls_total",
277
281
  help: "Total model calls by provider and outcome.",
@@ -325,6 +329,20 @@ function runtimeMetricsHooksForObservability(observability) {
325
329
  labels: { outcome, port: String(port) }
326
330
  });
327
331
  },
332
+ onWorkspaceCapture: ({ backend, outcome, durationSeconds }) => {
333
+ if (!Number.isFinite(durationSeconds) || durationSeconds < 0) return;
334
+ const safeBackend = SandboxBackend.safeParse(backend).success ? backend : "unknown";
335
+ completedOperationSpan(observability, "worker.workspace_capture", durationSeconds, {
336
+ backend: safeBackend,
337
+ outcome
338
+ });
339
+ observability.observeHistogram({
340
+ name: "opengeni_workspace_capture_duration_seconds",
341
+ help: "Physical warm workspace capture and publication duration, including late settlement after caller timeout.",
342
+ labels: { backend: safeBackend, outcome },
343
+ value: durationSeconds
344
+ });
345
+ },
328
346
  onWorkspaceArchiveObject: ({ outcome, backend }) => {
329
347
  observability.incrementCounter({
330
348
  name: "opengeni_workspace_archive_object_total",
@@ -333,6 +351,7 @@ function runtimeMetricsHooksForObservability(observability) {
333
351
  });
334
352
  },
335
353
  onMcpToolCall: ({ outcome, durationSeconds }) => {
354
+ completedOperationSpan(observability, "worker.mcp.tool_call", durationSeconds, { outcome });
336
355
  observability.incrementCounter({
337
356
  name: "opengeni_mcp_tool_calls_total",
338
357
  help: "Total physical MCP tool calls by bounded structural outcome.",
@@ -1241,6 +1260,12 @@ function turnStartupCountBucket(count) {
1241
1260
  return "21+";
1242
1261
  }
1243
1262
  function recordTurnStartupPhase(observability, input) {
1263
+ completedOperationSpan(observability, `worker.prepare.${input.phase}`, input.durationSeconds, {
1264
+ provider: input.provider,
1265
+ backend: input.backend,
1266
+ outcome: input.outcome,
1267
+ ...input.phase === "claim_and_policy" && /^turn_[0-9a-f]{32}$/.test(input.executionCorrelationId ?? "") ? { correlationId: input.executionCorrelationId } : {}
1268
+ });
1244
1269
  observability.observeHistogram({
1245
1270
  name: "opengeni_turn_startup_phase_duration_seconds",
1246
1271
  help: "Turn startup phase duration before the model response stream begins.",
@@ -1256,6 +1281,56 @@ function recordTurnStartupPhase(observability, input) {
1256
1281
  value: Math.max(0, input.durationSeconds)
1257
1282
  });
1258
1283
  }
1284
+ function recordToolPreparationPhase(observability, input) {
1285
+ if (input.execution === "blocking") {
1286
+ recordTurnStartupPhase(observability, {
1287
+ ...input,
1288
+ phase: `tool_${input.phase}`
1289
+ });
1290
+ return;
1291
+ }
1292
+ completedOperationSpan(
1293
+ observability,
1294
+ `worker.tool_prepare.${input.phase}`,
1295
+ input.durationSeconds,
1296
+ {
1297
+ provider: input.provider,
1298
+ backend: input.backend,
1299
+ outcome: input.outcome
1300
+ }
1301
+ );
1302
+ observability.observeHistogram({
1303
+ name: "opengeni_tool_background_preparation_duration_seconds",
1304
+ help: "Nonblocking MCP preparation operations; may overlap startup and later execution.",
1305
+ buckets: TURN_STARTUP_PHASE_BUCKETS,
1306
+ labels: {
1307
+ phase: input.phase,
1308
+ provider: input.provider,
1309
+ backend: input.backend,
1310
+ outcome: input.outcome
1311
+ },
1312
+ value: Math.max(0, input.durationSeconds)
1313
+ });
1314
+ }
1315
+ function completedOperationSpan(observability, name, durationSeconds, attributes) {
1316
+ if (!Number.isFinite(durationSeconds) || durationSeconds < 0) return;
1317
+ try {
1318
+ const failed = [
1319
+ "failed",
1320
+ "error",
1321
+ "provider_declared_error",
1322
+ "auth_needed",
1323
+ "outcome_uncertain",
1324
+ "timeout",
1325
+ "thrown_transport_error",
1326
+ "thrown_protocol_error"
1327
+ ].includes(attributes.outcome);
1328
+ observability.startSpan(name, attributes, { startTimeMs: Date.now() - durationSeconds * 1e3 }).end({
1329
+ ...failed ? { error: true } : {}
1330
+ });
1331
+ } catch {
1332
+ }
1333
+ }
1259
1334
  function recordTurnSandboxEstablishPolicy(observability, input) {
1260
1335
  observability.incrementCounter({
1261
1336
  name: "opengeni_turn_sandbox_establish_policy_total",
@@ -1679,6 +1754,7 @@ export {
1679
1754
  recordCreditMicros,
1680
1755
  recordModelRequestPhase,
1681
1756
  recordTurnStartupPhase,
1757
+ recordToolPreparationPhase,
1682
1758
  recordTurnSandboxEstablishPolicy,
1683
1759
  recordSandboxProvisionAttempt,
1684
1760
  recordSandboxLogicalProvision,
@@ -1697,4 +1773,4 @@ export {
1697
1773
  recordModelCacheTokens,
1698
1774
  modelCallAccountContext
1699
1775
  };
1700
- //# sourceMappingURL=chunk-A4XQWVZK.js.map
1776
+ //# sourceMappingURL=chunk-I7HKKMUJ.js.map