@codemation/host 0.1.0 → 0.1.2

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 (70) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/{AppConfigFactory-Ciz9YKWx.js → AppConfigFactory-ByT1D8dM.js} +253 -15
  3. package/dist/{AppConfigFactory-Ciz9YKWx.js.map → AppConfigFactory-ByT1D8dM.js.map} +1 -1
  4. package/dist/{AppConfigFactory-CiBPHleh.d.ts → AppConfigFactory-_fqSok1J.d.ts} +6565 -177
  5. package/dist/{AppContainerFactory-DH88oxpg.js → AppContainerFactory-BRU02PTm.js} +838 -145
  6. package/dist/AppContainerFactory-BRU02PTm.js.map +1 -0
  7. package/dist/{CodemationConfig-DfK1KLvO.d.ts → CodemationConfig-CNfytKR6.d.ts} +2 -2
  8. package/dist/{CodemationConfigNormalizer-BKgIOeLm.d.ts → CodemationConfigNormalizer-BuKWVNEq.d.ts} +2 -2
  9. package/dist/{CodemationConsumerConfigLoader-bdhJsBKt.d.ts → CodemationConsumerConfigLoader-Mv4cywWu.d.ts} +2 -2
  10. package/dist/{CodemationPluginListMerger-BFZeO0WG.d.ts → CodemationPluginListMerger-BD5mR6gK.d.ts} +11 -5
  11. package/dist/{CredentialServices-aKIwHEhf.d.ts → CredentialServices-BQsEtctT.d.ts} +8 -7
  12. package/dist/{CredentialServices-DNb3CZwW.js → CredentialServices-xVxVA9Tq.js} +60 -114
  13. package/dist/CredentialServices-xVxVA9Tq.js.map +1 -0
  14. package/dist/{PublicFrontendBootstrapFactory-6ahaU0XM.d.ts → PublicFrontendBootstrapFactory-kTyAJdHI.d.ts} +2 -2
  15. package/dist/consumer.d.ts +4 -4
  16. package/dist/credentials.d.ts +3 -3
  17. package/dist/credentials.js +1 -1
  18. package/dist/devServerSidecar.d.ts +1 -1
  19. package/dist/{index-BYbzmUwS.d.ts → index-CX752QE9.d.ts} +68 -4
  20. package/dist/index.d.ts +10 -10
  21. package/dist/index.js +5 -5
  22. package/dist/nextServer.d.ts +20 -15
  23. package/dist/nextServer.js +35 -58
  24. package/dist/nextServer.js.map +1 -1
  25. package/dist/{persistenceServer-DL8yBGDU.d.ts → persistenceServer-CLY4qtMo.d.ts} +2 -2
  26. package/dist/{persistenceServer-CuAqL_fF.js → persistenceServer-DMvIOGW8.js} +2 -2
  27. package/dist/{persistenceServer-CuAqL_fF.js.map → persistenceServer-DMvIOGW8.js.map} +1 -1
  28. package/dist/persistenceServer.d.ts +5 -5
  29. package/dist/persistenceServer.js +2 -2
  30. package/dist/{server-EbxQft_X.js → server-ChTCEc6R.js} +4 -4
  31. package/dist/{server-EbxQft_X.js.map → server-ChTCEc6R.js.map} +1 -1
  32. package/dist/{server-BceIfIJf.d.ts → server-DwpcwzFb.d.ts} +6 -5
  33. package/dist/server.d.ts +8 -8
  34. package/dist/server.js +5 -5
  35. package/package.json +5 -5
  36. package/prisma/migrations/20260407140000_run_normalized_persistence/migration.sql +327 -0
  37. package/prisma/migrations/20260407193000_rename_run_projection_to_run_slot_projection/migration.sql +10 -0
  38. package/prisma/migrations.sqlite/20260407140000_run_normalized_persistence/migration.sql +326 -0
  39. package/prisma/migrations.sqlite/20260407193000_rename_run_projection_to_run_slot_projection/migration.sql +38 -0
  40. package/prisma/schema.postgresql.prisma +100 -1
  41. package/prisma/schema.sqlite.prisma +101 -1
  42. package/scripts/integration-database-global-setup.mjs +0 -3
  43. package/src/application/mapping/WorkflowDefinitionMapper.ts +95 -56
  44. package/src/application/mapping/WorkflowPolicyUiPresentationFactory.ts +1 -1
  45. package/src/application/queries/GetWorkflowRunDetailQuery.ts +8 -0
  46. package/src/application/queries/GetWorkflowRunDetailQueryHandler.ts +24 -0
  47. package/src/application/queries/WorkflowQueryHandlers.ts +1 -0
  48. package/src/application/runs/WorkflowRunRetentionPruneScheduler.ts +52 -27
  49. package/src/domain/credentials/WorkflowCredentialNodeResolver.ts +113 -158
  50. package/src/domain/runs/WorkflowRunRepository.ts +7 -1
  51. package/src/infrastructure/persistence/InMemoryWorkflowRunRepository.ts +123 -1
  52. package/src/infrastructure/persistence/PrismaMigrationDeployer.ts +226 -6
  53. package/src/infrastructure/persistence/PrismaWorkflowRunRepository.ts +796 -109
  54. package/src/infrastructure/persistence/generated/prisma-postgresql-client/edge.js +85 -5
  55. package/src/infrastructure/persistence/generated/prisma-postgresql-client/index-browser.js +81 -1
  56. package/src/infrastructure/persistence/generated/prisma-postgresql-client/index.d.ts +7107 -237
  57. package/src/infrastructure/persistence/generated/prisma-postgresql-client/index.js +85 -5
  58. package/src/infrastructure/persistence/generated/prisma-postgresql-client/package.json +1 -1
  59. package/src/infrastructure/persistence/generated/prisma-postgresql-client/schema.prisma +101 -1
  60. package/src/infrastructure/persistence/generated/prisma-sqlite-client/edge.js +85 -5
  61. package/src/infrastructure/persistence/generated/prisma-sqlite-client/index-browser.js +81 -1
  62. package/src/infrastructure/persistence/generated/prisma-sqlite-client/index.d.ts +7104 -242
  63. package/src/infrastructure/persistence/generated/prisma-sqlite-client/index.js +85 -5
  64. package/src/infrastructure/persistence/generated/prisma-sqlite-client/package.json +1 -1
  65. package/src/infrastructure/persistence/generated/prisma-sqlite-client/schema.prisma +101 -1
  66. package/src/presentation/http/ApiPaths.ts +4 -0
  67. package/src/presentation/http/hono/registrars/RunHonoApiRouteRegistrar.ts +1 -0
  68. package/src/presentation/http/routeHandlers/RunHttpRouteHandler.ts +13 -0
  69. package/dist/AppContainerFactory-DH88oxpg.js.map +0 -1
  70. package/dist/CredentialServices-DNb3CZwW.js.map +0 -1
@@ -213,10 +213,18 @@ interface PendingNodeExecution {
213
213
  batchId?: string;
214
214
  enqueuedAt: string;
215
215
  }
216
+ interface PersistedRunSchedulingState {
217
+ pending?: PendingNodeExecution;
218
+ queue: RunQueueEntry[];
219
+ }
216
220
  interface PersistedRunState {
217
221
  runId: RunId;
218
222
  workflowId: WorkflowId;
219
223
  startedAt: string;
224
+ /** Canonical terminal time for listings and retention when persisted on the run root. */
225
+ finishedAt?: string;
226
+ /** Optimistic concurrency / CAS on the run aggregate (repository may increment on save). */
227
+ revision?: number;
220
228
  parent?: ParentExecutionRef;
221
229
  executionOptions?: RunExecutionOptions;
222
230
  control?: PersistedRunControlState;
@@ -248,9 +256,17 @@ interface WorkflowExecutionRepository {
248
256
  engineCounters?: EngineRunCounters;
249
257
  }): Promise<void>;
250
258
  load(runId: RunId): Promise<PersistedRunState | undefined>;
259
+ loadSchedulingState(runId: RunId): Promise<PersistedRunSchedulingState | undefined>;
251
260
  save(state: PersistedRunState): Promise<void>;
252
261
  deleteRun?(runId: RunId): Promise<void>;
253
262
  }
