@boboddy/sdk 0.3.1 → 0.4.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.
@@ -13135,7 +13135,7 @@ class StepExecutions extends HeyApiClient {
13135
13135
  class PipelineDefinitions extends HeyApiClient {
13136
13136
  createPipelineDefinition(options) {
13137
13137
  return (options.client ?? this.client).post({
13138
- url: "/api/linear-pipeline-definitions",
13138
+ url: "/api/pipeline-definitions",
13139
13139
  ...options,
13140
13140
  headers: {
13141
13141
  "Content-Type": "application/json",
@@ -13145,7 +13145,7 @@ class PipelineDefinitions extends HeyApiClient {
13145
13145
  }
13146
13146
  upsertPipelineDefinition(options) {
13147
13147
  return (options.client ?? this.client).put({
13148
- url: "/api/linear-pipeline-definitions",
13148
+ url: "/api/pipeline-definitions",
13149
13149
  ...options,
13150
13150
  headers: {
13151
13151
  "Content-Type": "application/json",
@@ -13154,14 +13154,14 @@ class PipelineDefinitions extends HeyApiClient {
13154
13154
  });
13155
13155
  }
13156
13156
  archivePipelineDefinition(options) {
13157
- return (options.client ?? this.client).put({ url: "/api/linear-pipeline-definitions/{linearPipelineDefinitionId}/archive", ...options });
13157
+ return (options.client ?? this.client).put({ url: "/api/pipeline-definitions/{pipelineDefinitionId}/archive", ...options });
13158
13158
  }
13159
13159
  unarchivePipelineDefinition(options) {
13160
- return (options.client ?? this.client).put({ url: "/api/linear-pipeline-definitions/{linearPipelineDefinitionId}/unarchive", ...options });
13160
+ return (options.client ?? this.client).put({ url: "/api/pipeline-definitions/{pipelineDefinitionId}/unarchive", ...options });
13161
13161
  }
13162
13162
  addPipelineStep(options) {
13163
13163
  return (options.client ?? this.client).post({
13164
- url: "/api/linear-pipeline-definitions/{linearPipelineDefinitionId}/steps",
13164
+ url: "/api/pipeline-definitions/{pipelineDefinitionId}/steps",
13165
13165
  ...options,
13166
13166
  headers: {
13167
13167
  "Content-Type": "application/json",
@@ -13170,11 +13170,11 @@ class PipelineDefinitions extends HeyApiClient {
13170
13170
  });
13171
13171
  }
13172
13172
  removePipelineStep(options) {
13173
- return (options.client ?? this.client).delete({ url: "/api/linear-pipeline-definitions/{linearPipelineDefinitionId}/steps/{linearPipelineStepDefinitionId}", ...options });
13173
+ return (options.client ?? this.client).delete({ url: "/api/pipeline-definitions/{pipelineDefinitionId}/steps/{pipelineStepDefinitionId}", ...options });
13174
13174
  }
13175
13175
  updatePipelineStep(options) {
13176
13176
  return (options.client ?? this.client).put({
13177
- url: "/api/linear-pipeline-definitions/{linearPipelineDefinitionId}/steps/{linearPipelineStepDefinitionId}",
13177
+ url: "/api/pipeline-definitions/{pipelineDefinitionId}/steps/{pipelineStepDefinitionId}",
13178
13178
  ...options,
13179
13179
  headers: {
13180
13180
  "Content-Type": "application/json",
@@ -13184,7 +13184,7 @@ class PipelineDefinitions extends HeyApiClient {
13184
13184
  }
13185
13185
  setPipelineStepAdvancementPolicy(options) {
13186
13186
  return (options.client ?? this.client).put({
13187
- url: "/api/linear-pipeline-definitions/{linearPipelineDefinitionId}/steps/{linearPipelineStepDefinitionId}/advancement-policy",
13187
+ url: "/api/pipeline-definitions/{pipelineDefinitionId}/steps/{pipelineStepDefinitionId}/advancement-policy",
13188
13188
  ...options,
13189
13189
  headers: {
13190
13190
  "Content-Type": "application/json",
@@ -13193,20 +13193,20 @@ class PipelineDefinitions extends HeyApiClient {
13193
13193
  });
13194
13194
  }
13195
13195
  getPipelineDefinition(options) {
13196
- return (options.client ?? this.client).get({ url: "/api/linear-pipeline-definitions/{linearPipelineDefinitionId}", ...options });
13196
+ return (options.client ?? this.client).get({ url: "/api/pipeline-definitions/{pipelineDefinitionId}", ...options });
13197
13197
  }
13198
13198
  listPipelineDefinitions(options) {
13199
- return (options.client ?? this.client).get({ url: "/api/projects/{projectId}/linear-pipeline-definitions", ...options });
13199
+ return (options.client ?? this.client).get({ url: "/api/projects/{projectId}/pipeline-definitions", ...options });
13200
13200
  }
13201
13201
  }
13202
13202
 
13203
13203
  class PipelineExecutions extends HeyApiClient {
13204
13204
  listPipelineExecutions(options) {
13205
- return (options.client ?? this.client).get({ url: "/api/linear-pipeline-executions", ...options });
13205
+ return (options.client ?? this.client).get({ url: "/api/pipeline-executions", ...options });
13206
13206
  }
13207
13207
  createPipelineExecution(options) {
13208
13208
  return (options.client ?? this.client).post({
13209
- url: "/api/linear-pipeline-executions",
13209
+ url: "/api/pipeline-executions",
13210
13210
  ...options,
13211
13211
  headers: {
13212
13212
  "Content-Type": "application/json",
@@ -13215,17 +13215,17 @@ class PipelineExecutions extends HeyApiClient {
13215
13215
  });
13216
13216
  }
13217
13217
  startPipelineExecution(options) {
13218
- return (options.client ?? this.client).put({ url: "/api/linear-pipeline-executions/{linearPipelineExecutionId}/start", ...options });
13218
+ return (options.client ?? this.client).put({ url: "/api/pipeline-executions/{pipelineExecutionId}/start", ...options });
13219
13219
  }
13220
13220
  queueFirstPipelineStepRun(options) {
13221
- return (options.client ?? this.client).post({ url: "/api/linear-pipeline-executions/{linearPipelineExecutionId}/step-runs/first", ...options });
13221
+ return (options.client ?? this.client).post({ url: "/api/pipeline-executions/{pipelineExecutionId}/step-runs/first", ...options });
13222
13222
  }
13223
13223
  markPipelineStepRunRunning(options) {
13224
- return (options.client ?? this.client).put({ url: "/api/linear-pipeline-executions/{linearPipelineExecutionId}/step-runs/{linearPipelineStepRunId}/running", ...options });
13224
+ return (options.client ?? this.client).put({ url: "/api/pipeline-executions/{pipelineExecutionId}/step-runs/{pipelineStepRunId}/running", ...options });
13225
13225
  }
13226
13226
  applyPipelineStepResult(options) {
13227
13227
  return (options.client ?? this.client).post({
13228
- url: "/api/linear-pipeline-executions/{linearPipelineExecutionId}/step-runs/{linearPipelineStepRunId}/results",
13228
+ url: "/api/pipeline-executions/{pipelineExecutionId}/step-runs/{pipelineStepRunId}/results",
13229
13229
  ...options,
13230
13230
  headers: {
13231
13231
  "Content-Type": "application/json",
@@ -13235,7 +13235,17 @@ class PipelineExecutions extends HeyApiClient {
13235
13235
  }
13236
13236
  acceptPipelineStepRun(options) {
13237
13237
  return (options.client ?? this.client).post({
13238
- url: "/api/linear-pipeline-executions/{linearPipelineExecutionId}/step-runs/{linearPipelineStepRunId}/accept",
13238
+ url: "/api/pipeline-executions/{pipelineExecutionId}/step-runs/{pipelineStepRunId}/accept",
13239
+ ...options,
13240
+ headers: {
13241
+ "Content-Type": "application/json",
13242
+ ...options.headers
13243
+ }
13244
+ });
13245
+ }
13246
+ acceptPipelineCohort(options) {
13247
+ return (options.client ?? this.client).post({
13248
+ url: "/api/pipeline-executions/{pipelineExecutionId}/cohorts/{originNodeDefinitionId}/accept",
13239
13249
  ...options,
13240
13250
  headers: {
13241
13251
  "Content-Type": "application/json",
@@ -13245,7 +13255,7 @@ class PipelineExecutions extends HeyApiClient {
13245
13255
  }
13246
13256
  rerunPipelineExecution(options) {
13247
13257
  return (options.client ?? this.client).post({
13248
- url: "/api/linear-pipeline-executions/{linearPipelineExecutionId}/rerun",
13258
+ url: "/api/pipeline-executions/{pipelineExecutionId}/rerun",
13249
13259
  ...options,
13250
13260
  headers: {
13251
13261
  "Content-Type": "application/json",
@@ -13254,19 +13264,22 @@ class PipelineExecutions extends HeyApiClient {
13254
13264
  });
13255
13265
  }
13256
13266
  cancelPipelineExecution(options) {
13257
- return (options.client ?? this.client).put({ url: "/api/linear-pipeline-executions/{linearPipelineExecutionId}/cancel", ...options });
13267
+ return (options.client ?? this.client).put({ url: "/api/pipeline-executions/{pipelineExecutionId}/cancel", ...options });
13258
13268
  }
13259
13269
  getPipelineExecution(options) {
13260
- return (options.client ?? this.client).get({ url: "/api/linear-pipeline-executions/{linearPipelineExecutionId}", ...options });
13270
+ return (options.client ?? this.client).get({ url: "/api/pipeline-executions/{pipelineExecutionId}", ...options });
13271
+ }
13272
+ getPipelineExecutionRoutedChain(options) {
13273
+ return (options.client ?? this.client).get({ url: "/api/pipeline-executions/{pipelineExecutionId}/routed-chain", ...options });
13261
13274
  }
13262
13275
  countPipelineExecutionsByPipeline(options) {
13263
- return (options.client ?? this.client).get({ url: "/api/linear-pipeline-executions/counts/by-pipeline", ...options });
13276
+ return (options.client ?? this.client).get({ url: "/api/pipeline-executions/counts/by-pipeline", ...options });
13264
13277
  }
13265
13278
  listPipelineDefinitionStepRollups(options) {
13266
- return (options.client ?? this.client).get({ url: "/api/linear-pipeline-executions/step-rollups/by-definition/{linearPipelineDefinitionId}", ...options });
13279
+ return (options.client ?? this.client).get({ url: "/api/pipeline-executions/step-rollups/by-definition/{pipelineDefinitionId}", ...options });
13267
13280
  }
13268
13281
  listPipelineDefinitionStepRuns(options) {
13269
- return (options.client ?? this.client).get({ url: "/api/linear-pipeline-executions/step-runs/by-definition/{linearPipelineDefinitionId}", ...options });
13282
+ return (options.client ?? this.client).get({ url: "/api/pipeline-executions/step-runs/by-definition/{pipelineDefinitionId}", ...options });
13270
13283
  }
13271
13284
  }
13272
13285
 
@@ -16205,6 +16218,140 @@ function extractInlineComputedSignals(policy) {
16205
16218
  return [...byKey.values()];
16206
16219
  }
16207
16220
 
16221
+ // src/definitions/advancement-policies/cohort-advancement-policy.ts
16222
+ var cohortAdvancementEventTypeValues = ["continue", "block"];
16223
+ function serializeCohortCondition(condition) {
16224
+ if (condition._tag === "signal") {
16225
+ return {
16226
+ fact: typeof condition.signal === "string" ? condition.signal : condition.signal.key,
16227
+ operator: condition.operator,
16228
+ value: condition.value
16229
+ };
16230
+ }
16231
+ if (condition._tag === "all") {
16232
+ return { all: condition.conditions.map(serializeCohortCondition) };
16233
+ }
16234
+ return { any: condition.conditions.map(serializeCohortCondition) };
16235
+ }
16236
+ function serializeCohortRule(rule) {
16237
+ return {
16238
+ conditions: { [rule.mode]: rule.conditions.map(serializeCohortCondition) },
16239
+ event: {
16240
+ type: rule.outcome,
16241
+ ...rule.outcomeJson ? { params: rule.outcomeJson } : {}
16242
+ }
16243
+ };
16244
+ }
16245
+ function serializeCohortAdvancementPolicy(policy) {
16246
+ if (!policy) {
16247
+ return { rules: [], defaultEventType: "continue", defaultEventParamsJson: null };
16248
+ }
16249
+ return {
16250
+ rules: (policy.rules ?? []).map(serializeCohortRule),
16251
+ defaultEventType: policy.default,
16252
+ defaultEventParamsJson: policy.defaultParamsJson ?? null
16253
+ };
16254
+ }
16255
+ function visitCohortSignalConditions(conditions, visit) {
16256
+ for (const c of conditions) {
16257
+ if (c._tag === "signal") {
16258
+ visit(c);
16259
+ } else {
16260
+ visitCohortSignalConditions(c.conditions, visit);
16261
+ }
16262
+ }
16263
+ }
16264
+ function isSameStepSignalsListDefinition(a, b) {
16265
+ return JSON.stringify(a.ops) === JSON.stringify(b.ops) && JSON.stringify(a.reducer) === JSON.stringify(b.reducer);
16266
+ }
16267
+ function extractInlineStepSignalsListDefinitions(policy) {
16268
+ if (!policy?.rules)
16269
+ return [];
16270
+ const byKey = new Map;
16271
+ for (const rule of policy.rules) {
16272
+ visitCohortSignalConditions(rule.conditions, (cond) => {
16273
+ if (typeof cond.signal === "string")
16274
+ return;
16275
+ const inline = cond.signal;
16276
+ const def = {
16277
+ key: inline.key,
16278
+ ops: inline.ops,
16279
+ reducer: inline.reducer
16280
+ };
16281
+ const existing = byKey.get(def.key);
16282
+ if (existing) {
16283
+ if (!isSameStepSignalsListDefinition(existing, def)) {
16284
+ throw new Error(`Conflicting inline stepSignalsList definitions for key "${def.key}"`);
16285
+ }
16286
+ return;
16287
+ }
16288
+ byKey.set(def.key, def);
16289
+ });
16290
+ }
16291
+ return [...byKey.values()];
16292
+ }
16293
+
16294
+ // src/definitions/pipelines/chain-graph.ts
16295
+ function tryOrderChainNodeDefinitions(nodeDefinitions, dependencyEdges) {
16296
+ const nodesByKey = new Map;
16297
+ for (const nodeDefinition of nodeDefinitions) {
16298
+ nodesByKey.set(nodeDefinition.nodeKey, nodeDefinition);
16299
+ }
16300
+ const outgoing = new Map;
16301
+ const incomingCount = new Map;
16302
+ for (const nodeDefinition of nodeDefinitions) {
16303
+ incomingCount.set(nodeDefinition.nodeKey, 0);
16304
+ }
16305
+ for (const edge of dependencyEdges) {
16306
+ if (!nodesByKey.has(edge.fromNodeKey) || !nodesByKey.has(edge.toNodeKey)) {
16307
+ return null;
16308
+ }
16309
+ if (outgoing.has(edge.fromNodeKey))
16310
+ return null;
16311
+ outgoing.set(edge.fromNodeKey, edge.toNodeKey);
16312
+ incomingCount.set(edge.toNodeKey, (incomingCount.get(edge.toNodeKey) ?? 0) + 1);
16313
+ }
16314
+ for (const count of incomingCount.values()) {
16315
+ if (count > 1)
16316
+ return null;
16317
+ }
16318
+ if (nodeDefinitions.length === 0)
16319
+ return [];
16320
+ const roots = nodeDefinitions.filter((nodeDefinition) => (incomingCount.get(nodeDefinition.nodeKey) ?? 0) === 0);
16321
+ if (roots.length !== 1)
16322
+ return null;
16323
+ const rootNode = roots[0];
16324
+ if (!rootNode)
16325
+ return null;
16326
+ const ordered = [];
16327
+ const visited = new Set;
16328
+ let currentKey = rootNode.nodeKey;
16329
+ while (currentKey !== undefined) {
16330
+ if (visited.has(currentKey))
16331
+ return null;
16332
+ visited.add(currentKey);
16333
+ const currentNode = nodesByKey.get(currentKey);
16334
+ if (!currentNode)
16335
+ return null;
16336
+ ordered.push(currentNode);
16337
+ currentKey = outgoing.get(currentKey);
16338
+ }
16339
+ if (ordered.length !== nodeDefinitions.length)
16340
+ return null;
16341
+ return ordered;
16342
+ }
16343
+ function buildChainDependencyEdges(orderedNodes) {
16344
+ const dependencyEdges = [];
16345
+ for (let index = 0;index < orderedNodes.length - 1; index += 1) {
16346
+ const from = orderedNodes[index];
16347
+ const to = orderedNodes[index + 1];
16348
+ if (!from || !to)
16349
+ continue;
16350
+ dependencyEdges.push({ fromNodeKey: from.nodeKey, toNodeKey: to.nodeKey });
16351
+ }
16352
+ return dependencyEdges;
16353
+ }
16354
+
16208
16355
  // src/definitions/pipelines/define-pipeline.ts
16209
16356
  function serializeBinding(binding) {
16210
16357
  if (binding.source === "pipeline_input") {
@@ -16223,15 +16370,42 @@ function serializeBinding(binding) {
16223
16370
  if (binding.source === "literal") {
16224
16371
  return { source: "literal", value: binding.value };
16225
16372
  }
16373
+ if (binding.source === "signals_list") {
16374
+ return { source: "signals_list", stepKey: binding.fanOutStep.key };
16375
+ }
16376
+ if (binding.source === "fan_out_item") {
16377
+ return { source: "fan_out_item" };
16378
+ }
16226
16379
  return { source: "step_output", stepKey: binding.step.key };
16227
16380
  }
16381
+ var isFanOutConfig = (node) => ("nodeType" in node) && node.nodeType === "fanOut";
16382
+ var isCohortGateConfig = (node) => ("nodeType" in node) && node.nodeType === "cohortGate";
16383
+ function serializeInputBindings(input, pipelineInputBindings) {
16384
+ const autoBindings = {
16385
+ workItemTitle: { source: "work_item", field: "title" },
16386
+ workItemDescription: { source: "work_item", field: "description" }
16387
+ };
16388
+ const pipelineBindings = {};
16389
+ for (const [key, binding] of Object.entries(pipelineInputBindings ?? {})) {
16390
+ pipelineBindings[key] = serializeBinding(binding);
16391
+ }
16392
+ const explicitBindings = Object.fromEntries(Object.entries(input ?? {}).filter((entry) => entry[1] !== undefined).map(([key, binding]) => [key, serializeBinding(binding)]));
16393
+ return { ...autoBindings, ...pipelineBindings, ...explicitBindings };
16394
+ }
16228
16395
  function buildPipelineSpec(config2) {
16229
- const steps = config2.steps;
16396
+ const nodes = config2.nodes;
16230
16397
  const stepDefMap = new Map;
16231
- for (const stepConfig of steps) {
16232
- const mapKey = `${stepConfig.step.key}@v${String(stepConfig.step.version)}`;
16398
+ const registerStepDef = (step) => {
16399
+ const mapKey = `${step.key}@v${String(step.version)}`;
16233
16400
  if (!stepDefMap.has(mapKey)) {
16234
- stepDefMap.set(mapKey, stepConfig.step);
16401
+ stepDefMap.set(mapKey, step);
16402
+ }
16403
+ };
16404
+ for (const node of nodes) {
16405
+ if (isFanOutConfig(node)) {
16406
+ registerStepDef(node.fanOutStep);
16407
+ } else if (!isCohortGateConfig(node)) {
16408
+ registerStepDef(node.step);
16235
16409
  }
16236
16410
  }
16237
16411
  let inputSchemaJson = null;
@@ -16242,6 +16416,46 @@ function buildPipelineSpec(config2) {
16242
16416
  inputSchemaJson = null;
16243
16417
  }
16244
16418
  }
16419
+ const nodeDefinitions = nodes.map((node) => {
16420
+ if (isCohortGateConfig(node)) {
16421
+ const serializedPolicy = serializeCohortAdvancementPolicy(node.advanceAll);
16422
+ const inlineStepSignalsListDefinitions = extractInlineStepSignalsListDefinitions(node.advanceAll);
16423
+ return {
16424
+ nodeKey: node.nodeKey,
16425
+ kind: "cohortGate",
16426
+ advanceAllPolicyDefinition: serializedPolicy,
16427
+ stepSignalsListDefinitions: [
16428
+ ...inlineStepSignalsListDefinitions,
16429
+ ...node.stepSignalsListDefinitions ?? []
16430
+ ]
16431
+ };
16432
+ }
16433
+ if (isFanOutConfig(node)) {
16434
+ return {
16435
+ nodeKey: node.fanOutStep.key,
16436
+ kind: "fanOut",
16437
+ stepKey: node.fanOutStep.key,
16438
+ stepName: node.fanOutStep.name,
16439
+ stepDescription: node.fanOutStep.description,
16440
+ inputBindingsJson: serializeInputBindings(node.input, config2.pipelineInputBindings),
16441
+ timeoutSeconds: node.timeout ?? null,
16442
+ overSignalKey: node.overSignalKey,
16443
+ advanceEachPolicyDefinition: serializeCohortAdvancementPolicy(node.advanceEach)
16444
+ };
16445
+ }
16446
+ return {
16447
+ nodeKey: node.step.key,
16448
+ kind: "step",
16449
+ stepKey: node.step.key,
16450
+ stepName: node.step.name,
16451
+ stepDescription: node.step.description,
16452
+ inputBindingsJson: serializeInputBindings(node.input, config2.pipelineInputBindings),
16453
+ timeoutSeconds: node.timeout ?? null,
16454
+ advancementPolicyDefinition: serializeAdvancementPolicy(node.advancement),
16455
+ computedSignalDefinitions: extractInlineComputedSignals(node.advancement)
16456
+ };
16457
+ });
16458
+ const dependencyEdges = buildChainDependencyEdges(nodeDefinitions);
16245
16459
  return {
16246
16460
  key: config2.key,
16247
16461
  name: config2.name,
@@ -16250,31 +16464,8 @@ function buildPipelineSpec(config2) {
16250
16464
  status: config2.status ?? "active",
16251
16465
  inputSchemaJson,
16252
16466
  _stepDefinitions: [...stepDefMap.values()],
16253
- steps: steps.map((stepConfig, index) => {
16254
- const autoBindings = {
16255
- workItemTitle: { source: "work_item", field: "title" },
16256
- workItemDescription: { source: "work_item", field: "description" }
16257
- };
16258
- const pipelineBindings = {};
16259
- for (const [key, binding] of Object.entries(config2.pipelineInputBindings ?? {})) {
16260
- pipelineBindings[key] = serializeBinding(binding);
16261
- }
16262
- const explicitStepBindings = Object.fromEntries(Object.entries(stepConfig.input ?? {}).filter((entry) => entry[1] !== undefined).map(([key, binding]) => [key, serializeBinding(binding)]));
16263
- return {
16264
- stepKey: stepConfig.step.key,
16265
- stepName: stepConfig.step.name,
16266
- stepDescription: stepConfig.step.description,
16267
- position: index + 1,
16268
- inputBindingsJson: {
16269
- ...autoBindings,
16270
- ...pipelineBindings,
16271
- ...explicitStepBindings
16272
- },
16273
- timeoutSeconds: stepConfig.timeout ?? null,
16274
- advancementPolicyDefinition: serializeAdvancementPolicy(stepConfig.advancement),
16275
- computedSignalDefinitions: extractInlineComputedSignals(stepConfig.advancement)
16276
- };
16277
- })
16467
+ nodeDefinitions,
16468
+ dependencyEdges
16278
16469
  };
16279
16470
  }
16280
16471
  // src/definitions/advancement-policies/fluent-rules.ts
@@ -16445,7 +16636,10 @@ function makeStepInputCtx(inputSchema) {
16445
16636
  output(step) {
16446
16637
  return { source: "step_output", step };
16447
16638
  },
16448
- literal: literal2
16639
+ literal: literal2,
16640
+ signalsList(fanOutStep) {
16641
+ return { source: "signals_list", fanOutStep };
16642
+ }
16449
16643
  };
16450
16644
  }
16451
16645
  function literal2(value) {
@@ -16490,61 +16684,247 @@ function mergeStepBindings(pipelineBindings, explicitBindings) {
16490
16684
  return Object.keys(merged).length > 0 ? merged : undefined;
16491
16685
  }
16492
16686
 
16493
- // src/definitions/pipelines/builder.ts
16494
- class PipelineStepAdvancementBuilder {
16495
- inputSchema;
16496
- meta;
16497
- steps;
16498
- pipelineInputBindings;
16499
- pipelineStepInputBindings;
16500
- constructor(inputSchema, meta3, steps, pipelineInputBindings = {}, pipelineStepInputBindings = {}) {
16501
- this.inputSchema = inputSchema;
16502
- this.meta = meta3;
16503
- this.steps = steps;
16504
- this.pipelineInputBindings = pipelineInputBindings;
16505
- this.pipelineStepInputBindings = pipelineStepInputBindings;
16506
- }
16507
- advance(callback) {
16508
- const last = this.steps.at(-1);
16509
- if (!last)
16510
- throw new Error("Internal error: no steps available");
16511
- const ctx = makeAdvanceCtx();
16512
- const result = callback(ctx);
16513
- const policy = {
16514
- defaultOutcome: result.default,
16515
- ...result.rules !== undefined ? { rules: result.rules } : {}
16687
+ // src/definitions/advancement-policies/cohort-fluent-rules.ts
16688
+ var LEAF_BRAND2 = Symbol("boboddy.cohortRule.leaf");
16689
+ var GROUP_BRAND2 = Symbol("boboddy.cohortRule.group");
16690
+ function createCohortSignalRef(signal2) {
16691
+ const leaf = (operator, value) => {
16692
+ const condition = {
16693
+ _tag: "signal",
16694
+ signal: signal2,
16695
+ operator,
16696
+ value
16516
16697
  };
16517
- last.advancement = policy;
16518
- return new PipelineStepBuilder(this.inputSchema, this.meta, this.steps, this.pipelineInputBindings, this.pipelineStepInputBindings);
16519
- }
16698
+ return {
16699
+ [LEAF_BRAND2]: condition,
16700
+ then(outcome, paramsJson) {
16701
+ return {
16702
+ _tag: "rule",
16703
+ mode: "all",
16704
+ conditions: [condition],
16705
+ outcome,
16706
+ ...paramsJson ? { outcomeJson: paramsJson } : {}
16707
+ };
16708
+ }
16709
+ };
16710
+ };
16711
+ return {
16712
+ eq: (v) => leaf("equal", v),
16713
+ ne: (v) => leaf("notEqual", v),
16714
+ gt: (v) => leaf("greaterThan", v),
16715
+ gte: (v) => leaf("greaterThanInclusive", v),
16716
+ lt: (v) => leaf("lessThan", v),
16717
+ lte: (v) => leaf("lessThanInclusive", v),
16718
+ in: (vs) => leaf("in", vs),
16719
+ notIn: (vs) => leaf("notIn", vs),
16720
+ contains: (v) => leaf("contains", v),
16721
+ doesNotContain: (v) => leaf("doesNotContain", v)
16722
+ };
16723
+ }
16724
+ function createCohortLeafFromCondition(condition) {
16725
+ return {
16726
+ [LEAF_BRAND2]: condition,
16727
+ then(outcome, paramsJson) {
16728
+ return {
16729
+ _tag: "rule",
16730
+ mode: "all",
16731
+ conditions: [condition],
16732
+ outcome,
16733
+ ...paramsJson ? { outcomeJson: paramsJson } : {}
16734
+ };
16735
+ }
16736
+ };
16737
+ }
16738
+ function extractCohortCondition(ref) {
16739
+ if (LEAF_BRAND2 in ref)
16740
+ return ref[LEAF_BRAND2];
16741
+ const group = ref[GROUP_BRAND2];
16742
+ return group.mode === "all" ? { _tag: "all", conditions: group.conditions } : { _tag: "any", conditions: group.conditions };
16743
+ }
16744
+ function createCohortGroup(mode, refs) {
16745
+ const conditions = refs.map(extractCohortCondition);
16746
+ return {
16747
+ [GROUP_BRAND2]: { mode, conditions },
16748
+ then(outcome, paramsJson) {
16749
+ return {
16750
+ _tag: "rule",
16751
+ mode,
16752
+ conditions,
16753
+ outcome,
16754
+ ...paramsJson ? { outcomeJson: paramsJson } : {}
16755
+ };
16756
+ }
16757
+ };
16758
+ }
16759
+ function makeKeyedCohortSignalRef(key) {
16760
+ return createCohortSignalRef(key);
16761
+ }
16762
+ function makeAdvanceEachCtx() {
16763
+ return {
16764
+ signal: (key) => makeKeyedCohortSignalRef(key),
16765
+ stepSignals: new Proxy({}, {
16766
+ get(_, key) {
16767
+ if (typeof key === "string")
16768
+ return makeKeyedCohortSignalRef(key);
16769
+ return;
16770
+ }
16771
+ }),
16772
+ all: (...refs) => createCohortGroup("all", refs),
16773
+ any: (...refs) => createCohortGroup("any", refs)
16774
+ };
16775
+ }
16776
+ var branchOutcomeValues = [
16777
+ "continue",
16778
+ "block",
16779
+ "error",
16780
+ "abandoned"
16781
+ ];
16782
+ function summarizeTransformOp(op) {
16783
+ if (op.op === "filter") {
16784
+ return `filter_${op.operator}_${JSON.stringify(op.value)}`;
16785
+ }
16786
+ if (op.op === "sortBy") {
16787
+ return `sortBy_${op.direction}`;
16788
+ }
16789
+ return "unique";
16790
+ }
16791
+ function deriveStepSignalsListKey(ops, reducer) {
16792
+ const pluck = ops.find((op) => op.op === "pluck");
16793
+ const base = `${reducer.op}_${pluck?.signalKey ?? "value"}`;
16794
+ const extras = ops.filter((op) => op.op !== "pluck").map(summarizeTransformOp);
16795
+ const reducerExtra = reducer.op === "join" ? `sep_${reducer.separator}` : null;
16796
+ const suffixParts = [...extras, ...reducerExtra ? [reducerExtra] : []];
16797
+ return suffixParts.length > 0 ? `${base}_${suffixParts.join("_")}` : base;
16798
+ }
16799
+ function createStepSignalsListBuilder(ops) {
16800
+ const withOp = (op) => createStepSignalsListBuilder([...ops, op]);
16801
+ const reduce = (reducer) => {
16802
+ const token = {
16803
+ _tag: "step_signals_list",
16804
+ key: deriveStepSignalsListKey(ops, reducer),
16805
+ ops: [...ops],
16806
+ reducer
16807
+ };
16808
+ return createCohortSignalRef(token);
16809
+ };
16810
+ return {
16811
+ filter: (operator, value) => withOp({ op: "filter", operator, value }),
16812
+ sortBy: (direction = "asc") => withOp({ op: "sortBy", direction }),
16813
+ unique: () => withOp({ op: "unique" }),
16814
+ count: () => reduce({ op: "count" }),
16815
+ sum: () => reduce({ op: "sum" }),
16816
+ avg: () => reduce({ op: "avg" }),
16817
+ min: () => reduce({ op: "min" }),
16818
+ max: () => reduce({ op: "max" }),
16819
+ booleanAll: () => reduce({ op: "booleanAll" }),
16820
+ booleanAny: () => reduce({ op: "booleanAny" }),
16821
+ join: (separator = ",") => reduce({ op: "join", separator }),
16822
+ first: () => reduce({ op: "first" }),
16823
+ last: () => reduce({ op: "last" })
16824
+ };
16825
+ }
16826
+ function makeAdvanceAllCtx() {
16827
+ return {
16828
+ branchOutcomes: {
16829
+ total: () => createCohortSignalRef("branchCount"),
16830
+ count: (outcome) => createCohortSignalRef(`${outcome}Count`),
16831
+ every: (outcome) => createCohortLeafFromCondition({
16832
+ _tag: "signal",
16833
+ signal: `${outcome}Count`,
16834
+ operator: "equal",
16835
+ value: { fact: "branchCount" }
16836
+ }),
16837
+ some: (outcome) => createCohortLeafFromCondition({
16838
+ _tag: "signal",
16839
+ signal: `${outcome}Count`,
16840
+ operator: "greaterThan",
16841
+ value: 0
16842
+ })
16843
+ },
16844
+ stepSignalsList: {
16845
+ pluck: (signalKey) => createStepSignalsListBuilder([{ op: "pluck", signalKey }])
16846
+ },
16847
+ all: (...refs) => createCohortGroup("all", refs),
16848
+ any: (...refs) => createCohortGroup("any", refs)
16849
+ };
16850
+ }
16851
+
16852
+ // src/definitions/pipelines/fan-out-builder.ts
16853
+ function beginFanOut(inputSchema, meta3, nodes, pipelineInputBindings, pipelineStepInputBindings, step, config2) {
16854
+ const baseCtx = makeStepInputCtx(inputSchema);
16855
+ const ctx = {
16856
+ ...baseCtx,
16857
+ item: { source: "fan_out_item" }
16858
+ };
16859
+ const rawInput = config2.input ? config2.input(ctx) : {};
16860
+ const input = mergeStepBindings(pipelineStepInputBindings, normalizeInputMapping(rawInput));
16861
+ const fanOutNodeConfig = {
16862
+ nodeType: "fanOut",
16863
+ fanOutStep: step,
16864
+ overSignalKey: config2.over,
16865
+ ...input ? { input } : {},
16866
+ ...config2.timeout !== undefined ? { timeout: config2.timeout } : {}
16867
+ };
16868
+ const advanceEachCtx = makeAdvanceEachCtx();
16869
+ const advanceEachResult = config2.advance(advanceEachCtx);
16870
+ const advanceEachPolicy = {
16871
+ default: advanceEachResult.default,
16872
+ ...advanceEachResult.rules !== undefined ? { rules: advanceEachResult.rules } : {}
16873
+ };
16874
+ fanOutNodeConfig.advanceEach = advanceEachPolicy;
16875
+ const cohortGateNodeConfig = {
16876
+ nodeType: "cohortGate",
16877
+ nodeKey: `${step.key}__cohortGate`
16878
+ };
16879
+ const advanceAllCtx = makeAdvanceAllCtx();
16880
+ const advanceAllResult = config2.advanceAll(advanceAllCtx);
16881
+ const advanceAllPolicy = {
16882
+ default: advanceAllResult.default,
16883
+ ...advanceAllResult.rules !== undefined ? { rules: advanceAllResult.rules } : {}
16884
+ };
16885
+ cohortGateNodeConfig.advanceAll = advanceAllPolicy;
16886
+ nodes.push(fanOutNodeConfig, cohortGateNodeConfig);
16887
+ return new PipelineStepBuilder(inputSchema, meta3, nodes, pipelineInputBindings, pipelineStepInputBindings);
16888
+ }
16889
+
16890
+ // src/definitions/pipelines/builder.ts
16891
+ function pushStep(inputSchema, meta3, nodes, pipelineInputBindings, pipelineStepInputBindings, step, rawOptions) {
16892
+ const options = rawOptions;
16893
+ const ctx = makeStepInputCtx(inputSchema);
16894
+ const rawInput = options.input ? options.input(ctx) : {};
16895
+ const input = mergeStepBindings(pipelineStepInputBindings, normalizeInputMapping(rawInput));
16896
+ const stepConfig = { step, input };
16897
+ if (options.timeout !== undefined)
16898
+ stepConfig.timeout = options.timeout;
16899
+ const advanceCtx = makeAdvanceCtx();
16900
+ const result = options.advance(advanceCtx);
16901
+ const policy = {
16902
+ defaultOutcome: result.default,
16903
+ ...result.rules !== undefined ? { rules: result.rules } : {}
16904
+ };
16905
+ stepConfig.advancement = policy;
16906
+ nodes.push(stepConfig);
16907
+ return new PipelineStepBuilder(inputSchema, meta3, nodes, pipelineInputBindings, pipelineStepInputBindings);
16520
16908
  }
16521
16909
 
16522
16910
  class PipelineStepBuilder {
16523
16911
  inputSchema;
16524
16912
  meta;
16525
- steps;
16913
+ nodes;
16526
16914
  pipelineInputBindings;
16527
16915
  pipelineStepInputBindings;
16528
- constructor(inputSchema, meta3, steps, pipelineInputBindings = {}, pipelineStepInputBindings = {}) {
16916
+ constructor(inputSchema, meta3, nodes, pipelineInputBindings = {}, pipelineStepInputBindings = {}) {
16529
16917
  this.inputSchema = inputSchema;
16530
16918
  this.meta = meta3;
16531
- this.steps = steps;
16919
+ this.nodes = nodes;
16532
16920
  this.pipelineInputBindings = pipelineInputBindings;
16533
16921
  this.pipelineStepInputBindings = pipelineStepInputBindings;
16534
16922
  }
16535
- step(step, mapper, configFn) {
16536
- const ctx = makeStepInputCtx(this.inputSchema);
16537
- const rawInput = mapper ? mapper(ctx) : {};
16538
- const input = mergeStepBindings(this.pipelineStepInputBindings, normalizeInputMapping(rawInput));
16539
- const stepConfig = { step, input };
16540
- if (configFn) {
16541
- const cfg = {};
16542
- configFn(cfg);
16543
- if (cfg.timeout !== undefined)
16544
- stepConfig.timeout = cfg.timeout;
16545
- }
16546
- this.steps.push(stepConfig);
16547
- return new PipelineStepAdvancementBuilder(this.inputSchema, this.meta, this.steps, this.pipelineInputBindings, this.pipelineStepInputBindings);
16923
+ step(step, options) {
16924
+ return pushStep(this.inputSchema, this.meta, this.nodes, this.pipelineInputBindings, this.pipelineStepInputBindings, step, options);
16925
+ }
16926
+ fanOutStep(step, config2) {
16927
+ return beginFanOut(this.inputSchema, this.meta, this.nodes, this.pipelineInputBindings, this.pipelineStepInputBindings, step, config2);
16548
16928
  }
16549
16929
  build() {
16550
16930
  const config2 = {
@@ -16554,7 +16934,7 @@ class PipelineStepBuilder {
16554
16934
  version: this.meta.version,
16555
16935
  status: this.meta.status,
16556
16936
  input: this.inputSchema,
16557
- steps: this.steps,
16937
+ nodes: this.nodes,
16558
16938
  pipelineInputBindings: this.pipelineInputBindings
16559
16939
  };
16560
16940
  return buildPipelineSpec(config2);
@@ -16564,7 +16944,7 @@ class PipelineStepBuilder {
16564
16944
  class PipelineBuilder {
16565
16945
  inputSchema;
16566
16946
  meta;
16567
- steps = [];
16947
+ nodes = [];
16568
16948
  pipelineInputBindings;
16569
16949
  pipelineStepInputBindings;
16570
16950
  constructor(meta3) {
@@ -16589,19 +16969,8 @@ class PipelineBuilder {
16589
16969
  }
16590
16970
  this.pipelineStepInputBindings = resolveAdditionalStepInputBindings("additionalStepInput", additionalStepInput);
16591
16971
  }
16592
- step(step, mapper, configFn) {
16593
- const ctx = makeStepInputCtx(this.inputSchema);
16594
- const rawInput = mapper ? mapper(ctx) : {};
16595
- const input = mergeStepBindings(this.pipelineStepInputBindings, normalizeInputMapping(rawInput));
16596
- const stepConfig = { step, input };
16597
- if (configFn) {
16598
- const cfg = {};
16599
- configFn(cfg);
16600
- if (cfg.timeout !== undefined)
16601
- stepConfig.timeout = cfg.timeout;
16602
- }
16603
- this.steps.push(stepConfig);
16604
- return new PipelineStepAdvancementBuilder(this.inputSchema, this.meta, this.steps, this.pipelineInputBindings, this.pipelineStepInputBindings);
16972
+ step(step, options) {
16973
+ return pushStep(this.inputSchema, this.meta, this.nodes, this.pipelineInputBindings, this.pipelineStepInputBindings, step, options);
16605
16974
  }
16606
16975
  }
16607
16976
  function pipeline(meta3) {
@@ -16631,23 +17000,35 @@ var buildPipelineDefinitionsClient = (pipelineDefinitions) => {
16631
17000
  stepDefMap.set(s.key, s);
16632
17001
  }
16633
17002
  }
16634
- const stepDefinitions = spec.steps.map((step) => {
16635
- const stepDef = stepDefMap.get(step.stepKey);
17003
+ const nonStepNode = spec.nodeDefinitions.find((node) => node.kind !== "step");
17004
+ if (nonStepNode) {
17005
+ throw new Error(`Pipeline "${spec.key}" contains a "${nonStepNode.kind}" node ("${nonStepNode.nodeKey}"), ` + `but fan-out pipelines cannot be pushed via the current wire contract yet. ` + `Only "step"-only (chain) pipelines can be pushed with \`upsertFromSpec\` today.`);
17006
+ }
17007
+ const ordered = tryOrderChainNodeDefinitions(spec.nodeDefinitions, spec.dependencyEdges);
17008
+ if (ordered === null) {
17009
+ throw new Error(`Pipeline "${spec.key}" has a malformed step graph: its node and ` + `dependency-edge definitions do not form a single connected, ` + `acyclic chain. This should not happen from the \`pipeline()\` ` + `builder \u2014 check for hand-edited or generated pipeline specs.`);
17010
+ }
17011
+ const stepDefinitions = ordered.map((node, index) => {
17012
+ const stepKey = node.stepKey;
17013
+ if (!stepKey) {
17014
+ throw new Error(`Node "${node.nodeKey}" in pipeline "${spec.key}" has no stepKey.`);
17015
+ }
17016
+ const stepDef = stepDefMap.get(stepKey);
16636
17017
  if (!stepDef) {
16637
- throw new Error(`Step "${step.stepKey}" referenced in pipeline "${spec.key}" was not found on the server. ` + `Run \`boboddy steps push\` first to push your step definitions.`);
17018
+ throw new Error(`Step "${stepKey}" referenced in pipeline "${spec.key}" was not found on the server. ` + `Run \`boboddy steps push\` first to push your step definitions.`);
16638
17019
  }
16639
17020
  return {
16640
17021
  stepDefinitionId: stepDef.id,
16641
17022
  stepDefinitionVersion: stepDef.version,
16642
- key: step.stepKey,
16643
- name: step.stepName,
16644
- description: step.stepDescription,
16645
- position: step.position,
16646
- inputBindingsJson: step.inputBindingsJson,
16647
- timeoutSeconds: step.timeoutSeconds,
17023
+ key: node.nodeKey,
17024
+ name: node.stepName ?? "",
17025
+ description: node.stepDescription ?? null,
17026
+ position: index + 1,
17027
+ inputBindingsJson: node.inputBindingsJson ?? {},
17028
+ timeoutSeconds: node.timeoutSeconds ?? null,
16648
17029
  retryPolicyJson: null,
16649
- advancementPolicyDefinition: step.advancementPolicyDefinition,
16650
- computedSignalDefinitions: step.computedSignalDefinitions
17030
+ advancementPolicyDefinition: node.advancementPolicyDefinition,
17031
+ computedSignalDefinitions: node.computedSignalDefinitions ?? []
16651
17032
  };
16652
17033
  });
16653
17034
  const body = {
@@ -16682,7 +17063,12 @@ function makeLeaf(fact, path, operator, value) {
16682
17063
  return {
16683
17064
  _condition: condition,
16684
17065
  then(outcome) {
16685
- return { _tag: "assignment_rule", conditions: [condition], mode: "all", outcome };
17066
+ return {
17067
+ _tag: "assignment_rule",
17068
+ conditions: [condition],
17069
+ mode: "all",
17070
+ outcome
17071
+ };
16686
17072
  }
16687
17073
  };
16688
17074
  }
@@ -16701,7 +17087,7 @@ function makeFieldRef(fact, path) {
16701
17087
  };
16702
17088
  }
16703
17089
  function makeAssign(pipeline2) {
16704
- if (typeof pipeline2 !== "object" || typeof pipeline2["key"] !== "string" || !Array.isArray(pipeline2["steps"])) {
17090
+ if (typeof pipeline2 !== "object" || typeof pipeline2["key"] !== "string" || !Array.isArray(pipeline2["nodeDefinitions"])) {
16705
17091
  throw new Error("assign() requires a pipeline spec produced by pipeline().build(). " + "Pass the default-exported value from a pipeline definition file.");
16706
17092
  }
16707
17093
  return { _tag: "assign", pipeline: pipeline2 };
@@ -16789,7 +17175,7 @@ function serializeDefaultPipelineAssignment(spec) {
16789
17175
  return serializeAssignmentRule(rule);
16790
17176
  });
16791
17177
  return {
16792
- linearPipelineDefinitionKey: primaryKey,
17178
+ pipelineDefinitionKey: primaryKey,
16793
17179
  rulesJson: { rules: serializedRules },
16794
17180
  defaultEventType: defaultType,
16795
17181
  defaultEventParamsJson: defaultParams,
@@ -17087,6 +17473,8 @@ function checkHealthChecks(steps) {
17087
17473
  return issues;
17088
17474
  }
17089
17475
  function routeTargets(policy) {
17476
+ if (!policy)
17477
+ return [];
17090
17478
  const keys = [];
17091
17479
  if (policy.defaultEventType === "route" && typeof policy.defaultEventParamsJson?.["pipelineKey"] === "string") {
17092
17480
  keys.push(policy.defaultEventParamsJson["pipelineKey"]);
@@ -17105,36 +17493,42 @@ function checkRouteTargets(pipelines, knownPipelineKeys) {
17105
17493
  ...knownPipelineKeys
17106
17494
  ]);
17107
17495
  for (const pipeline2 of pipelines) {
17108
- for (const step of pipeline2.steps) {
17109
- for (const target of routeTargets(step.advancementPolicyDefinition)) {
17496
+ for (const node of pipeline2.nodeDefinitions) {
17497
+ for (const target of routeTargets(node.advancementPolicyDefinition)) {
17110
17498
  if (known.has(target))
17111
17499
  continue;
17112
17500
  issues.push({
17113
17501
  check: "route-target",
17114
- message: `Pipeline "${pipeline2.key}" step "${step.stepKey}" routes to pipeline ` + `"${target}", but no pipeline with that key was found on the server or ` + `in the current push batch. Push the target pipeline first.`
17502
+ message: `Pipeline "${pipeline2.key}" step "${node.stepKey ?? node.nodeKey}" routes to pipeline ` + `"${target}", but no pipeline with that key was found on the server or ` + `in the current push batch. Push the target pipeline first.`
17115
17503
  });
17116
17504
  }
17117
17505
  }
17118
17506
  }
17119
17507
  return issues;
17120
17508
  }
17121
- function executionRanks(steps) {
17122
- const positions = steps.map((step) => step.position);
17123
- const usable = positions.every((value) => Number.isInteger(value) && value > 0) && new Set(positions).size === positions.length;
17124
- const indexes = steps.map((_, index) => index);
17125
- const ordered = usable ? [...indexes].sort((left, right) => (positions[left] ?? 0) - (positions[right] ?? 0)) : indexes;
17509
+ function executionRanks(nodeDefinitions, dependencyEdges) {
17510
+ const indexes = nodeDefinitions.map((_, index) => index);
17511
+ const orderedNodes = tryOrderChainNodeDefinitions(nodeDefinitions, dependencyEdges);
17512
+ if (orderedNodes === null) {
17513
+ return new Map(indexes.map((index, rank) => [index, rank]));
17514
+ }
17515
+ const indexByNodeKey = new Map(nodeDefinitions.map((node, index) => [node.nodeKey, index]));
17516
+ const ordered = orderedNodes.map((node) => indexByNodeKey.get(node.nodeKey) ?? 0);
17126
17517
  return new Map(ordered.map((index, rank) => [index, rank]));
17127
17518
  }
17128
17519
  function bindingSource(binding) {
17129
17520
  if (binding.source === "step_signal") {
17130
- return { stepKey: binding.stepKey, signalKey: binding.signalKey };
17521
+ return { stepKey: binding.stepKey, signalKey: binding.signalKey, kind: "signal" };
17131
17522
  }
17132
17523
  if (binding.source === "step_output") {
17133
- return { stepKey: binding.stepKey, signalKey: null };
17524
+ return { stepKey: binding.stepKey, signalKey: null, kind: "output" };
17525
+ }
17526
+ if (binding.source === "signals_list") {
17527
+ return { stepKey: binding.stepKey, signalKey: null, kind: "signals_list" };
17134
17528
  }
17135
17529
  return null;
17136
17530
  }
17137
- function declaredSignalKeys(stepKey, stepsByKey, pipelineSteps) {
17531
+ function declaredSignalKeys(stepKey, stepsByKey, pipelineNodeDefinitions) {
17138
17532
  const specs = stepsByKey.get(stepKey);
17139
17533
  if (!specs || specs.length === 0)
17140
17534
  return null;
@@ -17143,10 +17537,10 @@ function declaredSignalKeys(stepKey, stepsByKey, pipelineSteps) {
17143
17537
  for (const signal2 of spec.signalExtractorDefinitions)
17144
17538
  keys.add(signal2.key);
17145
17539
  }
17146
- for (const step of pipelineSteps) {
17147
- if (step.stepKey !== stepKey)
17540
+ for (const node of pipelineNodeDefinitions) {
17541
+ if (node.stepKey !== stepKey)
17148
17542
  continue;
17149
- for (const computed of step.computedSignalDefinitions)
17543
+ for (const computed of node.computedSignalDefinitions ?? [])
17150
17544
  keys.add(computed.key);
17151
17545
  }
17152
17546
  return [...keys];
@@ -17154,18 +17548,18 @@ function declaredSignalKeys(stepKey, stepsByKey, pipelineSteps) {
17154
17548
  function checkSignalBindings(pipelines, stepsByKey) {
17155
17549
  const issues = [];
17156
17550
  for (const pipeline2 of pipelines) {
17157
- const ranks = executionRanks(pipeline2.steps);
17158
- const order = [...pipeline2.steps.keys()].sort((left, right) => (ranks.get(left) ?? 0) - (ranks.get(right) ?? 0)).map((index) => pipeline2.steps[index]?.stepKey ?? "");
17551
+ const ranks = executionRanks(pipeline2.nodeDefinitions, pipeline2.dependencyEdges);
17552
+ const order = [...pipeline2.nodeDefinitions.keys()].sort((left, right) => (ranks.get(left) ?? 0) - (ranks.get(right) ?? 0)).map((index) => pipeline2.nodeDefinitions[index]?.stepKey ?? "");
17159
17553
  const orderHint = `Steps in "${pipeline2.key}", in order: ${order.join(" \u2192 ")}.`;
17160
- pipeline2.steps.forEach((step, index) => {
17554
+ pipeline2.nodeDefinitions.forEach((node, index) => {
17161
17555
  const consumerRank = ranks.get(index) ?? index;
17162
- const where = `Pipeline "${pipeline2.key}" step "${step.stepKey}"`;
17163
- for (const [field, binding] of Object.entries(step.inputBindingsJson)) {
17556
+ const where = `Pipeline "${pipeline2.key}" step "${node.stepKey ?? node.nodeKey}"`;
17557
+ for (const [field, binding] of Object.entries(node.inputBindingsJson ?? {})) {
17164
17558
  const source = bindingSource(binding);
17165
17559
  if (!source)
17166
17560
  continue;
17167
- const what = source.signalKey ? `binds input "${field}" to signal "${source.signalKey}" of step "${source.stepKey}"` : `binds input "${field}" to the output of step "${source.stepKey}"`;
17168
- const producerRanks = pipeline2.steps.map((candidate, candidateIndex) => candidate.stepKey === source.stepKey ? ranks.get(candidateIndex) ?? candidateIndex : null).filter((rank) => rank !== null);
17561
+ const what = source.kind === "signal" ? `binds input "${field}" to signal "${source.signalKey ?? ""}" of step "${source.stepKey}"` : source.kind === "signals_list" ? `binds input "${field}" to the signals list of fan-out step "${source.stepKey}"` : `binds input "${field}" to the output of step "${source.stepKey}"`;
17562
+ const producerRanks = pipeline2.nodeDefinitions.map((candidate, candidateIndex) => candidate.stepKey === source.stepKey ? ranks.get(candidateIndex) ?? candidateIndex : null).filter((rank) => rank !== null);
17169
17563
  if (producerRanks.length === 0) {
17170
17564
  issues.push({
17171
17565
  check: "signal-binding",
@@ -17182,7 +17576,7 @@ function checkSignalBindings(pipelines, stepsByKey) {
17182
17576
  }
17183
17577
  if (source.signalKey === null)
17184
17578
  continue;
17185
- const available = declaredSignalKeys(source.stepKey, stepsByKey, pipeline2.steps);
17579
+ const available = declaredSignalKeys(source.stepKey, stepsByKey, pipeline2.nodeDefinitions);
17186
17580
  if (available === null || available.includes(source.signalKey))
17187
17581
  continue;
17188
17582
  issues.push({
@@ -17233,7 +17627,7 @@ function isPipelineDefinitionSpec(value) {
17233
17627
  if (typeof value !== "object" || value === null)
17234
17628
  return false;
17235
17629
  const obj = value;
17236
- return typeof obj["key"] === "string" && typeof obj["name"] === "string" && typeof obj["version"] === "number" && Array.isArray(obj["steps"]);
17630
+ return typeof obj["key"] === "string" && typeof obj["name"] === "string" && typeof obj["version"] === "number" && Array.isArray(obj["nodeDefinitions"]);
17237
17631
  }
17238
17632
  async function importModule(path) {
17239
17633
  return await import(pathToFileURL(path).href);
@@ -17331,7 +17725,7 @@ async function syncDefaultPipelineAssignment(spec, opts, headers, pipelinesClien
17331
17725
  p.id
17332
17726
  ]));
17333
17727
  const referencedKeys = new Set;
17334
- referencedKeys.add(serialized.linearPipelineDefinitionKey);
17728
+ referencedKeys.add(serialized.pipelineDefinitionKey);
17335
17729
  for (const rule of serialized.rulesJson.rules) {
17336
17730
  if (rule.event.type === "assign" && typeof rule.event.params?.["pipelineKey"] === "string") {
17337
17731
  referencedKeys.add(rule.event.params["pipelineKey"]);
@@ -17342,9 +17736,9 @@ async function syncDefaultPipelineAssignment(spec, opts, headers, pipelinesClien
17342
17736
  throw new Error(`${DEFAULT_PIPELINE_ASSIGNMENT_FILENAME} references pipeline "${key}", ` + `but no pipeline with that key was found on the server. ` + `Push the pipeline first with \`boboddy pipelines push\`.`);
17343
17737
  }
17344
17738
  }
17345
- const linearPipelineDefinitionId = pipelineKeyToId.get(serialized.linearPipelineDefinitionKey);
17346
- if (!linearPipelineDefinitionId) {
17347
- throw new Error(`Pipeline key "${serialized.linearPipelineDefinitionKey}" was not found on the server.`);
17739
+ const pipelineDefinitionId = pipelineKeyToId.get(serialized.pipelineDefinitionKey);
17740
+ if (!pipelineDefinitionId) {
17741
+ throw new Error(`Pipeline key "${serialized.pipelineDefinitionKey}" was not found on the server.`);
17348
17742
  }
17349
17743
  const resolvedRules = serialized.rulesJson.rules.map((rule) => {
17350
17744
  if (rule.event.type === "assign" && typeof rule.event.params?.["pipelineKey"] === "string") {
@@ -17373,7 +17767,7 @@ async function syncDefaultPipelineAssignment(spec, opts, headers, pipelinesClien
17373
17767
  path: { projectId: opts.projectId },
17374
17768
  body: {
17375
17769
  defaultPipelineAssignment: {
17376
- linearPipelineDefinitionId,
17770
+ pipelineDefinitionId,
17377
17771
  rulesJson: { rules: resolvedRules },
17378
17772
  defaultEventType: serialized.defaultEventType,
17379
17773
  defaultEventParamsJson: serialized.defaultEventParamsJson,
@@ -17385,7 +17779,7 @@ async function syncDefaultPipelineAssignment(spec, opts, headers, pipelinesClien
17385
17779
  if (result.error) {
17386
17780
  throw new Error(`Failed to update project default pipeline assignment: ${JSON.stringify(result.error)}`);
17387
17781
  }
17388
- log(`\u2713 default pipeline assignment \u2192 synced (primary pipeline: ${serialized.linearPipelineDefinitionKey})`);
17782
+ log(`\u2713 default pipeline assignment \u2192 synced (primary pipeline: ${serialized.pipelineDefinitionKey})`);
17389
17783
  return true;
17390
17784
  }
17391
17785
  export {