263
+ /** Runs eligible for retention-based pruning (completed or failed, older than cutoff). */
264
+ interface RunPruneCandidate {
265
+ readonly runId: RunId;
266
+ readonly workflowId: WorkflowId;
267
+ readonly startedAt: string;
268
+ readonly finishedAt: string;
269
+ }
254
270
  type RunResult = {
255
271
  runId: RunId;
256
272
  workflowId: WorkflowId;
@@ -286,6 +302,53 @@ interface PersistedWorkflowTokenRegistryLike {
286
302
  registerFromWorkflows?(workflows: ReadonlyArray<WorkflowDefinition>): void;
287
303
  }
288
304
  //#endregion
305
+ //#region ../core/src/contracts/executionPersistenceContracts.d.ts
306
+ /** Canonical id for persisted execution rows (activation or connection invocation). */
307
+ type ExecutionInstanceId = string;
308
+ /** Batch grouping for planner activations. */
309
+ type BatchId = string;
310
+ type PersistedExecutionInstanceKind = "workflowNodeActivation" | "connectionInvocation";
311
+ type ConnectionInvocationKind = "languageModel" | "tool" | "nestedAgent";
312
+ interface WorkflowRunDetailDto {
313
+ readonly runId: RunId;
314
+ readonly workflowId: WorkflowId;
315
+ readonly startedAt: string;
316
+ readonly finishedAt?: string;
317
+ readonly status: RunStatus;
318
+ readonly workflowSnapshot?: PersistedWorkflowSnapshot;
319
+ readonly mutableState?: PersistedMutableRunState;
320
+ readonly slotStates: ReadonlyArray<SlotExecutionStateDto>;
321
+ readonly executionInstances: ReadonlyArray<ExecutionInstanceDto>;
322
+ }
323
+ interface SlotExecutionStateDto {
324
+ readonly slotNodeId: NodeId;
325
+ readonly latestInstanceId?: ExecutionInstanceId;
326
+ readonly latestTerminalInstanceId?: ExecutionInstanceId;
327
+ readonly latestRunningInstanceId?: ExecutionInstanceId;
328
+ readonly status?: NodeExecutionStatus;
329
+ readonly invocationCount: number;
330
+ readonly runCount: number;
331
+ }
332
+ interface ExecutionInstanceDto {
333
+ readonly instanceId: ExecutionInstanceId;
334
+ readonly slotNodeId: NodeId;
335
+ readonly workflowNodeId: NodeId;
336
+ readonly parentInstanceId?: ExecutionInstanceId;
337
+ readonly kind: PersistedExecutionInstanceKind;
338
+ readonly connectionKind?: ConnectionInvocationKind;
339
+ readonly runIndex: number;
340
+ readonly batchId: BatchId;
341
+ readonly activationId?: NodeActivationId;
342
+ readonly status: NodeExecutionStatus;
343
+ readonly queuedAt?: string;
344
+ readonly startedAt?: string;
345
+ readonly finishedAt?: string;
346
+ readonly itemCount: number;
347
+ readonly inputJson?: JsonValue;
348
+ readonly outputJson?: JsonValue;
349
+ readonly error?: Readonly<NodeExecutionError>;
350
+ }
351
+ //#endregion
289
352
  //#region ../core/src/contracts/webhookTypes.d.ts
290
353
  type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
291
354
  /** Match for an incoming HTTP request: user-defined URL segment + workflow trigger node. */
@@ -622,8 +685,9 @@ interface Edge {
622
685
  }
623
686
  type NodeConnectionName = string;
624
687
  /**
625
- * Named connection from an executable parent node to child nodes that exist in {@link WorkflowDefinition.nodes}
626
- * but are not traversed by the main execution graph.
688
+ * Named connection from a parent node to child nodes that exist in {@link WorkflowDefinition.nodes}
689
+ * but are not traversed by the main execution graph. Parents are commonly executable nodes, but may
690
+ * also be connection-owned nodes for recursive agent attachments.
627
691
  */
628
692
  interface WorkflowNodeConnection {
629
693
  readonly parentNodeId: NodeId;
@@ -1192,5 +1256,5 @@ declare class RunIntentService {
1192
1256
  private createWebhookExecutionOptions;
1193
1257
  }
1194
1258
  //#endregion
1195
- export { RunIdFactory as A, TypeToken as B, CredentialTypeId as C, Item as D, BinaryAttachment as E, BinaryStorage as F, AnyRunnableNodeConfig as G, RunEvent as H, NodeExecutionRequestHandler as I, PersistedRunState as J, WorkflowActivationPolicy as K, NodeExecutionScheduler as L, RunnableNodeOutputJson as M, WorkflowDefinition as N, NodeDefinition as O, WorkflowId as P, WorkflowRepository as R, CredentialTypeDefinition as S, ActivationIdFactory as T, RunEventBus as U, EngineExecutionLimitsPolicyConfig as V, ChainCursor as W, RunSummary as X, RunCurrentState as Y, Clock as Z, CredentialRequirement as _, ToolConfig as a, CredentialSetupStatus as b, CredentialBinding as c, CredentialHealth as d, CredentialInstanceId as f, CredentialOAuth2AuthDefinition as g, CredentialMaterialSourceKind as h, ChatModelConfig as i, RunnableNodeConfig as j, RunId as k, CredentialBindingKey as l, CredentialJsonRecord as m, Engine as n, DefinedNode as o, CredentialInstanceRecord as p, WebhookInvocationMatch as q, AgentGuardrailConfig as r, AnyCredentialType as s, RunIntentService as t, CredentialFieldSchema as u, CredentialSessionFactoryArgs as v, CredentialTypeRegistry as w, CredentialType as x, CredentialSessionService as y, Container as z };
1196
- //# sourceMappingURL=index-BYbzmUwS.d.ts.map
1259
+ export { RunnableNodeConfig as A, EngineExecutionLimitsPolicyConfig as B, CredentialTypeId as C, Item as D, BinaryAttachment as E, NodeExecutionRequestHandler as F, WorkflowActivationPolicy as G, RunEventBus as H, NodeExecutionScheduler as I, PersistedRunState as J, WebhookInvocationMatch as K, WorkflowRepository as L, WorkflowDefinition as M, WorkflowId as N, RunId as O, BinaryStorage as P, Clock as Q, Container as R, CredentialTypeDefinition as S, ActivationIdFactory as T, ChainCursor as U, RunEvent as V, AnyRunnableNodeConfig as W, RunPruneCandidate as X, RunCurrentState as Y, RunSummary as Z, CredentialRequirement as _, ToolConfig as a, CredentialSetupStatus as b, CredentialBinding as c, CredentialHealth as d, CredentialInstanceId as f, CredentialOAuth2AuthDefinition as g, CredentialMaterialSourceKind as h, ChatModelConfig as i, RunnableNodeOutputJson as j, RunIdFactory as k, CredentialBindingKey as l, CredentialJsonRecord as m, Engine as n, DefinedNode as o, CredentialInstanceRecord as p, WorkflowRunDetailDto as q, AgentGuardrailConfig as r, AnyCredentialType as s, RunIntentService as t, CredentialFieldSchema as u, CredentialSessionFactoryArgs as v, CredentialTypeRegistry as w, CredentialType as x, CredentialSessionService as y, TypeToken as z };
1260
+ //# sourceMappingURL=index-CX752QE9.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,16 +1,16 @@
1
1
  import { a as CodemationWhitelabelConfig, c as CodemationLogRule, i as CodemationAuthOidcProviderConfig, n as CodemationAuthKind, o as CodemationLogConfig, r as CodemationAuthOAuthProviderConfig, s as CodemationLogLevelName, t as CodemationAuthConfig } from "./CodemationAuthConfig-7hEfICPf.js";
2
2
  import { a as CodemationFrontendAuthSnapshot, i as CodemationFrontendAuthProviderSnapshot, n as InternalAuthBootstrap, r as FrontendAppConfig, t as PublicFrontendBootstrap } from "./PublicFrontendBootstrap-DCniMBGu.js";
3
3
  import { i as CodemationFrontendAuthSnapshotJsonCodec, n as InternalAuthBootstrapJsonCodec, r as FrontendAppConfigJsonCodec, t as PublicFrontendBootstrapJsonCodec } from "./PublicFrontendBootstrapJsonCodec-BE0mhe1v.js";
4
- import { G as AnyRunnableNodeConfig, M as RunnableNodeOutputJson, N as WorkflowDefinition, W as ChainCursor, a as ToolConfig, i as ChatModelConfig, j as RunnableNodeConfig, o as DefinedNode, r as AgentGuardrailConfig, s as AnyCredentialType } from "./index-BYbzmUwS.js";
5
- import { S as CodemationPluginPackageMetadata, a as CodemationConfig, b as CodemationPluginConfig, c as CodemationEngineExecutionLimitsConfig, d as CodemationSchedulerConfig, f as CodemationSchedulerKind, g as AppConfig, h as CodemationRegistrationContextBase, i as CodemationApplicationRuntimeConfig, l as CodemationEventBusConfig, m as CodemationAppContext, n as CodemationAppSchedulerConfig, o as CodemationDatabaseConfig, p as CodemationWorkflowDiscovery, r as CodemationAppSchedulerKind, s as CodemationDatabaseKind, t as CodemationAppDefinition, u as CodemationEventBusKind, v as AppPluginLoadSummary, w as CodemationClassToken, x as CodemationPluginContext, y as CodemationPlugin } from "./CodemationConfig-DfK1KLvO.js";
6
- import "./CodemationConfigNormalizer-BKgIOeLm.js";
7
- import { t as CodemationConsumerConfigLoader } from "./CodemationConsumerConfigLoader-bdhJsBKt.js";
8
- import "./CredentialServices-aKIwHEhf.js";
9
- import { _ as Command, c as WorkerRuntime, d as AppContainerLifecycle, f as AppContainerFactory, g as CommandBus, h as Query, l as FrontendRuntime, m as QueryBus, n as CodemationBootstrapRequest, r as ApplicationTokens, t as CodemationPluginListMerger, u as DatabaseMigrations } from "./CodemationPluginListMerger-BFZeO0WG.js";
10
- import { r as PrismaDatabaseClient, t as AppConfigFactory } from "./AppConfigFactory-CiBPHleh.js";
11
- import { t as CodemationPostgresPrismaClientFactory } from "./persistenceServer-DL8yBGDU.js";
12
- import { c as CodemationServerGateway, l as ApiPaths } from "./server-BceIfIJf.js";
13
- import { i as CodemationFrontendAuthSnapshotFactory, n as InternalAuthBootstrapFactory, r as FrontendAppConfigFactory, t as PublicFrontendBootstrapFactory } from "./PublicFrontendBootstrapFactory-6ahaU0XM.js";
4
+ import { A as RunnableNodeConfig, M as WorkflowDefinition, U as ChainCursor, W as AnyRunnableNodeConfig, a as ToolConfig, i as ChatModelConfig, j as RunnableNodeOutputJson, o as DefinedNode, r as AgentGuardrailConfig, s as AnyCredentialType } from "./index-CX752QE9.js";
5
+ import { S as CodemationPluginPackageMetadata, a as CodemationConfig, b as CodemationPluginConfig, c as CodemationEngineExecutionLimitsConfig, d as CodemationSchedulerConfig, f as CodemationSchedulerKind, g as AppConfig, h as CodemationRegistrationContextBase, i as CodemationApplicationRuntimeConfig, l as CodemationEventBusConfig, m as CodemationAppContext, n as CodemationAppSchedulerConfig, o as CodemationDatabaseConfig, p as CodemationWorkflowDiscovery, r as CodemationAppSchedulerKind, s as CodemationDatabaseKind, t as CodemationAppDefinition, u as CodemationEventBusKind, v as AppPluginLoadSummary, w as CodemationClassToken, x as CodemationPluginContext, y as CodemationPlugin } from "./CodemationConfig-CNfytKR6.js";
6
+ import "./CodemationConfigNormalizer-BuKWVNEq.js";
7
+ import { t as CodemationConsumerConfigLoader } from "./CodemationConsumerConfigLoader-Mv4cywWu.js";
8
+ import "./CredentialServices-BQsEtctT.js";
9
+ import { _ as Command, c as WorkerRuntime, d as AppContainerLifecycle, f as AppContainerFactory, g as CommandBus, h as Query, l as FrontendRuntime, m as QueryBus, n as CodemationBootstrapRequest, r as ApplicationTokens, t as CodemationPluginListMerger, u as DatabaseMigrations } from "./CodemationPluginListMerger-BD5mR6gK.js";
10
+ import { r as PrismaDatabaseClient, t as AppConfigFactory } from "./AppConfigFactory-_fqSok1J.js";
11
+ import { t as CodemationPostgresPrismaClientFactory } from "./persistenceServer-CLY4qtMo.js";
12
+ import { c as CodemationServerGateway, l as ApiPaths } from "./server-DwpcwzFb.js";
13
+ import { i as CodemationFrontendAuthSnapshotFactory, n as InternalAuthBootstrapFactory, r as FrontendAppConfigFactory, t as PublicFrontendBootstrapFactory } from "./PublicFrontendBootstrapFactory-kTyAJdHI.js";
14
14
  import { z } from "zod";
15
15
 
16
16
  //#region src/application/contracts/userDirectoryContracts.types.d.ts
package/dist/index.js CHANGED
@@ -4,12 +4,12 @@ import { t as CodemationConsumerConfigLoader } from "./CodemationConsumerConfigL
4
4
  import "./ServerLoggerFactory-BltIIDfQ.js";
5
5
  import "./decorateParam-DrsXNPuw.js";
6
6
  import "./decorate-B0PP651O.js";
7
- import { u as ApplicationTokens } from "./CredentialServices-DNb3CZwW.js";
8
- import { E as ListUserAccountsQuery, T as UpsertLocalBootstrapUserCommand, _ as CodemationFrontendAuthSnapshotFactory, a as AppContainerLifecycle, g as FrontendAppConfigFactory, h as InternalAuthBootstrapFactory, i as DatabaseMigrations, m as PublicFrontendBootstrapFactory, n as WorkerRuntime, r as FrontendRuntime, t as AppContainerFactory, y as ApiPaths } from "./AppContainerFactory-DH88oxpg.js";
9
- import { n as CodemationPluginPackageMetadata, t as AppConfigFactory } from "./AppConfigFactory-Ciz9YKWx.js";
7
+ import { u as ApplicationTokens } from "./CredentialServices-xVxVA9Tq.js";
8
+ import { E as ListUserAccountsQuery, T as UpsertLocalBootstrapUserCommand, _ as CodemationFrontendAuthSnapshotFactory, a as AppContainerLifecycle, g as FrontendAppConfigFactory, h as InternalAuthBootstrapFactory, i as DatabaseMigrations, m as PublicFrontendBootstrapFactory, n as WorkerRuntime, r as FrontendRuntime, t as AppContainerFactory, y as ApiPaths } from "./AppContainerFactory-BRU02PTm.js";
9
+ import { n as CodemationPluginPackageMetadata, t as AppConfigFactory } from "./AppConfigFactory-ByT1D8dM.js";
10
10
  import { n as CodemationBootstrapRequest, t as CodemationPluginListMerger } from "./CodemationPluginListMerger-CGwOTdZ7.js";
11
- import { t as CodemationPostgresPrismaClientFactory } from "./persistenceServer-CuAqL_fF.js";
12
- import { r as CodemationServerGateway } from "./server-EbxQft_X.js";
11
+ import { t as CodemationPostgresPrismaClientFactory } from "./persistenceServer-DMvIOGW8.js";
12
+ import { r as CodemationServerGateway } from "./server-ChTCEc6R.js";
13
13
  import { workflow } from "@codemation/core-nodes";
14
14
 
15
15
  //#region src/presentation/config/CodemationAuthoring.types.ts
@@ -1,14 +1,15 @@
1
1
  import { l as Logger, u as LoggerFactory } from "./CodemationAuthConfig-7hEfICPf.js";
2
2
  import { t as LogLevelPolicy } from "./LogLevelPolicy-9IcPGZFk.js";
3
3
  import { a as CodemationFrontendAuthSnapshot, i as CodemationFrontendAuthProviderSnapshot, n as InternalAuthBootstrap, r as FrontendAppConfig, t as PublicFrontendBootstrap } from "./PublicFrontendBootstrap-DCniMBGu.js";
4
- import { A as RunIdFactory, D as Item, E as BinaryAttachment, F as BinaryStorage, K as WorkflowActivationPolicy, N as WorkflowDefinition, O as NodeDefinition, S as CredentialTypeDefinition, T as ActivationIdFactory, Z as Clock, g as CredentialOAuth2AuthDefinition, q as WebhookInvocationMatch, t as RunIntentService } from "./index-BYbzmUwS.js";
5
- import { g as AppConfig } from "./CodemationConfig-DfK1KLvO.js";
6
- import "./CodemationConfigNormalizer-BKgIOeLm.js";
7
- import { a as CredentialInstanceService, c as CredentialFieldEnvOverlayService, i as CredentialBindingService, l as CredentialTypeRegistryImpl, o as CredentialMaterialResolver, r as CredentialRuntimeMaterialService, s as CredentialSecretCipher, t as CredentialStore } from "./CredentialServices-aKIwHEhf.js";
8
- import { a as WorkflowDebuggerOverlayRepository, c as WorkerRuntime, d as AppContainerLifecycle, f as AppContainerFactory, g as CommandBus, i as HonoApiRouteRegistrar, l as FrontendRuntime, m as QueryBus, n as CodemationBootstrapRequest, o as WorkflowRunRepository, p as WorkflowWebsocketServer, r as ApplicationTokens, s as SessionVerifier, t as CodemationPluginListMerger, u as DatabaseMigrations } from "./CodemationPluginListMerger-BFZeO0WG.js";
9
- import { t as AppConfigFactory } from "./AppConfigFactory-CiBPHleh.js";
10
- import { a as WorkflowDto, n as InternalAuthBootstrapFactory, o as WorkflowSummary, r as FrontendAppConfigFactory, t as PublicFrontendBootstrapFactory } from "./PublicFrontendBootstrapFactory-6ahaU0XM.js";
4
+ import { D as Item, E as BinaryAttachment, G as WorkflowActivationPolicy, K as WebhookInvocationMatch, M as WorkflowDefinition$1, P as BinaryStorage, Q as Clock, S as CredentialTypeDefinition, T as ActivationIdFactory, g as CredentialOAuth2AuthDefinition, k as RunIdFactory, t as RunIntentService } from "./index-CX752QE9.js";
5
+ import { g as AppConfig } from "./CodemationConfig-CNfytKR6.js";
6
+ import "./CodemationConfigNormalizer-BuKWVNEq.js";
7
+ import { a as CredentialInstanceService, c as CredentialFieldEnvOverlayService, i as CredentialBindingService, l as CredentialTypeRegistryImpl, o as CredentialMaterialResolver, r as CredentialRuntimeMaterialService, s as CredentialSecretCipher, t as CredentialStore } from "./CredentialServices-BQsEtctT.js";
8
+ import { a as WorkflowDebuggerOverlayRepository, c as WorkerRuntime, d as AppContainerLifecycle, f as AppContainerFactory, g as CommandBus, i as HonoApiRouteRegistrar, l as FrontendRuntime, m as QueryBus, n as CodemationBootstrapRequest, o as WorkflowRunRepository, p as WorkflowWebsocketServer, r as ApplicationTokens, s as SessionVerifier, t as CodemationPluginListMerger, u as DatabaseMigrations } from "./CodemationPluginListMerger-BD5mR6gK.js";
9
+ import { t as AppConfigFactory } from "./AppConfigFactory-_fqSok1J.js";
10
+ import { a as WorkflowDto, n as InternalAuthBootstrapFactory, o as WorkflowSummary, r as FrontendAppConfigFactory, t as PublicFrontendBootstrapFactory } from "./PublicFrontendBootstrapFactory-kTyAJdHI.js";
11
11
  import { Hono } from "hono";
12
+ import { NodeDefinition, WorkflowDefinition } from "@codemation/core/browser";
12
13
 
13
14
  //#region src/application/dev/DevBootstrapSummaryJson.types.d.ts
14
15
  type DevBootstrapSummaryJson = Readonly<{
@@ -122,19 +123,21 @@ declare class WorkflowPolicyUiPresentationFactory {
122
123
  }
123
124
  //#endregion
124
125
  //#region src/application/mapping/WorkflowDefinitionMapper.d.ts
125
- declare class WorkflowDefinitionMapper implements DataMapper<WorkflowDefinition, WorkflowDto> {
126
+ declare class WorkflowDefinitionMapper implements DataMapper<WorkflowDefinition$1, WorkflowDto> {
126
127
  private readonly policyUi;
127
128
  private readonly workflowActivationPolicy;
128
129
  constructor(policyUi: WorkflowPolicyUiPresentationFactory, workflowActivationPolicy: WorkflowActivationPolicy);
129
- map(workflow: WorkflowDefinition): Promise<WorkflowDto>;
130
- mapSync(workflow: WorkflowDefinition): WorkflowDto;
131
- toSummary(workflow: WorkflowDefinition): WorkflowSummary;
130
+ map(workflow: WorkflowDefinition$1): Promise<WorkflowDto>;
131
+ mapSync(workflow: WorkflowDefinition$1): WorkflowDto;
132
+ toSummary(workflow: WorkflowDefinition$1): WorkflowSummary;
132
133
  private buildConnectionChildMeta;
133
- private agentHasConnectionMetadata;
134
134
  private toNodes;
135
135
  private toEdges;
136
- private createLanguageModelNode;
137
- private createToolNode;
136
+ private appendMaterializedConnectionEdges;
137
+ private appendVirtualConnectionNodes;
138
+ private appendVirtualConnectionEdges;
139
+ private edgeKey;
140
+ private createConnectionNode;
138
141
  private nodeTypeName;
139
142
  }
140
143
  //#endregion
@@ -151,12 +154,13 @@ declare class WorkflowRunRetentionPruneScheduler {
151
154
  private readonly appConfig;
152
155
  private timer;
153
156
  private readonly logger;
154
- private readonly binaryKeysCollector;
155
157
  constructor(clock: Clock, runs: WorkflowRunRepository, binaryStorage: BinaryStorage, appConfig: AppConfig, loggerFactory: ServerLoggerFactory);
156
158
  start(): void;
157
159
  stop(): void;
158
160
  /** Exposed for tests; production path is the interval started by {@link start}. */
159
161
  runOnce(): Promise<void>;
162
+ private loadStorageKeysFromRunStateFallback;
163
+ private collectStorageKeysFromValue;
160
164
  }
161
165
  //#endregion
162
166
  //#region src/infrastructure/webhooks/RequestToWebhookItemMapper.d.ts
@@ -311,6 +315,7 @@ declare class RunHttpRouteHandler {
311
315
  private readonly commandBus;
312
316
  constructor(queryBus: QueryBus, commandBus: CommandBus);
313
317
  getRun(_: Request, params: ServerHttpRouteParams): Promise<Response>;
318
+ getRunDetail(_: Request, params: ServerHttpRouteParams): Promise<Response>;
314
319
  postRuns(request: Request, _: ServerHttpRouteParams): Promise<Response>;
315
320
  patchRunWorkflowSnapshot(request: Request, params: ServerHttpRouteParams): Promise<Response>;
316
321
  patchRunNodePin(request: Request, params: ServerHttpRouteParams): Promise<Response>;
@@ -2,58 +2,17 @@ import "./ConsoleLogger-ClPU7jtc.js";
2
2
  import { a as FilteringLogger, i as PerformanceLogPolicy, n as PerformanceLogPolicyFactory, o as LogLevelPolicyFactory, r as performanceLogPolicyFactory, s as logLevelPolicyFactory, t as ServerLoggerFactory } from "./ServerLoggerFactory-BltIIDfQ.js";
3
3
  import { n as __decorateMetadata, t as __decorateParam } from "./decorateParam-DrsXNPuw.js";
4
4
  import { t as __decorate } from "./decorate-B0PP651O.js";
5
- import { a as CredentialInstanceService, i as CredentialBindingService, u as ApplicationTokens } from "./CredentialServices-DNb3CZwW.js";
6
- import { a as AppContainerLifecycle, b as WorkflowDefinitionMapper, c as RequestToWebhookItemMapper, d as CredentialHttpRouteHandler, f as CodemationHonoApiApp, g as FrontendAppConfigFactory, h as InternalAuthBootstrapFactory, i as DatabaseMigrations, l as RunHttpRouteHandler, m as PublicFrontendBootstrapFactory, n as WorkerRuntime, o as WorkflowHttpRouteHandler, p as BinaryHttpRouteHandler, r as FrontendRuntime, s as WebhookHttpRouteHandler, t as AppContainerFactory, u as OAuth2HttpRouteHandler, v as WorkflowWebsocketServer, w as RunBinaryAttachmentLookupService, x as WorkflowPolicyUiPresentationFactory } from "./AppContainerFactory-DH88oxpg.js";
7
- import { t as AppConfigFactory } from "./AppConfigFactory-Ciz9YKWx.js";
5
+ import { a as CredentialInstanceService, i as CredentialBindingService, u as ApplicationTokens } from "./CredentialServices-xVxVA9Tq.js";
6
+ import { a as AppContainerLifecycle, b as WorkflowDefinitionMapper, c as RequestToWebhookItemMapper, d as CredentialHttpRouteHandler, f as CodemationHonoApiApp, g as FrontendAppConfigFactory, h as InternalAuthBootstrapFactory, i as DatabaseMigrations, l as RunHttpRouteHandler, m as PublicFrontendBootstrapFactory, n as WorkerRuntime, o as WorkflowHttpRouteHandler, p as BinaryHttpRouteHandler, r as FrontendRuntime, s as WebhookHttpRouteHandler, t as AppContainerFactory, u as OAuth2HttpRouteHandler, v as WorkflowWebsocketServer, w as RunBinaryAttachmentLookupService, x as WorkflowPolicyUiPresentationFactory } from "./AppContainerFactory-BRU02PTm.js";
7
+ import { t as AppConfigFactory } from "./AppConfigFactory-ByT1D8dM.js";
8
8
  import { n as CodemationBootstrapRequest, t as CodemationPluginListMerger } from "./CodemationPluginListMerger-CGwOTdZ7.js";
9
- import { CoreTokens, RunFinishedAtFactory, inject, injectable } from "@codemation/core";
9
+ import { CoreTokens, inject, injectable } from "@codemation/core";
10
10
 
11
- //#region src/application/binary/RunStateBinaryStorageKeysCollector.ts
12
- /**
13
- * Collects every `storageKey` referenced by binary attachments embedded in persisted run state
14
- * (outputs, node snapshots, mutable debugger state).
15
- */
16
- var RunStateBinaryStorageKeysCollector = class {
17
- collectFromRunState(state) {
18
- const keys = /* @__PURE__ */ new Set();
19
- this.addFromOutputsByNode(state.outputsByNode, keys);
20
- this.addFromNodeSnapshots(state, keys);
21
- this.addFromMutableState(state.mutableState, keys);
22
- return keys;
23
- }
24
- addFromOutputsByNode(outputsByNode, keys) {
25
- for (const outputs of Object.values(outputsByNode)) for (const items of Object.values(outputs)) this.addFromItems(items, keys);
26
- }
27
- addFromNodeSnapshots(state, keys) {
28
- for (const snapshot of Object.values(state.nodeSnapshotsByNodeId)) {
29
- this.addFromPortMap(snapshot.inputsByPort, keys);
30
- this.addFromPortMap(snapshot.outputs, keys);
31
- }
32
- }
33
- addFromMutableState(mutableState, keys) {
34
- for (const nodeState of Object.values(mutableState?.nodesById ?? {})) {
35
- this.addFromPortMap(nodeState.pinnedOutputsByPort, keys);
36
- this.addFromItems(nodeState.lastDebugInput, keys);
37
- }
38
- }
39
- addFromPortMap(itemMap, keys) {
40
- for (const items of Object.values(itemMap ?? {})) this.addFromItems(items, keys);
41
- }
42
- addFromItems(items, keys) {
43
- for (const item of items ?? []) for (const attachment of Object.values(item.binary ?? {})) this.addAttachment(attachment, keys);
44
- }
45
- addAttachment(attachment, keys) {
46
- if (attachment.storageKey.length > 0) keys.add(attachment.storageKey);
47
- }
48
- };
49
-
50
- //#endregion
51
11
  //#region src/application/runs/WorkflowRunRetentionPruneScheduler.ts
52
12
  var _ref;
53
13
  let WorkflowRunRetentionPruneScheduler = class WorkflowRunRetentionPruneScheduler$1 {
54
14
  timer;
55
15
  logger;
56
- binaryKeysCollector = new RunStateBinaryStorageKeysCollector();
57
16
  constructor(clock, runs, binaryStorage, appConfig, loggerFactory) {
58
17
  this.clock = clock;
59
18
  this.runs = runs;
@@ -81,22 +40,18 @@ let WorkflowRunRetentionPruneScheduler = class WorkflowRunRetentionPruneSchedule
81
40
  async runOnce() {
82
41
  this.logger.debug("Run retention prune: starting check");
83
42
  const defaultRetentionSec = Number(this.appConfig.env.CODEMATION_RUN_RETENTION_DEFAULT_SECONDS ?? 86400);
84
- const summaries = await this.runs.listRuns({ limit: 500 });
85
- const nowMs = this.clock.now().getTime();
43
+ const beforeIso = (/* @__PURE__ */ new Date(this.clock.now().getTime() - defaultRetentionSec * 1e3)).toISOString();
44
+ const candidates = await this.runs.listRunsOlderThan?.({
45
+ beforeIso,
46
+ limit: 500
47
+ }) ?? (await this.runs.listRuns({ limit: 500 })).filter((summary) => summary.status === "completed" || summary.status === "failed");
86
48
  let foundCount = 0;
87
49
  let prunedCount = 0;
88
- for (const s of summaries) {
89
- if (s.status !== "completed" && s.status !== "failed") continue;
90
- const state = await this.runs.load(s.runId);
91
- if (!state) continue;
92
- const retentionSec = state.policySnapshot?.retentionSeconds ?? defaultRetentionSec;
93
- const finishedAt = RunFinishedAtFactory.resolveIso(state) ?? s.finishedAt;
94
- if (!finishedAt) continue;
95
- if (nowMs - Date.parse(finishedAt) <= retentionSec * 1e3) continue;
96
- const runId = s.runId;
97
- const workflowId = s.workflowId;
50
+ for (const candidate of candidates) {
51
+ const runId = candidate.runId;
52
+ const workflowId = candidate.workflowId;
98
53
  foundCount += 1;
99
- const storageKeys = this.binaryKeysCollector.collectFromRunState(state);
54
+ const storageKeys = await this.runs.listBinaryStorageKeys?.(runId) ?? await this.loadStorageKeysFromRunStateFallback(runId);
100
55
  for (const key of storageKeys) await this.binaryStorage.delete(key);
101
56
  await this.runs.deleteRun(runId);
102
57
  prunedCount += 1;
@@ -105,6 +60,28 @@ let WorkflowRunRetentionPruneScheduler = class WorkflowRunRetentionPruneSchedule
105
60
  this.logger.info(`Run retention prune: found ${foundCount} run(s) to prune`);
106
61
  this.logger.info(`Run retention prune: pruned ${prunedCount} run(s)`);
107
62
  }
63
+ async loadStorageKeysFromRunStateFallback(runId) {
64
+ const state = await this.runs.load(runId);
65
+ if (!state) return [];
66
+ const keys = /* @__PURE__ */ new Set();
67
+ this.collectStorageKeysFromValue(state.outputsByNode, keys);
68
+ this.collectStorageKeysFromValue(state.nodeSnapshotsByNodeId, keys);
69
+ this.collectStorageKeysFromValue(state.mutableState, keys);
70
+ return [...keys];
71
+ }
72
+ collectStorageKeysFromValue(value, keys) {
73
+ if (Array.isArray(value)) {
74
+ for (const entry of value) this.collectStorageKeysFromValue(entry, keys);
75
+ return;
76
+ }
77
+ if (!value || typeof value !== "object") return;
78
+ const record = value;
79
+ if (typeof record.id === "string" && typeof record.storageKey === "string" && typeof record.mimeType === "string" && typeof record.size === "number") {
80
+ if (record.storageKey.length > 0) keys.add(record.storageKey);
81
+ return;
82
+ }
83
+ for (const child of Object.values(record)) this.collectStorageKeysFromValue(child, keys);
84
+ }
108
85
  };
109
86
  WorkflowRunRetentionPruneScheduler = __decorate([
110
87
  injectable(),
@@ -1 +1 @@
1
- {"version":3,"file":"nextServer.js","names":["WorkflowRunRetentionPruneScheduler","clock: Clock","runs: WorkflowRunRepository","binaryStorage: BinaryStorage","appConfig: AppConfig","loggerFactory: ServerLoggerFactory"],"sources":["../src/application/binary/RunStateBinaryStorageKeysCollector.ts","../src/application/runs/WorkflowRunRetentionPruneScheduler.ts"],"sourcesContent":["import type { BinaryAttachment, Items, PersistedRunState } from \"@codemation/core\";\n\n/**\n * Collects every `storageKey` referenced by binary attachments embedded in persisted run state\n * (outputs, node snapshots, mutable debugger state).\n */\nexport class RunStateBinaryStorageKeysCollector {\n collectFromRunState(state: PersistedRunState): ReadonlySet<string> {\n const keys = new Set<string>();\n this.addFromOutputsByNode(state.outputsByNode, keys);\n this.addFromNodeSnapshots(state, keys);\n this.addFromMutableState(state.mutableState, keys);\n return keys;\n }\n\n private addFromOutputsByNode(outputsByNode: PersistedRunState[\"outputsByNode\"], keys: Set<string>): void {\n for (const outputs of Object.values(outputsByNode)) {\n for (const items of Object.values(outputs)) {\n this.addFromItems(items, keys);\n }\n }\n }\n\n private addFromNodeSnapshots(state: PersistedRunState, keys: Set<string>): void {\n for (const snapshot of Object.values(state.nodeSnapshotsByNodeId)) {\n this.addFromPortMap(snapshot.inputsByPort, keys);\n this.addFromPortMap(snapshot.outputs, keys);\n }\n }\n\n private addFromMutableState(mutableState: PersistedRunState[\"mutableState\"], keys: Set<string>): void {\n for (const nodeState of Object.values(mutableState?.nodesById ?? {})) {\n this.addFromPortMap(nodeState.pinnedOutputsByPort, keys);\n this.addFromItems(nodeState.lastDebugInput, keys);\n }\n }\n\n private addFromPortMap(itemMap: Readonly<Partial<Record<string, Items>>> | undefined, keys: Set<string>): void {\n for (const items of Object.values(itemMap ?? {})) {\n this.addFromItems(items, keys);\n }\n }\n\n private addFromItems(items: Items | undefined, keys: Set<string>): void {\n for (const item of items ?? []) {\n for (const attachment of Object.values(item.binary ?? {})) {\n this.addAttachment(attachment, keys);\n }\n }\n }\n\n private addAttachment(attachment: BinaryAttachment, keys: Set<string>): void {\n if (attachment.storageKey.length > 0) {\n keys.add(attachment.storageKey);\n }\n }\n}\n","import type { BinaryStorage, Clock, RunId, WorkflowId } from \"@codemation/core\";\nimport { CoreTokens, RunFinishedAtFactory } from \"@codemation/core\";\nimport { inject, injectable } from \"@codemation/core\";\nimport type { Logger } from \"../logging/Logger\";\nimport { RunStateBinaryStorageKeysCollector } from \"../binary/RunStateBinaryStorageKeysCollector\";\nimport { ApplicationTokens } from \"../../applicationTokens\";\nimport type { AppConfig } from \"../../presentation/config/AppConfig\";\nimport type { WorkflowRunRepository } from \"../../domain/runs/WorkflowRunRepository\";\nimport { ServerLoggerFactory } from \"../../infrastructure/logging/ServerLoggerFactory\";\n\n/**\n * Periodically deletes terminal workflow runs whose age exceeds the effective retention\n * (`policySnapshot.retentionSeconds` or `CODEMATION_RUN_RETENTION_DEFAULT_SECONDS`),\n * and removes binary blobs referenced from run state via {@link BinaryStorage}.\n */\n@injectable()\nexport class WorkflowRunRetentionPruneScheduler {\n private timer: ReturnType<typeof setInterval> | undefined;\n private readonly logger: Logger;\n private readonly binaryKeysCollector = new RunStateBinaryStorageKeysCollector();\n\n constructor(\n @inject(ApplicationTokens.Clock) private readonly clock: Clock,\n @inject(ApplicationTokens.WorkflowRunRepository) private readonly runs: WorkflowRunRepository,\n @inject(CoreTokens.BinaryStorage) private readonly binaryStorage: BinaryStorage,\n @inject(ApplicationTokens.AppConfig) private readonly appConfig: AppConfig,\n @inject(ServerLoggerFactory) loggerFactory: ServerLoggerFactory,\n ) {\n this.logger = loggerFactory.create(\"codemation.runRetentionPrune\");\n }\n\n start(): void {\n if (this.appConfig.env.CODEMATION_RUN_PRUNE_ENABLED === \"false\") {\n return;\n }\n if (this.timer) {\n return;\n }\n const intervalMs = Number(this.appConfig.env.CODEMATION_RUN_PRUNE_INTERVAL_MS ?? 60_000);\n this.timer = setInterval(() => {\n void this.runOnce().catch((error: unknown) => {\n this.logger.warn(`Run retention prune tick failed: ${error instanceof Error ? error.message : String(error)}`);\n });\n }, intervalMs);\n }\n\n stop(): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n }\n\n /** Exposed for tests; production path is the interval started by {@link start}. */\n async runOnce(): Promise<void> {\n this.logger.debug(\"Run retention prune: starting check\");\n\n const defaultRetentionSec = Number(this.appConfig.env.CODEMATION_RUN_RETENTION_DEFAULT_SECONDS ?? 86_400);\n const summaries = await this.runs.listRuns({ limit: 500 });\n const nowMs = this.clock.now().getTime();\n\n let foundCount = 0;\n let prunedCount = 0;\n for (const s of summaries) {\n if (s.status !== \"completed\" && s.status !== \"failed\") {\n continue;\n }\n const state = await this.runs.load(s.runId);\n if (!state) {\n continue;\n }\n const retentionSec = state.policySnapshot?.retentionSeconds ?? defaultRetentionSec;\n const finishedAt = RunFinishedAtFactory.resolveIso(state) ?? s.finishedAt;\n if (!finishedAt) {\n continue;\n }\n const ageMs = nowMs - Date.parse(finishedAt);\n if (ageMs <= retentionSec * 1000) {\n continue;\n }\n\n const runId = s.runId as RunId;\n const workflowId = s.workflowId as WorkflowId;\n foundCount += 1;\n\n const storageKeys = this.binaryKeysCollector.collectFromRunState(state);\n for (const key of storageKeys) {\n await this.binaryStorage.delete(key);\n }\n await this.runs.deleteRun(runId);\n prunedCount += 1;\n this.logger.debug(`Run retention prune: pruned run ${runId} for workflow ${workflowId}`);\n }\n\n this.logger.info(`Run retention prune: found ${foundCount} run(s) to prune`);\n this.logger.info(`Run retention prune: pruned ${prunedCount} run(s)`);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"nextServer.js","names":["WorkflowRunRetentionPruneScheduler","clock: Clock","runs: WorkflowRunRepository","binaryStorage: BinaryStorage","appConfig: AppConfig","loggerFactory: ServerLoggerFactory"],"sources":["../src/application/runs/WorkflowRunRetentionPruneScheduler.ts"],"sourcesContent":["import type { BinaryStorage, Clock, RunId, WorkflowId } from \"@codemation/core\";\nimport { CoreTokens } from \"@codemation/core\";\nimport { inject, injectable } from \"@codemation/core\";\nimport type { Logger } from \"../logging/Logger\";\nimport { ApplicationTokens } from \"../../applicationTokens\";\nimport type { AppConfig } from \"../../presentation/config/AppConfig\";\nimport type { WorkflowRunRepository } from \"../../domain/runs/WorkflowRunRepository\";\nimport { ServerLoggerFactory } from \"../../infrastructure/logging/ServerLoggerFactory\";\n\n/**\n * Periodically deletes terminal workflow runs whose age exceeds the effective retention\n * (`policySnapshot.retentionSeconds` or `CODEMATION_RUN_RETENTION_DEFAULT_SECONDS`),\n * and removes binary blobs referenced from run state via {@link BinaryStorage}.\n */\n@injectable()\nexport class WorkflowRunRetentionPruneScheduler {\n private timer: ReturnType<typeof setInterval> | undefined;\n private readonly logger: Logger;\n\n constructor(\n @inject(ApplicationTokens.Clock) private readonly clock: Clock,\n @inject(ApplicationTokens.WorkflowRunRepository) private readonly runs: WorkflowRunRepository,\n @inject(CoreTokens.BinaryStorage) private readonly binaryStorage: BinaryStorage,\n @inject(ApplicationTokens.AppConfig) private readonly appConfig: AppConfig,\n @inject(ServerLoggerFactory) loggerFactory: ServerLoggerFactory,\n ) {\n this.logger = loggerFactory.create(\"codemation.runRetentionPrune\");\n }\n\n start(): void {\n if (this.appConfig.env.CODEMATION_RUN_PRUNE_ENABLED === \"false\") {\n return;\n }\n if (this.timer) {\n return;\n }\n const intervalMs = Number(this.appConfig.env.CODEMATION_RUN_PRUNE_INTERVAL_MS ?? 60_000);\n this.timer = setInterval(() => {\n void this.runOnce().catch((error: unknown) => {\n this.logger.warn(`Run retention prune tick failed: ${error instanceof Error ? error.message : String(error)}`);\n });\n }, intervalMs);\n }\n\n stop(): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n }\n\n /** Exposed for tests; production path is the interval started by {@link start}. */\n async runOnce(): Promise<void> {\n this.logger.debug(\"Run retention prune: starting check\");\n const defaultRetentionSec = Number(this.appConfig.env.CODEMATION_RUN_RETENTION_DEFAULT_SECONDS ?? 86_400);\n const beforeIso = new Date(this.clock.now().getTime() - defaultRetentionSec * 1000).toISOString();\n const summaries = await this.runs.listRunsOlderThan?.({ beforeIso, limit: 500 });\n const candidates =\n summaries ??\n (await this.runs.listRuns({ limit: 500 })).filter(\n (summary) => summary.status === \"completed\" || summary.status === \"failed\",\n );\n\n let foundCount = 0;\n let prunedCount = 0;\n for (const candidate of candidates) {\n const runId = candidate.runId as RunId;\n const workflowId = candidate.workflowId as WorkflowId;\n foundCount += 1;\n\n const storageKeys =\n (await this.runs.listBinaryStorageKeys?.(runId)) ?? (await this.loadStorageKeysFromRunStateFallback(runId));\n for (const key of storageKeys) {\n await this.binaryStorage.delete(key);\n }\n await this.runs.deleteRun(runId);\n prunedCount += 1;\n this.logger.debug(`Run retention prune: pruned run ${runId} for workflow ${workflowId}`);\n }\n\n this.logger.info(`Run retention prune: found ${foundCount} run(s) to prune`);\n this.logger.info(`Run retention prune: pruned ${prunedCount} run(s)`);\n }\n\n private async loadStorageKeysFromRunStateFallback(runId: RunId): Promise<ReadonlyArray<string>> {\n const state = await this.runs.load(runId);\n if (!state) {\n return [];\n }\n const keys = new Set<string>();\n this.collectStorageKeysFromValue(state.outputsByNode, keys);\n this.collectStorageKeysFromValue(state.nodeSnapshotsByNodeId, keys);\n this.collectStorageKeysFromValue(state.mutableState, keys);\n return [...keys];\n }\n\n private collectStorageKeysFromValue(value: unknown, keys: Set<string>): void {\n if (Array.isArray(value)) {\n for (const entry of value) {\n this.collectStorageKeysFromValue(entry, keys);\n }\n return;\n }\n if (!value || typeof value !== \"object\") {\n return;\n }\n const record = value as Record<string, unknown>;\n if (\n typeof record.id === \"string\" &&\n typeof record.storageKey === \"string\" &&\n typeof record.mimeType === \"string\" &&\n typeof record.size === \"number\"\n ) {\n if (record.storageKey.length > 0) {\n keys.add(record.storageKey);\n }\n return;\n }\n for (const child of Object.values(record)) {\n this.collectStorageKeysFromValue(child, keys);\n }\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { i as PrismaClient } from "./AppConfigFactory-CiBPHleh.js";
1
+ import { i as PrismaClient } from "./AppConfigFactory-_fqSok1J.js";
2
2
 
3
3
  //#region src/infrastructure/persistence/CodemationPostgresPrismaClientFactory.d.ts
4
4
  declare class CodemationPostgresPrismaClientFactory {
@@ -6,4 +6,4 @@ declare class CodemationPostgresPrismaClientFactory {
6
6
  }
7
7
  //#endregion
8
8
  export { CodemationPostgresPrismaClientFactory as t };
9
- //# sourceMappingURL=persistenceServer-DL8yBGDU.d.ts.map
9
+ //# sourceMappingURL=persistenceServer-CLY4qtMo.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { i as __toESM } from "./chunk-7V6ThxGB.js";
2
- import { i as require_client } from "./AppConfigFactory-Ciz9YKWx.js";
2
+ import { i as require_client } from "./AppConfigFactory-ByT1D8dM.js";
3
3
  import { PrismaPg } from "@prisma/adapter-pg";
4
4
 
5
5
  //#region src/infrastructure/persistence/CodemationPostgresPrismaClientFactory.ts
@@ -12,4 +12,4 @@ var CodemationPostgresPrismaClientFactory = class {
12
12
 
13
13
  //#endregion
14
14
  export { CodemationPostgresPrismaClientFactory as t };
15
- //# sourceMappingURL=persistenceServer-CuAqL_fF.js.map
15
+ //# sourceMappingURL=persistenceServer-DMvIOGW8.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"persistenceServer-CuAqL_fF.js","names":["PrismaClient"],"sources":["../src/infrastructure/persistence/CodemationPostgresPrismaClientFactory.ts"],"sourcesContent":["import { PrismaPg } from \"@prisma/adapter-pg\";\nimport { PrismaClient } from \"./generated/prisma-postgresql-client/client.js\";\n\nexport class CodemationPostgresPrismaClientFactory {\n static create(databaseUrl: string): PrismaClient {\n const adapter = new PrismaPg({ connectionString: databaseUrl });\n return new PrismaClient({ adapter });\n }\n}\n"],"mappings":";;;;;;AAGA,IAAa,wCAAb,MAAmD;CACjD,OAAO,OAAO,aAAmC;AAE/C,SAAO,IAAIA,2BAAa,EAAE,SADV,IAAI,SAAS,EAAE,kBAAkB,aAAa,CAAC,EAC5B,CAAC"}
1
+ {"version":3,"file":"persistenceServer-DMvIOGW8.js","names":["PrismaClient"],"sources":["../src/infrastructure/persistence/CodemationPostgresPrismaClientFactory.ts"],"sourcesContent":["import { PrismaPg } from \"@prisma/adapter-pg\";\nimport { PrismaClient } from \"./generated/prisma-postgresql-client/client.js\";\n\nexport class CodemationPostgresPrismaClientFactory {\n static create(databaseUrl: string): PrismaClient {\n const adapter = new PrismaPg({ connectionString: databaseUrl });\n return new PrismaClient({ adapter });\n }\n}\n"],"mappings":";;;;;;AAGA,IAAa,wCAAb,MAAmD;CACjD,OAAO,OAAO,aAAmC;AAE/C,SAAO,IAAIA,2BAAa,EAAE,SADV,IAAI,SAAS,EAAE,kBAAkB,aAAa,CAAC,EAC5B,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import "./CodemationAuthConfig-7hEfICPf.js";
2
- import "./index-BYbzmUwS.js";
3
- import { _ as AppPersistenceConfig } from "./CodemationConfig-DfK1KLvO.js";
4
- import "./CodemationConfigNormalizer-BKgIOeLm.js";
5
- import { n as PrismaMigrationDeployer, r as PrismaDatabaseClient, t as AppConfigFactory } from "./AppConfigFactory-CiBPHleh.js";
6
- import { t as CodemationPostgresPrismaClientFactory } from "./persistenceServer-DL8yBGDU.js";
2
+ import "./index-CX752QE9.js";
3
+ import { _ as AppPersistenceConfig } from "./CodemationConfig-CNfytKR6.js";
4
+ import "./CodemationConfigNormalizer-BuKWVNEq.js";
5
+ import { n as PrismaMigrationDeployer, r as PrismaDatabaseClient, t as AppConfigFactory } from "./AppConfigFactory-_fqSok1J.js";
6
+ import { t as CodemationPostgresPrismaClientFactory } from "./persistenceServer-CLY4qtMo.js";
7
7
  export { AppConfigFactory, AppPersistenceConfig, CodemationPostgresPrismaClientFactory, PrismaDatabaseClient as PrismaClient, PrismaMigrationDeployer };
@@ -1,5 +1,5 @@
1
1
  import "./decorate-B0PP651O.js";
2
- import { r as PrismaMigrationDeployer, t as AppConfigFactory } from "./AppConfigFactory-Ciz9YKWx.js";
3
- import { t as CodemationPostgresPrismaClientFactory } from "./persistenceServer-CuAqL_fF.js";
2
+ import { r as PrismaMigrationDeployer, t as AppConfigFactory } from "./AppConfigFactory-ByT1D8dM.js";
3
+ import { t as CodemationPostgresPrismaClientFactory } from "./persistenceServer-DMvIOGW8.js";
4
4
 
5
5
  export { AppConfigFactory, CodemationPostgresPrismaClientFactory, PrismaMigrationDeployer };
@@ -1,7 +1,7 @@
1
1
  import { a as CodemationConfigNormalizer, t as CodemationConsumerConfigLoader } from "./CodemationConsumerConfigLoader-C_ISRrpI.js";
2
- import { u as ApplicationTokens } from "./CredentialServices-DNb3CZwW.js";
3
- import { C as GetWorkflowDetailQuery, S as GetWorkflowSummariesQuery, a as AppContainerLifecycle, b as WorkflowDefinitionMapper, f as CodemationHonoApiApp, r as FrontendRuntime, t as AppContainerFactory } from "./AppContainerFactory-DH88oxpg.js";
4
- import { n as CodemationPluginPackageMetadata, t as AppConfigFactory } from "./AppConfigFactory-Ciz9YKWx.js";
2
+ import { u as ApplicationTokens } from "./CredentialServices-xVxVA9Tq.js";
3
+ import { C as GetWorkflowDetailQuery, S as GetWorkflowSummariesQuery, a as AppContainerLifecycle, b as WorkflowDefinitionMapper, f as CodemationHonoApiApp, r as FrontendRuntime, t as AppContainerFactory } from "./AppContainerFactory-BRU02PTm.js";
4
+ import { n as CodemationPluginPackageMetadata, t as AppConfigFactory } from "./AppConfigFactory-ByT1D8dM.js";
5
5
  import { readFile, readdir } from "node:fs/promises";
6
6
  import path from "node:path";
7
7
  import { pathToFileURL } from "node:url";
@@ -219,4 +219,4 @@ var CodemationPluginDiscovery = class {
219
219
 
220
220
  //#endregion
221
221
  export { AppConfigLoader as n, CodemationServerGateway as r, CodemationPluginDiscovery as t };
222
- //# sourceMappingURL=server-EbxQft_X.js.map
222
+ //# sourceMappingURL=server-ChTCEc6R.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server-EbxQft_X.js","names":["config: CodemationConfig","consumerRoot: string","configSource?: string","workflowSources: ReadonlyArray<string>","env?: Readonly<NodeJS.ProcessEnv>","consumerConfigLoader: CodemationConsumerConfigLoader","appConfigFactory: AppConfigFactory","discoveredPackages: CodemationDiscoveredPluginPackage[]","resolvedPackages: CodemationResolvedPluginPackage[]","packageRoots: string[]"],"sources":["../src/presentation/http/CodemationServerGatewayFactory.ts","../src/presentation/server/AppConfigLoader.ts","../src/presentation/server/CodemationPluginDiscovery.ts"],"sourcesContent":["import { accessSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { QueryBus } from \"../../application/bus/QueryBus\";\nimport type { WorkflowDto, WorkflowSummary } from \"../../application/contracts/WorkflowViewContracts\";\nimport { WorkflowDefinitionMapper } from \"../../application/mapping/WorkflowDefinitionMapper\";\nimport { GetWorkflowDetailQuery } from \"../../application/queries/GetWorkflowDetailQuery\";\nimport { GetWorkflowSummariesQuery } from \"../../application/queries/GetWorkflowSummariesQuery\";\nimport { ApplicationTokens } from \"../../applicationTokens\";\nimport { AppContainerFactory } from \"../../bootstrap/AppContainerFactory\";\nimport { AppContainerLifecycle } from \"../../bootstrap/AppContainerLifecycle\";\nimport { FrontendRuntime } from \"../../bootstrap/runtime/FrontendRuntime\";\nimport { AppConfigFactory } from \"../../bootstrap/runtime/AppConfigFactory\";\nimport type { CodemationConfig } from \"../config/CodemationConfig\";\nimport { CodemationConfigNormalizer } from \"../config/CodemationConfigNormalizer\";\nimport { CodemationHonoApiApp } from \"./hono/CodemationHonoApiAppFactory\";\n\ntype ServerGatewayContext = Readonly<{\n container: import(\"@codemation/core\").Container;\n httpApi: CodemationHonoApiApp;\n queryBus: QueryBus;\n workflowDefinitionMapper: WorkflowDefinitionMapper;\n}>;\n\nexport class CodemationServerGateway {\n private static readonly contextsByConfig = new WeakMap<object, Promise<ServerGatewayContext>>();\n\n constructor(\n private readonly config: CodemationConfig,\n private readonly consumerRoot: string,\n private readonly configSource?: string,\n private readonly workflowSources: ReadonlyArray<string> = [],\n private readonly env?: Readonly<NodeJS.ProcessEnv>,\n ) {}\n\n async dispatch(request: Request): Promise<Response> {\n return await (await this.getContext()).httpApi.fetch(request);\n }\n\n async prepare(): Promise<void> {\n await this.getContext();\n }\n\n async close(): Promise<void> {\n const cachedContext = CodemationServerGateway.contextsByConfig.get(this.config as object);\n if (!cachedContext) {\n return;\n }\n CodemationServerGateway.contextsByConfig.delete(this.config as object);\n await (await cachedContext).container.resolve(AppContainerLifecycle).stop();\n }\n\n async loadWorkflowSummaries(): Promise<ReadonlyArray<WorkflowSummary>> {\n const context = await this.getContext();\n const workflows = await context.queryBus.execute(new GetWorkflowSummariesQuery());\n return workflows.map((workflow) => context.workflowDefinitionMapper.toSummary(workflow));\n }\n\n async loadWorkflowDetail(workflowId: string): Promise<WorkflowDto> {\n const context = await this.getContext();\n const workflow = await context.queryBus.execute(new GetWorkflowDetailQuery(workflowId));\n if (!workflow) {\n throw new Error(`Unknown workflowId: ${workflowId}`);\n }\n return await context.workflowDefinitionMapper.map(workflow);\n }\n\n private getContext(): Promise<ServerGatewayContext> {\n const cachedContext = CodemationServerGateway.contextsByConfig.get(this.config as object);\n if (cachedContext) {\n return cachedContext;\n }\n const nextContext = this.createContext();\n CodemationServerGateway.contextsByConfig.set(this.config as object, nextContext);\n return nextContext;\n }\n\n private async createContext(): Promise<ServerGatewayContext> {\n const repoRoot = this.detectWorkspaceRoot(this.consumerRoot);\n // This gateway is the config/env boundary that materializes AppConfig from raw inputs.\n // eslint-disable-next-line no-restricted-properties\n const env = this.env ?? process.env;\n const appConfig = new AppConfigFactory().create({\n repoRoot,\n consumerRoot: this.consumerRoot,\n env,\n config: new CodemationConfigNormalizer().normalize(this.config),\n workflowSources: this.resolveWorkflowSources(),\n });\n const container = await new AppContainerFactory().create({\n appConfig,\n sharedWorkflowWebsocketServer: null,\n });\n await container.resolve(FrontendRuntime).start();\n return {\n container,\n httpApi: container.resolve(CodemationHonoApiApp),\n queryBus: container.resolve(ApplicationTokens.QueryBus),\n workflowDefinitionMapper: container.resolve(WorkflowDefinitionMapper),\n };\n }\n\n private resolveWorkflowSources(): ReadonlyArray<string> {\n if (this.workflowSources.length > 0) {\n return [...this.workflowSources];\n }\n if (!this.configSource || !this.config.workflows || this.config.workflows.length === 0) {\n return [];\n }\n return [this.configSource];\n }\n private detectWorkspaceRoot(startDirectory: string): string {\n let currentDirectory = path.resolve(startDirectory);\n while (true) {\n try {\n accessSync(path.resolve(currentDirectory, \"pnpm-workspace.yaml\"));\n return currentDirectory;\n } catch {\n const parentDirectory = path.dirname(currentDirectory);\n if (parentDirectory === currentDirectory) {\n return startDirectory;\n }\n currentDirectory = parentDirectory;\n }\n }\n }\n}\n","import type { AppConfig } from \"../config/AppConfig\";\nimport { CodemationConsumerConfigLoader } from \"./CodemationConsumerConfigLoader\";\nimport { AppConfigFactory } from \"../../bootstrap/runtime/AppConfigFactory\";\n\nexport type AppConfigLoadResult = Readonly<{\n appConfig: AppConfig;\n bootstrapSource: string | null;\n}>;\n\nexport class AppConfigLoader {\n constructor(\n private readonly consumerConfigLoader: CodemationConsumerConfigLoader = new CodemationConsumerConfigLoader(),\n private readonly appConfigFactory: AppConfigFactory = new AppConfigFactory(),\n ) {}\n\n async load(\n args: Readonly<{\n consumerRoot: string;\n repoRoot: string;\n env: NodeJS.ProcessEnv;\n configPathOverride?: string;\n }>,\n ): Promise<AppConfigLoadResult> {\n const resolution = await this.consumerConfigLoader.load({\n consumerRoot: args.consumerRoot,\n configPathOverride: args.configPathOverride,\n });\n return {\n appConfig: this.appConfigFactory.create({\n repoRoot: args.repoRoot,\n consumerRoot: args.consumerRoot,\n env: args.env,\n config: resolution.config,\n workflowSources: resolution.workflowSources,\n }),\n bootstrapSource: resolution.bootstrapSource,\n };\n }\n}\n","import type { CodemationPackageManifest } from \"../config/CodemationPackageManifest\";\nimport { CodemationPluginPackageMetadata, type CodemationPlugin } from \"../config/CodemationPlugin\";\nimport { readFile, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nexport type CodemationDiscoveredPluginPackage = Readonly<{\n packageName: string;\n packageRoot: string;\n pluginEntry: string;\n developmentEntry?: string;\n}>;\n\nexport type CodemationResolvedPluginPackage = Readonly<\n CodemationDiscoveredPluginPackage & {\n plugin: CodemationPlugin;\n }\n>;\n\ntype PackageJsonShape = Readonly<{\n codemation?: CodemationPackageManifest;\n name?: string;\n exports?: Readonly<Record<string, unknown>>;\n}>;\n\nexport class CodemationPluginDiscovery {\n private readonly pluginPackageMetadata = new CodemationPluginPackageMetadata();\n\n async discover(consumerRoot: string): Promise<ReadonlyArray<CodemationDiscoveredPluginPackage>> {\n const nodeModulesRoot = path.resolve(consumerRoot, \"node_modules\");\n const packageRoots = await this.collectPackageRoots(nodeModulesRoot);\n const discoveredPackages: CodemationDiscoveredPluginPackage[] = [];\n for (const packageRoot of packageRoots) {\n const packageJson = await this.readPackageJson(path.resolve(packageRoot, \"package.json\"));\n const pluginManifest = packageJson.codemation?.plugin;\n if (!packageJson.name || typeof pluginManifest !== \"string\" || pluginManifest.trim().length === 0) {\n continue;\n }\n discoveredPackages.push({\n packageName: packageJson.name,\n packageRoot,\n pluginEntry: pluginManifest,\n developmentEntry: await this.resolveDevelopmentPluginEntry(packageRoot),\n });\n }\n return discoveredPackages.sort((left, right) => left.packageName.localeCompare(right.packageName));\n }\n\n async resolvePlugins(consumerRoot: string): Promise<ReadonlyArray<CodemationResolvedPluginPackage>> {\n const discoveredPackages = await this.discover(consumerRoot);\n return await this.resolveDiscoveredPackages(discoveredPackages);\n }\n\n async resolveDiscoveredPackages(\n discoveredPackages: ReadonlyArray<CodemationDiscoveredPluginPackage>,\n ): Promise<ReadonlyArray<CodemationResolvedPluginPackage>> {\n const resolvedPackages: CodemationResolvedPluginPackage[] = [];\n for (const discoveredPackage of discoveredPackages) {\n resolvedPackages.push({\n ...discoveredPackage,\n plugin: await this.loadPlugin(discoveredPackage),\n });\n }\n return resolvedPackages;\n }\n\n private async collectPackageRoots(nodeModulesRoot: string): Promise<ReadonlyArray<string>> {\n try {\n const entries = await readdir(nodeModulesRoot, { withFileTypes: true });\n const packageRoots: string[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory() && !entry.isSymbolicLink()) {\n continue;\n }\n if (entry.name.startsWith(\"@\")) {\n const scopedEntries = await readdir(path.resolve(nodeModulesRoot, entry.name), { withFileTypes: true });\n for (const scopedEntry of scopedEntries) {\n if (scopedEntry.isDirectory() || scopedEntry.isSymbolicLink()) {\n packageRoots.push(path.resolve(nodeModulesRoot, entry.name, scopedEntry.name));\n }\n }\n continue;\n }\n packageRoots.push(path.resolve(nodeModulesRoot, entry.name));\n }\n return packageRoots;\n } catch {\n return [];\n }\n }\n\n private async readPackageJson(packageJsonPath: string): Promise<PackageJsonShape> {\n try {\n const rawPackageJson = await readFile(packageJsonPath, \"utf8\");\n return JSON.parse(rawPackageJson) as PackageJsonShape;\n } catch {\n return {};\n }\n }\n\n private async loadPlugin(discoveredPackage: CodemationDiscoveredPluginPackage): Promise<CodemationPlugin> {\n const pluginModulePath = path.resolve(discoveredPackage.packageRoot, this.resolvePluginEntry(discoveredPackage));\n const importedModule = (await import(\n /* webpackIgnore: true */ this.resolvePluginModuleSpecifier(pluginModulePath)\n )) as Record<string, unknown>;\n const exportedValue = importedModule.default;\n const plugin = this.resolvePluginValue(exportedValue);\n if (!plugin) {\n throw new Error(`Plugin package \"${discoveredPackage.packageName}\" did not default-export a Codemation plugin.`);\n }\n return this.pluginPackageMetadata.attachPackageName(plugin, discoveredPackage.packageName);\n }\n\n private resolvePluginValue(value: unknown): CodemationPlugin | null {\n if (this.isPluginConfig(value)) {\n return value;\n }\n return null;\n }\n\n private isPluginConfig(value: unknown): value is CodemationPlugin {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return false;\n }\n const pluginValue = value as {\n credentialTypes?: unknown;\n register?: unknown;\n sandbox?: unknown;\n };\n if (pluginValue.register !== undefined && typeof pluginValue.register !== \"function\") {\n return false;\n }\n if (pluginValue.credentialTypes !== undefined && !Array.isArray(pluginValue.credentialTypes)) {\n return false;\n }\n return (\n pluginValue.register !== undefined ||\n pluginValue.credentialTypes !== undefined ||\n pluginValue.sandbox !== undefined ||\n Object.keys(pluginValue).length === 0\n );\n }\n\n private resolvePluginEntry(discoveredPackage: CodemationDiscoveredPluginPackage): string {\n if (\n process.env.CODEMATION_PREFER_PLUGIN_SOURCE_ENTRY === \"true\" &&\n typeof discoveredPackage.developmentEntry === \"string\" &&\n discoveredPackage.developmentEntry.trim().length > 0\n ) {\n return discoveredPackage.developmentEntry;\n }\n return discoveredPackage.pluginEntry;\n }\n\n private async resolveDevelopmentPluginEntry(packageRoot: string): Promise<string | undefined> {\n const candidates = [\n path.resolve(packageRoot, \"codemation.plugin.ts\"),\n path.resolve(packageRoot, \"codemation.plugin.js\"),\n path.resolve(packageRoot, \"src\", \"codemation.plugin.ts\"),\n path.resolve(packageRoot, \"src\", \"codemation.plugin.js\"),\n ];\n for (const candidate of candidates) {\n if (await this.exists(candidate)) {\n return path.relative(packageRoot, candidate);\n }\n }\n return undefined;\n }\n\n private async exists(filePath: string): Promise<boolean> {\n try {\n await readFile(filePath, \"utf8\");\n return true;\n } catch {\n return false;\n }\n }\n\n private resolvePluginModuleSpecifier(pluginModulePath: string): string {\n return pathToFileURL(pluginModulePath).href;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"server-ChTCEc6R.js","names":["config: CodemationConfig","consumerRoot: string","configSource?: string","workflowSources: ReadonlyArray<string>","env?: Readonly<NodeJS.ProcessEnv>","consumerConfigLoader: CodemationConsumerConfigLoader","appConfigFactory: AppConfigFactory","discoveredPackages: CodemationDiscoveredPluginPackage[]","resolvedPackages: CodemationResolvedPluginPackage[]","packageRoots: string[]"],"sources":["../src/presentation/http/CodemationServerGatewayFactory.ts","../src/presentation/server/AppConfigLoader.ts","../src/presentation/server/CodemationPluginDiscovery.ts"],"sourcesContent":["import { accessSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { QueryBus } from \"../../application/bus/QueryBus\";\nimport type { WorkflowDto, WorkflowSummary } from \"../../application/contracts/WorkflowViewContracts\";\nimport { WorkflowDefinitionMapper } from \"../../application/mapping/WorkflowDefinitionMapper\";\nimport { GetWorkflowDetailQuery } from \"../../application/queries/GetWorkflowDetailQuery\";\nimport { GetWorkflowSummariesQuery } from \"../../application/queries/GetWorkflowSummariesQuery\";\nimport { ApplicationTokens } from \"../../applicationTokens\";\nimport { AppContainerFactory } from \"../../bootstrap/AppContainerFactory\";\nimport { AppContainerLifecycle } from \"../../bootstrap/AppContainerLifecycle\";\nimport { FrontendRuntime } from \"../../bootstrap/runtime/FrontendRuntime\";\nimport { AppConfigFactory } from \"../../bootstrap/runtime/AppConfigFactory\";\nimport type { CodemationConfig } from \"../config/CodemationConfig\";\nimport { CodemationConfigNormalizer } from \"../config/CodemationConfigNormalizer\";\nimport { CodemationHonoApiApp } from \"./hono/CodemationHonoApiAppFactory\";\n\ntype ServerGatewayContext = Readonly<{\n container: import(\"@codemation/core\").Container;\n httpApi: CodemationHonoApiApp;\n queryBus: QueryBus;\n workflowDefinitionMapper: WorkflowDefinitionMapper;\n}>;\n\nexport class CodemationServerGateway {\n private static readonly contextsByConfig = new WeakMap<object, Promise<ServerGatewayContext>>();\n\n constructor(\n private readonly config: CodemationConfig,\n private readonly consumerRoot: string,\n private readonly configSource?: string,\n private readonly workflowSources: ReadonlyArray<string> = [],\n private readonly env?: Readonly<NodeJS.ProcessEnv>,\n ) {}\n\n async dispatch(request: Request): Promise<Response> {\n return await (await this.getContext()).httpApi.fetch(request);\n }\n\n async prepare(): Promise<void> {\n await this.getContext();\n }\n\n async close(): Promise<void> {\n const cachedContext = CodemationServerGateway.contextsByConfig.get(this.config as object);\n if (!cachedContext) {\n return;\n }\n CodemationServerGateway.contextsByConfig.delete(this.config as object);\n await (await cachedContext).container.resolve(AppContainerLifecycle).stop();\n }\n\n async loadWorkflowSummaries(): Promise<ReadonlyArray<WorkflowSummary>> {\n const context = await this.getContext();\n const workflows = await context.queryBus.execute(new GetWorkflowSummariesQuery());\n return workflows.map((workflow) => context.workflowDefinitionMapper.toSummary(workflow));\n }\n\n async loadWorkflowDetail(workflowId: string): Promise<WorkflowDto> {\n const context = await this.getContext();\n const workflow = await context.queryBus.execute(new GetWorkflowDetailQuery(workflowId));\n if (!workflow) {\n throw new Error(`Unknown workflowId: ${workflowId}`);\n }\n return await context.workflowDefinitionMapper.map(workflow);\n }\n\n private getContext(): Promise<ServerGatewayContext> {\n const cachedContext = CodemationServerGateway.contextsByConfig.get(this.config as object);\n if (cachedContext) {\n return cachedContext;\n }\n const nextContext = this.createContext();\n CodemationServerGateway.contextsByConfig.set(this.config as object, nextContext);\n return nextContext;\n }\n\n private async createContext(): Promise<ServerGatewayContext> {\n const repoRoot = this.detectWorkspaceRoot(this.consumerRoot);\n // This gateway is the config/env boundary that materializes AppConfig from raw inputs.\n // eslint-disable-next-line no-restricted-properties\n const env = this.env ?? process.env;\n const appConfig = new AppConfigFactory().create({\n repoRoot,\n consumerRoot: this.consumerRoot,\n env,\n config: new CodemationConfigNormalizer().normalize(this.config),\n workflowSources: this.resolveWorkflowSources(),\n });\n const container = await new AppContainerFactory().create({\n appConfig,\n sharedWorkflowWebsocketServer: null,\n });\n await container.resolve(FrontendRuntime).start();\n return {\n container,\n httpApi: container.resolve(CodemationHonoApiApp),\n queryBus: container.resolve(ApplicationTokens.QueryBus),\n workflowDefinitionMapper: container.resolve(WorkflowDefinitionMapper),\n };\n }\n\n private resolveWorkflowSources(): ReadonlyArray<string> {\n if (this.workflowSources.length > 0) {\n return [...this.workflowSources];\n }\n if (!this.configSource || !this.config.workflows || this.config.workflows.length === 0) {\n return [];\n }\n return [this.configSource];\n }\n private detectWorkspaceRoot(startDirectory: string): string {\n let currentDirectory = path.resolve(startDirectory);\n while (true) {\n try {\n accessSync(path.resolve(currentDirectory, \"pnpm-workspace.yaml\"));\n return currentDirectory;\n } catch {\n const parentDirectory = path.dirname(currentDirectory);\n if (parentDirectory === currentDirectory) {\n return startDirectory;\n }\n currentDirectory = parentDirectory;\n }\n }\n }\n}\n","import type { AppConfig } from \"../config/AppConfig\";\nimport { CodemationConsumerConfigLoader } from \"./CodemationConsumerConfigLoader\";\nimport { AppConfigFactory } from \"../../bootstrap/runtime/AppConfigFactory\";\n\nexport type AppConfigLoadResult = Readonly<{\n appConfig: AppConfig;\n bootstrapSource: string | null;\n}>;\n\nexport class AppConfigLoader {\n constructor(\n private readonly consumerConfigLoader: CodemationConsumerConfigLoader = new CodemationConsumerConfigLoader(),\n private readonly appConfigFactory: AppConfigFactory = new AppConfigFactory(),\n ) {}\n\n async load(\n args: Readonly<{\n consumerRoot: string;\n repoRoot: string;\n env: NodeJS.ProcessEnv;\n configPathOverride?: string;\n }>,\n ): Promise<AppConfigLoadResult> {\n const resolution = await this.consumerConfigLoader.load({\n consumerRoot: args.consumerRoot,\n configPathOverride: args.configPathOverride,\n });\n return {\n appConfig: this.appConfigFactory.create({\n repoRoot: args.repoRoot,\n consumerRoot: args.consumerRoot,\n env: args.env,\n config: resolution.config,\n workflowSources: resolution.workflowSources,\n }),\n bootstrapSource: resolution.bootstrapSource,\n };\n }\n}\n","import type { CodemationPackageManifest } from \"../config/CodemationPackageManifest\";\nimport { CodemationPluginPackageMetadata, type CodemationPlugin } from \"../config/CodemationPlugin\";\nimport { readFile, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nexport type CodemationDiscoveredPluginPackage = Readonly<{\n packageName: string;\n packageRoot: string;\n pluginEntry: string;\n developmentEntry?: string;\n}>;\n\nexport type CodemationResolvedPluginPackage = Readonly<\n CodemationDiscoveredPluginPackage & {\n plugin: CodemationPlugin;\n }\n>;\n\ntype PackageJsonShape = Readonly<{\n codemation?: CodemationPackageManifest;\n name?: string;\n exports?: Readonly<Record<string, unknown>>;\n}>;\n\nexport class CodemationPluginDiscovery {\n private readonly pluginPackageMetadata = new CodemationPluginPackageMetadata();\n\n async discover(consumerRoot: string): Promise<ReadonlyArray<CodemationDiscoveredPluginPackage>> {\n const nodeModulesRoot = path.resolve(consumerRoot, \"node_modules\");\n const packageRoots = await this.collectPackageRoots(nodeModulesRoot);\n const discoveredPackages: CodemationDiscoveredPluginPackage[] = [];\n for (const packageRoot of packageRoots) {\n const packageJson = await this.readPackageJson(path.resolve(packageRoot, \"package.json\"));\n const pluginManifest = packageJson.codemation?.plugin;\n if (!packageJson.name || typeof pluginManifest !== \"string\" || pluginManifest.trim().length === 0) {\n continue;\n }\n discoveredPackages.push({\n packageName: packageJson.name,\n packageRoot,\n pluginEntry: pluginManifest,\n developmentEntry: await this.resolveDevelopmentPluginEntry(packageRoot),\n });\n }\n return discoveredPackages.sort((left, right) => left.packageName.localeCompare(right.packageName));\n }\n\n async resolvePlugins(consumerRoot: string): Promise<ReadonlyArray<CodemationResolvedPluginPackage>> {\n const discoveredPackages = await this.discover(consumerRoot);\n return await this.resolveDiscoveredPackages(discoveredPackages);\n }\n\n async resolveDiscoveredPackages(\n discoveredPackages: ReadonlyArray<CodemationDiscoveredPluginPackage>,\n ): Promise<ReadonlyArray<CodemationResolvedPluginPackage>> {\n const resolvedPackages: CodemationResolvedPluginPackage[] = [];\n for (const discoveredPackage of discoveredPackages) {\n resolvedPackages.push({\n ...discoveredPackage,\n plugin: await this.loadPlugin(discoveredPackage),\n });\n }\n return resolvedPackages;\n }\n\n private async collectPackageRoots(nodeModulesRoot: string): Promise<ReadonlyArray<string>> {\n try {\n const entries = await readdir(nodeModulesRoot, { withFileTypes: true });\n const packageRoots: string[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory() && !entry.isSymbolicLink()) {\n continue;\n }\n if (entry.name.startsWith(\"@\")) {\n const scopedEntries = await readdir(path.resolve(nodeModulesRoot, entry.name), { withFileTypes: true });\n for (const scopedEntry of scopedEntries) {\n if (scopedEntry.isDirectory() || scopedEntry.isSymbolicLink()) {\n packageRoots.push(path.resolve(nodeModulesRoot, entry.name, scopedEntry.name));\n }\n }\n continue;\n }\n packageRoots.push(path.resolve(nodeModulesRoot, entry.name));\n }\n return packageRoots;\n } catch {\n return [];\n }\n }\n\n private async readPackageJson(packageJsonPath: string): Promise<PackageJsonShape> {\n try {\n const rawPackageJson = await readFile(packageJsonPath, \"utf8\");\n return JSON.parse(rawPackageJson) as PackageJsonShape;\n } catch {\n return {};\n }\n }\n\n private async loadPlugin(discoveredPackage: CodemationDiscoveredPluginPackage): Promise<CodemationPlugin> {\n const pluginModulePath = path.resolve(discoveredPackage.packageRoot, this.resolvePluginEntry(discoveredPackage));\n const importedModule = (await import(\n /* webpackIgnore: true */ this.resolvePluginModuleSpecifier(pluginModulePath)\n )) as Record<string, unknown>;\n const exportedValue = importedModule.default;\n const plugin = this.resolvePluginValue(exportedValue);\n if (!plugin) {\n throw new Error(`Plugin package \"${discoveredPackage.packageName}\" did not default-export a Codemation plugin.`);\n }\n return this.pluginPackageMetadata.attachPackageName(plugin, discoveredPackage.packageName);\n }\n\n private resolvePluginValue(value: unknown): CodemationPlugin | null {\n if (this.isPluginConfig(value)) {\n return value;\n }\n return null;\n }\n\n private isPluginConfig(value: unknown): value is CodemationPlugin {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return false;\n }\n const pluginValue = value as {\n credentialTypes?: unknown;\n register?: unknown;\n sandbox?: unknown;\n };\n if (pluginValue.register !== undefined && typeof pluginValue.register !== \"function\") {\n return false;\n }\n if (pluginValue.credentialTypes !== undefined && !Array.isArray(pluginValue.credentialTypes)) {\n return false;\n }\n return (\n pluginValue.register !== undefined ||\n pluginValue.credentialTypes !== undefined ||\n pluginValue.sandbox !== undefined ||\n Object.keys(pluginValue).length === 0\n );\n }\n\n private resolvePluginEntry(discoveredPackage: CodemationDiscoveredPluginPackage): string {\n if (\n process.env.CODEMATION_PREFER_PLUGIN_SOURCE_ENTRY === \"true\" &&\n typeof discoveredPackage.developmentEntry === \"string\" &&\n discoveredPackage.developmentEntry.trim().length > 0\n ) {\n return discoveredPackage.developmentEntry;\n }\n return discoveredPackage.pluginEntry;\n }\n\n private async resolveDevelopmentPluginEntry(packageRoot: string): Promise<string | undefined> {\n const candidates = [\n path.resolve(packageRoot, \"codemation.plugin.ts\"),\n path.resolve(packageRoot, \"codemation.plugin.js\"),\n path.resolve(packageRoot, \"src\", \"codemation.plugin.ts\"),\n path.resolve(packageRoot, \"src\", \"codemation.plugin.js\"),\n ];\n for (const candidate of candidates) {\n if (await this.exists(candidate)) {\n return path.relative(packageRoot, candidate);\n }\n }\n return undefined;\n }\n\n private async exists(filePath: string): Promise<boolean> {\n try {\n await readFile(filePath, \"utf8\");\n return true;\n } catch {\n return false;\n }\n }\n\n private resolvePluginModuleSpecifier(pluginModulePath: string): string {\n return pathToFileURL(pluginModulePath).href;\n }\n}\n"],"mappings":"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"}