@boboddy/sdk 0.1.5-alpha → 0.1.7-alpha

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.
@@ -1,3 +1,50 @@
1
+ /** Aggregation types supported by the runtime for computed signals. */
2
+ export type PipelineStepComputedSignalType = "average" | "weighted_average" | "sum" | "min" | "max" | "count" | "boolean_any" | "boolean_all";
3
+ type Join<T extends readonly string[], D extends string> = T extends readonly [
4
+ infer Head extends string,
5
+ ...infer Rest extends readonly string[]
6
+ ] ? Rest extends readonly [] ? Head : `${Head}${D}${Join<Rest, D>}` : "";
7
+ /**
8
+ * An inline computed-signal token returned by `Computed.X(...)`. Carries the
9
+ * derived `key` (e.g. `"sum_success"`), the aggregation `type`, and the input
10
+ * signal keys it aggregates over. At serialization time, every inline token
11
+ * embedded in a rule's signal position is extracted into the step's
12
+ * `computedSignalDefinitions` and replaced by its bare key string.
13
+ *
14
+ * - `TKey` — the auto-derived key (literal template).
15
+ * - `TInputSignalKeys` — the union of input signal keys; constrained to the
16
+ * step's signals via `Rule.signal` / `Rule.when` typing.
17
+ */
18
+ export type InlineComputedSignal<TKey extends string = string, TInputSignalKeys extends string = string> = {
19
+ readonly _tag: "computed_signal";
20
+ readonly key: TKey;
21
+ readonly type: PipelineStepComputedSignalType;
22
+ readonly inputSignalKeys: ReadonlyArray<TInputSignalKeys>;
23
+ readonly configJson: Record<string, unknown> | null;
24
+ readonly availableWhenResultStatusIn: readonly string[] | null;
25
+ };
26
+ type ComputedOptions = {
27
+ configJson?: Record<string, unknown> | null;
28
+ availableWhenResultStatusIn?: readonly string[] | null;
29
+ };
30
+ /**
31
+ * Factories for inline computed signals. Each call returns a token whose `key`
32
+ * is auto-derived as `${type}_${inputSignalKeys.join("_")}`.
33
+ *
34
+ * @example
35
+ * Rule.when(Computed.sum(["success"]), "greaterThan", 1, "continue")
36
+ * Rule.signal(Computed.average(["score"]), "greaterThanInclusive", 80)
37
+ */
38
+ export declare const Computed: {
39
+ readonly average: <const TInputs extends readonly [string, string, ...string[]]>(inputSignalKeys: TInputs, options?: ComputedOptions) => InlineComputedSignal<`average_${Join<TInputs, "_">}`, TInputs[number]>;
40
+ readonly weightedAverage: <const TInputs extends readonly [string, string, ...string[]]>(inputSignalKeys: TInputs, options?: ComputedOptions) => InlineComputedSignal<`weighted_average_${Join<TInputs, "_">}`, TInputs[number]>;
41
+ readonly sum: <const TInputs extends readonly [string, string, ...string[]]>(inputSignalKeys: TInputs, options?: ComputedOptions) => InlineComputedSignal<`sum_${Join<TInputs, "_">}`, TInputs[number]>;
42
+ readonly min: <const TInputs extends readonly [string, string, ...string[]]>(inputSignalKeys: TInputs, options?: ComputedOptions) => InlineComputedSignal<`min_${Join<TInputs, "_">}`, TInputs[number]>;
43
+ readonly max: <const TInputs extends readonly [string, string, ...string[]]>(inputSignalKeys: TInputs, options?: ComputedOptions) => InlineComputedSignal<`max_${Join<TInputs, "_">}`, TInputs[number]>;
44
+ readonly count: <const TInputs extends readonly [string, string, ...string[]]>(inputSignalKeys: TInputs, options?: ComputedOptions) => InlineComputedSignal<`count_${Join<TInputs, "_">}`, TInputs[number]>;
45
+ readonly booleanAny: <const TInputs extends readonly [string, string, ...string[]]>(inputSignalKeys: TInputs, options?: ComputedOptions) => InlineComputedSignal<`boolean_any_${Join<TInputs, "_">}`, TInputs[number]>;
46
+ readonly booleanAll: <const TInputs extends readonly [string, string, ...string[]]>(inputSignalKeys: TInputs, options?: ComputedOptions) => InlineComputedSignal<`boolean_all_${Join<TInputs, "_">}`, TInputs[number]>;
47
+ };
1
48
  /**
2
49
  * Comparison operators supported by json-rules-engine.
3
50
  * These map directly to the operator names the runtime evaluates against signal values.
@@ -26,11 +73,14 @@ export type AdvancementOutcome = AdvancementEventType | {
26
73
  * by `Rule.when()`.
27
74
  *
28
75
  * `TSignalKeys` is constrained to the declaring step's signal keys, so the
29
- * `signal` field is validated at compile time.
76
+ * `signal` field is validated at compile time. `signal` may be either a step
77
+ * signal key (string) or an inline `Computed.X(...)` token — at serialization
78
+ * time, inline tokens are hoisted into `computedSignalDefinitions` and replaced
79
+ * by their bare key string.
30
80
  */
31
81
  export type SignalCondition<TSignalKeys extends string = string> = {
32
82
  readonly _tag: "signal";
33
- signal: TSignalKeys;
83
+ signal: TSignalKeys | InlineComputedSignal<string, TSignalKeys>;
34
84
  operator: ConditionOperator;
35
85
  value: unknown;
36
86
  };
@@ -80,7 +130,7 @@ export type Rule<TSignalKeys extends string = string> = {
80
130
  * Rule.signal("flagged", "equal", false),
81
131
  * ], "continue")
82
132
  */
83
- declare function signal<TSignalKeys extends string>(signal: TSignalKeys, operator: ConditionOperator, value: unknown): SignalCondition<TSignalKeys>;
133
+ declare function signal<TSignalKeys extends string>(signal: TSignalKeys | InlineComputedSignal<string, TSignalKeys>, operator: ConditionOperator, value: unknown): SignalCondition<TSignalKeys>;
84
134
  /**
85
135
  * When called with only `conditions`: returns a nested `AllCondition` group
86
136
  * for use inside another `Rule.all()` or `Rule.any()`.
@@ -136,7 +186,7 @@ declare function any<TSignalKeys extends string>(conditions: RuleCondition<TSign
136
186
  * Rule.when("passed", "equal", true, "continue")
137
187
  * Rule.when("score", "greaterThanInclusive", 80, { outcome: "continue", outcomeJson: { via: "score" } })
138
188
  */
139
- declare function when<TSignalKeys extends string>(signal: TSignalKeys, operator: ConditionOperator, value: unknown, outcome: AdvancementOutcome): Rule<TSignalKeys>;
189
+ declare function when<TSignalKeys extends string>(signal: TSignalKeys | InlineComputedSignal<string, TSignalKeys>, operator: ConditionOperator, value: unknown, outcome: AdvancementOutcome): Rule<TSignalKeys>;
140
190
  /**
141
191
  * All factories for building advancement rules.
142
192
  *
@@ -215,4 +265,19 @@ export type SerializedAdvancementPolicy = {
215
265
  allowedEventTypes: AdvancementEventType[];
216
266
  };
217
267
  export declare function serializeAdvancementPolicy(policy: AdvancementPolicy | undefined): SerializedAdvancementPolicy;
268
+ /** Wire-format computed signal definition emitted on the pipeline step. */
269
+ export type SerializedComputedSignalDefinition = {
270
+ key: string;
271
+ type: PipelineStepComputedSignalType;
272
+ inputSignalKeys: string[];
273
+ configJson: Record<string, unknown> | null;
274
+ availableWhenResultStatusIn: string[] | null;
275
+ };
276
+ /**
277
+ * Walks the rules tree, extracts every inline `Computed.X(...)` token embedded
278
+ * in a `SignalCondition.signal` position, dedupes by key, and returns the
279
+ * resulting computed-signal definitions. Two tokens with the same key but
280
+ * differing definitions are a programming error and throw.
281
+ */
282
+ export declare function extractInlineComputedSignals(policy: AdvancementPolicy | undefined): SerializedComputedSignalDefinition[];
218
283
  export {};
@@ -14,6 +14,27 @@ var __export = (target, all) => {
14
14
  };
15
15
 
16
16
  // src/definitions/advancement-policies/define-advancement-policy.ts
17
+ function makeComputed(type, inputSignalKeys, options) {
18
+ const key = [type, ...inputSignalKeys].join("_");
19
+ return {
20
+ _tag: "computed_signal",
21
+ key,
22
+ type,
23
+ inputSignalKeys,
24
+ configJson: options?.configJson ?? null,
25
+ availableWhenResultStatusIn: options?.availableWhenResultStatusIn ?? null
26
+ };
27
+ }
28
+ var Computed = {
29
+ average: (inputSignalKeys, options) => makeComputed("average", inputSignalKeys, options),
30
+ weightedAverage: (inputSignalKeys, options) => makeComputed("weighted_average", inputSignalKeys, options),
31
+ sum: (inputSignalKeys, options) => makeComputed("sum", inputSignalKeys, options),
32
+ min: (inputSignalKeys, options) => makeComputed("min", inputSignalKeys, options),
33
+ max: (inputSignalKeys, options) => makeComputed("max", inputSignalKeys, options),
34
+ count: (inputSignalKeys, options) => makeComputed("count", inputSignalKeys, options),
35
+ booleanAny: (inputSignalKeys, options) => makeComputed("boolean_any", inputSignalKeys, options),
36
+ booleanAll: (inputSignalKeys, options) => makeComputed("boolean_all", inputSignalKeys, options)
37
+ };
17
38
  function signal(signal2, operator, value) {
18
39
  return { _tag: "signal", signal: signal2, operator, value };
19
40
  }
@@ -47,7 +68,7 @@ function resolveOutcome(outcome) {
47
68
  function serializeCondition(condition) {
48
69
  if (condition._tag === "signal") {
49
70
  return {
50
- fact: condition.signal,
71
+ fact: typeof condition.signal === "string" ? condition.signal : condition.signal.key,
51
72
  operator: condition.operator,
52
73
  value: condition.value
53
74
  };
@@ -89,7 +110,49 @@ function serializeAdvancementPolicy(policy) {
89
110
  allowedEventTypes: [...outcomeSet]
90
111
  };
91
112
  }
113
+ function visitSignalConditions(conditions, visit) {
114
+ for (const c of conditions) {
115
+ if (c._tag === "signal") {
116
+ visit(c);
117
+ } else {
118
+ visitSignalConditions(c.conditions, visit);
119
+ }
120
+ }
121
+ }
122
+ function isSameComputedDefinition(a, b) {
123
+ return a.type === b.type && a.inputSignalKeys.length === b.inputSignalKeys.length && a.inputSignalKeys.every((k, i) => k === b.inputSignalKeys[i]) && JSON.stringify(a.configJson) === JSON.stringify(b.configJson) && JSON.stringify(a.availableWhenResultStatusIn) === JSON.stringify(b.availableWhenResultStatusIn);
124
+ }
125
+ function extractInlineComputedSignals(policy) {
126
+ if (!policy?.rules)
127
+ return [];
128
+ const byKey = new Map;
129
+ for (const rule of policy.rules) {
130
+ visitSignalConditions(rule.conditions, (cond) => {
131
+ if (typeof cond.signal === "string")
132
+ return;
133
+ const inline = cond.signal;
134
+ const def = {
135
+ key: inline.key,
136
+ type: inline.type,
137
+ inputSignalKeys: [...inline.inputSignalKeys],
138
+ configJson: inline.configJson,
139
+ availableWhenResultStatusIn: inline.availableWhenResultStatusIn ? [...inline.availableWhenResultStatusIn] : null
140
+ };
141
+ const existing = byKey.get(def.key);
142
+ if (existing) {
143
+ if (!isSameComputedDefinition(existing, def)) {
144
+ throw new Error(`Conflicting inline computed signal definitions for key "${def.key}"`);
145
+ }
146
+ return;
147
+ }
148
+ byKey.set(def.key, def);
149
+ });
150
+ }
151
+ return [...byKey.values()];
152
+ }
92
153
  export {
93
154
  serializeAdvancementPolicy,
94
- Rule
155
+ extractInlineComputedSignals,
156
+ Rule,
157
+ Computed
95
158
  };
@@ -1,8 +1,8 @@
1
1
  import type { ZodType } from "zod";
2
2
  import type { DotPaths, TypedStepDefinitionSpec } from "../steps/define-step";
3
- import { type AdvancementPolicy, type SerializedAdvancementPolicy } from "../advancement-policies/define-advancement-policy";
4
- export type { AdvancementPolicy } from "../advancement-policies/define-advancement-policy";
5
- export { Rule } from "../advancement-policies/define-advancement-policy";
3
+ import { type AdvancementPolicy, type SerializedAdvancementPolicy, type SerializedComputedSignalDefinition } from "../advancement-policies/define-advancement-policy";
4
+ export type { AdvancementPolicy, PipelineStepComputedSignalType, } from "../advancement-policies/define-advancement-policy";
5
+ export { Computed, Rule, } from "../advancement-policies/define-advancement-policy";
6
6
  type AnyTypedStep = TypedStepDefinitionSpec<any, any, any>;
7
7
  export type PipelineInputBinding = {
8
8
  source: "pipeline_input";
@@ -43,7 +43,10 @@ export type PipelineStepConfig<TStep extends AnyTypedStep = AnyTypedStep> = {
43
43
  timeout?: number | null;
44
44
  /**
45
45
  * Controls when and how this step advances in the pipeline.
46
- * Signal keys in `whenSignal()` rules are type-checked against this step's declared signals.
46
+ * Signal keys in `Rule.signal()` / `Rule.when()` calls are type-checked
47
+ * against the step's declared signals. Inline `Computed.X(...)` tokens can
48
+ * also appear in the signal position; they're hoisted into the step's
49
+ * `computedSignalDefinitions` at serialization time.
47
50
  * Defaults to `{ defaultOutcome: "continue" }` when omitted.
48
51
  */
49
52
  advancement?: AdvancementPolicy<TStep["__signalKeys"]>;
@@ -73,6 +76,7 @@ export type PipelineDefinitionSpec = {
73
76
  inputBindingsJson: Record<string, SerializedBinding>;
74
77
  timeoutSeconds: number | null;
75
78
  advancementPolicyDefinition: SerializedAdvancementPolicy;
79
+ computedSignalDefinitions: SerializedComputedSignalDefinition[];
76
80
  }>;
77
81
  };
78
82
  /**
@@ -92,7 +96,10 @@ export type DefinePipelineInput = {
92
96
  * Defines a pipeline from an ordered list of step configs.
93
97
  *
94
98
  * Each step's `advancement` policy is typed against that step's declared signal
95
- * keys — passing an unknown signal key to `whenSignal()` is a compile-time error.
99
+ * keys — passing an unknown signal key to `Rule.signal()` / `Rule.when()` is a
100
+ * compile-time error. Inline `Computed.X(...)` tokens can also be used in the
101
+ * signal position; they're walked out of the rules tree at serialization time
102
+ * and emitted as the step's `computedSignalDefinitions`.
96
103
  *
97
104
  * TypeScript achieves per-element signal key checking by constraining `TSteps`
98
105
  * to a tuple of step instances (`AnyTypedStep[]`), not step configs. Each element
@@ -14,6 +14,27 @@ var __export = (target, all) => {
14
14
  };
15
15
 
16
16
  // src/definitions/advancement-policies/define-advancement-policy.ts
17
+ function makeComputed(type, inputSignalKeys, options) {
18
+ const key = [type, ...inputSignalKeys].join("_");
19
+ return {
20
+ _tag: "computed_signal",
21
+ key,
22
+ type,
23
+ inputSignalKeys,
24
+ configJson: options?.configJson ?? null,
25
+ availableWhenResultStatusIn: options?.availableWhenResultStatusIn ?? null
26
+ };
27
+ }
28
+ var Computed = {
29
+ average: (inputSignalKeys, options) => makeComputed("average", inputSignalKeys, options),
30
+ weightedAverage: (inputSignalKeys, options) => makeComputed("weighted_average", inputSignalKeys, options),
31
+ sum: (inputSignalKeys, options) => makeComputed("sum", inputSignalKeys, options),
32
+ min: (inputSignalKeys, options) => makeComputed("min", inputSignalKeys, options),
33
+ max: (inputSignalKeys, options) => makeComputed("max", inputSignalKeys, options),
34
+ count: (inputSignalKeys, options) => makeComputed("count", inputSignalKeys, options),
35
+ booleanAny: (inputSignalKeys, options) => makeComputed("boolean_any", inputSignalKeys, options),
36
+ booleanAll: (inputSignalKeys, options) => makeComputed("boolean_all", inputSignalKeys, options)
37
+ };
17
38
  function signal(signal2, operator, value) {
18
39
  return { _tag: "signal", signal: signal2, operator, value };
19
40
  }
@@ -47,7 +68,7 @@ function resolveOutcome(outcome) {
47
68
  function serializeCondition(condition) {
48
69
  if (condition._tag === "signal") {
49
70
  return {
50
- fact: condition.signal,
71
+ fact: typeof condition.signal === "string" ? condition.signal : condition.signal.key,
51
72
  operator: condition.operator,
52
73
  value: condition.value
53
74
  };
@@ -89,6 +110,46 @@ function serializeAdvancementPolicy(policy) {
89
110
  allowedEventTypes: [...outcomeSet]
90
111
  };
91
112
  }
113
+ function visitSignalConditions(conditions, visit) {
114
+ for (const c of conditions) {
115
+ if (c._tag === "signal") {
116
+ visit(c);
117
+ } else {
118
+ visitSignalConditions(c.conditions, visit);
119
+ }
120
+ }
121
+ }
122
+ function isSameComputedDefinition(a, b) {
123
+ return a.type === b.type && a.inputSignalKeys.length === b.inputSignalKeys.length && a.inputSignalKeys.every((k, i) => k === b.inputSignalKeys[i]) && JSON.stringify(a.configJson) === JSON.stringify(b.configJson) && JSON.stringify(a.availableWhenResultStatusIn) === JSON.stringify(b.availableWhenResultStatusIn);
124
+ }
125
+ function extractInlineComputedSignals(policy) {
126
+ if (!policy?.rules)
127
+ return [];
128
+ const byKey = new Map;
129
+ for (const rule of policy.rules) {
130
+ visitSignalConditions(rule.conditions, (cond) => {
131
+ if (typeof cond.signal === "string")
132
+ return;
133
+ const inline = cond.signal;
134
+ const def = {
135
+ key: inline.key,
136
+ type: inline.type,
137
+ inputSignalKeys: [...inline.inputSignalKeys],
138
+ configJson: inline.configJson,
139
+ availableWhenResultStatusIn: inline.availableWhenResultStatusIn ? [...inline.availableWhenResultStatusIn] : null
140
+ };
141
+ const existing = byKey.get(def.key);
142
+ if (existing) {
143
+ if (!isSameComputedDefinition(existing, def)) {
144
+ throw new Error(`Conflicting inline computed signal definitions for key "${def.key}"`);
145
+ }
146
+ return;
147
+ }
148
+ byKey.set(def.key, def);
149
+ });
150
+ }
151
+ return [...byKey.values()];
152
+ }
92
153
 
93
154
  // src/definitions/pipelines/define-pipeline.ts
94
155
  function fromPipelineInput(_schema, path) {
@@ -128,7 +189,8 @@ function definePipeline(config) {
128
189
  position: index + 1,
129
190
  inputBindingsJson: Object.fromEntries(Object.entries(stepConfig.input ?? {}).filter((entry) => entry[1] !== undefined).map(([key, binding]) => [key, serializeBinding(binding)])),
130
191
  timeoutSeconds: stepConfig.timeout ?? null,
131
- advancementPolicyDefinition: serializeAdvancementPolicy(stepConfig.advancement)
192
+ advancementPolicyDefinition: serializeAdvancementPolicy(stepConfig.advancement),
193
+ computedSignalDefinitions: extractInlineComputedSignals(stepConfig.advancement)
132
194
  }))
133
195
  };
134
196
  }
@@ -179,5 +241,6 @@ export {
179
241
  fromPipelineInput,
180
242
  definePipeline,
181
243
  createPipelineDefinitionsClient,
182
- Rule
244
+ Rule,
245
+ Computed
183
246
  };
@@ -43,13 +43,6 @@ export type StepSignalSpec = {
43
43
  required?: boolean;
44
44
  availableWhenResultStatusIn?: string[] | null;
45
45
  };
46
- export type StepComputedSignalSpec = {
47
- key: string;
48
- type: "average" | "weighted_average" | "sum" | "min" | "max" | "custom";
49
- inputSignalKeys: string[];
50
- configJson?: Record<string, unknown> | null;
51
- availableWhenResultStatusIn?: string[] | null;
52
- };
53
46
  export type DefineStepInput<TInput extends ZodType = ZodType, TResult extends ZodType = ZodType> = {
54
47
  key: string;
55
48
  name: string;
@@ -59,7 +52,6 @@ export type DefineStepInput<TInput extends ZodType = ZodType, TResult extends Zo
59
52
  input?: TInput;
60
53
  result?: TResult;
61
54
  signals?: SignalSpecInput<TResult["_output"]>[];
62
- computedSignals?: StepComputedSignalSpec[];
63
55
  features?: AnyStepFeature[];
64
56
  mcpServers?: OpenCodeMcpServers | null;
65
57
  status?: "draft" | "active";
@@ -81,13 +73,6 @@ export type StepDefinitionSpec = {
81
73
  required: boolean;
82
74
  availableWhenResultStatusIn: string[] | null;
83
75
  }>;
84
- computedSignalDefinitions: Array<{
85
- key: string;
86
- type: "average" | "weighted_average" | "sum" | "min" | "max" | "custom";
87
- inputSignalKeys: string[];
88
- configJson: Record<string, unknown> | null;
89
- availableWhenResultStatusIn: string[] | null;
90
- }>;
91
76
  opencodeMcpJson: OpenCodeMcpServers | null;
92
77
  };
93
78
  export type TypedStepDefinitionSpec<TInput = unknown, TResult = unknown, TSignalKeys extends string = string> = StepDefinitionSpec & {
@@ -12026,13 +12026,6 @@ ${feature._promptAddition}` : feature._promptAddition;
12026
12026
  availableWhenResultStatusIn: s.availableWhenResultStatusIn ?? null
12027
12027
  }))
12028
12028
  ],
12029
- computedSignalDefinitions: (config2.computedSignals ?? []).map((cs) => ({
12030
- key: cs.key,
12031
- type: cs.type,
12032
- inputSignalKeys: cs.inputSignalKeys,
12033
- configJson: cs.configJson ?? null,
12034
- availableWhenResultStatusIn: cs.availableWhenResultStatusIn ?? null
12035
- })),
12036
12029
  opencodeMcpJson: config2.mcpServers ?? null
12037
12030
  };
12038
12031
  return spec;
@@ -56,16 +56,6 @@ declare const buildStepDefinitionsClient: (stepDefinitions: StepDefinitions) =>
56
56
  createdAt: string;
57
57
  updatedAt: string;
58
58
  }>;
59
- computedSignalDefinitions: Array<{
60
- id: string;
61
- key: string;
62
- type: "average" | "weighted_average" | "sum" | "min" | "max" | "custom";
63
- inputSignalKeys: Array<string>;
64
- configJson: unknown;
65
- availableWhenResultStatusIn: Array<string> | unknown;
66
- createdAt: string;
67
- updatedAt: string;
68
- }>;
69
59
  createdAt: string;
70
60
  updatedAt: string;
71
61
  }[]>;
@@ -118,16 +108,6 @@ declare const buildStepDefinitionsClient: (stepDefinitions: StepDefinitions) =>
118
108
  createdAt: string;
119
109
  updatedAt: string;
120
110
  }>;
121
- computedSignalDefinitions: Array<{
122
- id: string;
123
- key: string;
124
- type: "average" | "weighted_average" | "sum" | "min" | "max" | "custom";
125
- inputSignalKeys: Array<string>;
126
- configJson: unknown;
127
- availableWhenResultStatusIn: Array<string> | unknown;
128
- createdAt: string;
129
- updatedAt: string;
130
- }>;
131
111
  createdAt: string;
132
112
  updatedAt: string;
133
113
  }>;
@@ -180,16 +160,6 @@ declare const buildStepDefinitionsClient: (stepDefinitions: StepDefinitions) =>
180
160
  createdAt: string;
181
161
  updatedAt: string;
182
162
  }>;
183
- computedSignalDefinitions: Array<{
184
- id: string;
185
- key: string;
186
- type: "average" | "weighted_average" | "sum" | "min" | "max" | "custom";
187
- inputSignalKeys: Array<string>;
188
- configJson: unknown;
189
- availableWhenResultStatusIn: Array<string> | unknown;
190
- createdAt: string;
191
- updatedAt: string;
192
- }>;
193
163
  createdAt: string;
194
164
  updatedAt: string;
195
165
  }>;
@@ -690,16 +690,6 @@ export type GetApiStepDefinitionsResponses = {
690
690
  createdAt: string;
691
691
  updatedAt: string;
692
692
  }>;
693
- computedSignalDefinitions: Array<{
694
- id: string;
695
- key: string;
696
- type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'custom';
697
- inputSignalKeys: Array<string>;
698
- configJson: unknown;
699
- availableWhenResultStatusIn: Array<string> | unknown;
700
- createdAt: string;
701
- updatedAt: string;
702
- }>;
703
693
  createdAt: string;
704
694
  updatedAt: string;
705
695
  }>;
@@ -751,13 +741,6 @@ export type PostApiStepDefinitionsData = {
751
741
  required: boolean;
752
742
  availableWhenResultStatusIn: Array<string> | unknown;
753
743
  }>;
754
- computedSignalDefinitions: Array<{
755
- key: string;
756
- type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'custom';
757
- inputSignalKeys: Array<string>;
758
- configJson: unknown;
759
- availableWhenResultStatusIn: Array<string> | unknown;
760
- }>;
761
744
  };
762
745
  path?: never;
763
746
  query?: never;
@@ -931,16 +914,6 @@ export type PostApiStepDefinitionsResponses = {
931
914
  createdAt: string;
932
915
  updatedAt: string;
933
916
  }>;
934
- computedSignalDefinitions: Array<{
935
- id: string;
936
- key: string;
937
- type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'custom';
938
- inputSignalKeys: Array<string>;
939
- configJson: unknown;
940
- availableWhenResultStatusIn: Array<string> | unknown;
941
- createdAt: string;
942
- updatedAt: string;
943
- }>;
944
917
  createdAt: string;
945
918
  updatedAt: string;
946
919
  };
@@ -1090,16 +1063,6 @@ export type GetApiStepDefinitionsByStepDefinitionIdResponses = {
1090
1063
  createdAt: string;
1091
1064
  updatedAt: string;
1092
1065
  }>;
1093
- computedSignalDefinitions: Array<{
1094
- id: string;
1095
- key: string;
1096
- type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'custom';
1097
- inputSignalKeys: Array<string>;
1098
- configJson: unknown;
1099
- availableWhenResultStatusIn: Array<string> | unknown;
1100
- createdAt: string;
1101
- updatedAt: string;
1102
- }>;
1103
1066
  createdAt: string;
1104
1067
  updatedAt: string;
1105
1068
  };
@@ -1151,13 +1114,6 @@ export type PutApiStepDefinitionsByStepDefinitionIdData = {
1151
1114
  required: boolean;
1152
1115
  availableWhenResultStatusIn: Array<string> | unknown;
1153
1116
  }>;
1154
- computedSignalDefinitions: Array<{
1155
- key: string;
1156
- type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'custom';
1157
- inputSignalKeys: Array<string>;
1158
- configJson: unknown;
1159
- availableWhenResultStatusIn: Array<string> | unknown;
1160
- }>;
1161
1117
  };
1162
1118
  path: {
1163
1119
  stepDefinitionId: string;
@@ -1301,16 +1257,6 @@ export type PutApiStepDefinitionsByStepDefinitionIdResponses = {
1301
1257
  createdAt: string;
1302
1258
  updatedAt: string;
1303
1259
  }>;
1304
- computedSignalDefinitions: Array<{
1305
- id: string;
1306
- key: string;
1307
- type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'custom';
1308
- inputSignalKeys: Array<string>;
1309
- configJson: unknown;
1310
- availableWhenResultStatusIn: Array<string> | unknown;
1311
- createdAt: string;
1312
- updatedAt: string;
1313
- }>;
1314
1260
  createdAt: string;
1315
1261
  updatedAt: string;
1316
1262
  };
@@ -1460,16 +1406,6 @@ export type PutApiStepDefinitionsByStepDefinitionIdArchiveResponses = {
1460
1406
  createdAt: string;
1461
1407
  updatedAt: string;
1462
1408
  }>;
1463
- computedSignalDefinitions: Array<{
1464
- id: string;
1465
- key: string;
1466
- type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'custom';
1467
- inputSignalKeys: Array<string>;
1468
- configJson: unknown;
1469
- availableWhenResultStatusIn: Array<string> | unknown;
1470
- createdAt: string;
1471
- updatedAt: string;
1472
- }>;
1473
1409
  createdAt: string;
1474
1410
  updatedAt: string;
1475
1411
  };
@@ -3097,6 +3033,18 @@ export type GetApiLinearPipelineDefinitionsResponses = {
3097
3033
  createdAt: string;
3098
3034
  updatedAt: string;
3099
3035
  };
3036
+ computedSignalDefinitions: Array<{
3037
+ id: string;
3038
+ key: string;
3039
+ type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'count' | 'boolean_any' | 'boolean_all';
3040
+ inputSignalKeys: Array<string>;
3041
+ configJson: {
3042
+ [key: string]: unknown;
3043
+ } | unknown;
3044
+ availableWhenResultStatusIn: Array<string> | unknown;
3045
+ createdAt: string;
3046
+ updatedAt: string;
3047
+ }>;
3100
3048
  createdAt: string;
3101
3049
  updatedAt: string;
3102
3050
  }>;
@@ -3192,6 +3140,15 @@ export type PostApiLinearPipelineDefinitionsData = {
3192
3140
  } | unknown;
3193
3141
  allowedEventTypes: Array<'continue' | 'block' | 'needs_review' | 'complete'>;
3194
3142
  };
3143
+ computedSignalDefinitions: Array<{
3144
+ key: string;
3145
+ type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'count' | 'boolean_any' | 'boolean_all';
3146
+ inputSignalKeys: Array<string>;
3147
+ configJson: {
3148
+ [key: string]: unknown;
3149
+ } | unknown;
3150
+ availableWhenResultStatusIn: Array<string> | unknown;
3151
+ }>;
3195
3152
  }>;
3196
3153
  };
3197
3154
  path?: never;
@@ -3410,6 +3367,18 @@ export type PostApiLinearPipelineDefinitionsResponses = {
3410
3367
  createdAt: string;
3411
3368
  updatedAt: string;
3412
3369
  };
3370
+ computedSignalDefinitions: Array<{
3371
+ id: string;
3372
+ key: string;
3373
+ type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'count' | 'boolean_any' | 'boolean_all';
3374
+ inputSignalKeys: Array<string>;
3375
+ configJson: {
3376
+ [key: string]: unknown;
3377
+ } | unknown;
3378
+ availableWhenResultStatusIn: Array<string> | unknown;
3379
+ createdAt: string;
3380
+ updatedAt: string;
3381
+ }>;
3413
3382
  createdAt: string;
3414
3383
  updatedAt: string;
3415
3384
  }>;
@@ -3505,6 +3474,15 @@ export type PutApiLinearPipelineDefinitionsData = {
3505
3474
  } | unknown;
3506
3475
  allowedEventTypes: Array<'continue' | 'block' | 'needs_review' | 'complete'>;
3507
3476
  };
3477
+ computedSignalDefinitions: Array<{
3478
+ key: string;
3479
+ type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'count' | 'boolean_any' | 'boolean_all';
3480
+ inputSignalKeys: Array<string>;
3481
+ configJson: {
3482
+ [key: string]: unknown;
3483
+ } | unknown;
3484
+ availableWhenResultStatusIn: Array<string> | unknown;
3485
+ }>;
3508
3486
  }>;
3509
3487
  };
3510
3488
  path?: never;
@@ -3675,6 +3653,18 @@ export type PutApiLinearPipelineDefinitionsResponses = {
3675
3653
  createdAt: string;
3676
3654
  updatedAt: string;
3677
3655
  };
3656
+ computedSignalDefinitions: Array<{
3657
+ id: string;
3658
+ key: string;
3659
+ type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'count' | 'boolean_any' | 'boolean_all';
3660
+ inputSignalKeys: Array<string>;
3661
+ configJson: {
3662
+ [key: string]: unknown;
3663
+ } | unknown;
3664
+ availableWhenResultStatusIn: Array<string> | unknown;
3665
+ createdAt: string;
3666
+ updatedAt: string;
3667
+ }>;
3678
3668
  createdAt: string;
3679
3669
  updatedAt: string;
3680
3670
  }>;
@@ -3887,6 +3877,18 @@ export type GetApiLinearPipelineDefinitionsByLinearPipelineDefinitionIdResponses
3887
3877
  createdAt: string;
3888
3878
  updatedAt: string;
3889
3879
  };
3880
+ computedSignalDefinitions: Array<{
3881
+ id: string;
3882
+ key: string;
3883
+ type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'count' | 'boolean_any' | 'boolean_all';
3884
+ inputSignalKeys: Array<string>;
3885
+ configJson: {
3886
+ [key: string]: unknown;
3887
+ } | unknown;
3888
+ availableWhenResultStatusIn: Array<string> | unknown;
3889
+ createdAt: string;
3890
+ updatedAt: string;
3891
+ }>;
3890
3892
  createdAt: string;
3891
3893
  updatedAt: string;
3892
3894
  }>;
@@ -4083,6 +4085,18 @@ export type PutApiLinearPipelineDefinitionsByLinearPipelineDefinitionIdArchiveRe
4083
4085
  createdAt: string;
4084
4086
  updatedAt: string;
4085
4087
  };
4088
+ computedSignalDefinitions: Array<{
4089
+ id: string;
4090
+ key: string;
4091
+ type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'count' | 'boolean_any' | 'boolean_all';
4092
+ inputSignalKeys: Array<string>;
4093
+ configJson: {
4094
+ [key: string]: unknown;
4095
+ } | unknown;
4096
+ availableWhenResultStatusIn: Array<string> | unknown;
4097
+ createdAt: string;
4098
+ updatedAt: string;
4099
+ }>;
4086
4100
  createdAt: string;
4087
4101
  updatedAt: string;
4088
4102
  }>;
@@ -4171,6 +4185,15 @@ export type PostApiLinearPipelineDefinitionsByLinearPipelineDefinitionIdStepsDat
4171
4185
  } | unknown;
4172
4186
  allowedEventTypes: Array<'continue' | 'block' | 'needs_review' | 'complete'>;
4173
4187
  };
4188
+ computedSignalDefinitions: Array<{
4189
+ key: string;
4190
+ type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'count' | 'boolean_any' | 'boolean_all';
4191
+ inputSignalKeys: Array<string>;
4192
+ configJson: {
4193
+ [key: string]: unknown;
4194
+ } | unknown;
4195
+ availableWhenResultStatusIn: Array<string> | unknown;
4196
+ }>;
4174
4197
  };
4175
4198
  path: {
4176
4199
  linearPipelineDefinitionId: string;
@@ -4358,6 +4381,18 @@ export type PostApiLinearPipelineDefinitionsByLinearPipelineDefinitionIdStepsRes
4358
4381
  createdAt: string;
4359
4382
  updatedAt: string;
4360
4383
  };
4384
+ computedSignalDefinitions: Array<{
4385
+ id: string;
4386
+ key: string;
4387
+ type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'count' | 'boolean_any' | 'boolean_all';
4388
+ inputSignalKeys: Array<string>;
4389
+ configJson: {
4390
+ [key: string]: unknown;
4391
+ } | unknown;
4392
+ availableWhenResultStatusIn: Array<string> | unknown;
4393
+ createdAt: string;
4394
+ updatedAt: string;
4395
+ }>;
4361
4396
  createdAt: string;
4362
4397
  updatedAt: string;
4363
4398
  }>;
@@ -4555,6 +4590,18 @@ export type DeleteApiLinearPipelineDefinitionsByLinearPipelineDefinitionIdStepsB
4555
4590
  createdAt: string;
4556
4591
  updatedAt: string;
4557
4592
  };
4593
+ computedSignalDefinitions: Array<{
4594
+ id: string;
4595
+ key: string;
4596
+ type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'count' | 'boolean_any' | 'boolean_all';
4597
+ inputSignalKeys: Array<string>;
4598
+ configJson: {
4599
+ [key: string]: unknown;
4600
+ } | unknown;
4601
+ availableWhenResultStatusIn: Array<string> | unknown;
4602
+ createdAt: string;
4603
+ updatedAt: string;
4604
+ }>;
4558
4605
  createdAt: string;
4559
4606
  updatedAt: string;
4560
4607
  }>;
@@ -4643,6 +4690,15 @@ export type PutApiLinearPipelineDefinitionsByLinearPipelineDefinitionIdStepsByLi
4643
4690
  } | unknown;
4644
4691
  allowedEventTypes: Array<'continue' | 'block' | 'needs_review' | 'complete'>;
4645
4692
  };
4693
+ computedSignalDefinitions: Array<{
4694
+ key: string;
4695
+ type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'count' | 'boolean_any' | 'boolean_all';
4696
+ inputSignalKeys: Array<string>;
4697
+ configJson: {
4698
+ [key: string]: unknown;
4699
+ } | unknown;
4700
+ availableWhenResultStatusIn: Array<string> | unknown;
4701
+ }>;
4646
4702
  };
4647
4703
  path: {
4648
4704
  linearPipelineDefinitionId: string;
@@ -4831,6 +4887,18 @@ export type PutApiLinearPipelineDefinitionsByLinearPipelineDefinitionIdStepsByLi
4831
4887
  createdAt: string;
4832
4888
  updatedAt: string;
4833
4889
  };
4890
+ computedSignalDefinitions: Array<{
4891
+ id: string;
4892
+ key: string;
4893
+ type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'count' | 'boolean_any' | 'boolean_all';
4894
+ inputSignalKeys: Array<string>;
4895
+ configJson: {
4896
+ [key: string]: unknown;
4897
+ } | unknown;
4898
+ availableWhenResultStatusIn: Array<string> | unknown;
4899
+ createdAt: string;
4900
+ updatedAt: string;
4901
+ }>;
4834
4902
  createdAt: string;
4835
4903
  updatedAt: string;
4836
4904
  }>;
@@ -5076,6 +5144,18 @@ export type PutApiLinearPipelineDefinitionsByLinearPipelineDefinitionIdStepsByLi
5076
5144
  createdAt: string;
5077
5145
  updatedAt: string;
5078
5146
  };
5147
+ computedSignalDefinitions: Array<{
5148
+ id: string;
5149
+ key: string;
5150
+ type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'count' | 'boolean_any' | 'boolean_all';
5151
+ inputSignalKeys: Array<string>;
5152
+ configJson: {
5153
+ [key: string]: unknown;
5154
+ } | unknown;
5155
+ availableWhenResultStatusIn: Array<string> | unknown;
5156
+ createdAt: string;
5157
+ updatedAt: string;
5158
+ }>;
5079
5159
  createdAt: string;
5080
5160
  updatedAt: string;
5081
5161
  }>;
@@ -9125,16 +9205,6 @@ export type PostApiStepDefinitionTemplatesByStepDefinitionTemplateIdInstantiateR
9125
9205
  createdAt: string;
9126
9206
  updatedAt: string;
9127
9207
  }>;
9128
- computedSignalDefinitions: Array<{
9129
- id: string;
9130
- key: string;
9131
- type: 'average' | 'weighted_average' | 'sum' | 'min' | 'max' | 'custom';
9132
- inputSignalKeys: Array<string>;
9133
- configJson: unknown;
9134
- availableWhenResultStatusIn: Array<string> | unknown;
9135
- createdAt: string;
9136
- updatedAt: string;
9137
- }>;
9138
9208
  createdAt: string;
9139
9209
  updatedAt: string;
9140
9210
  };
package/dist/index.js CHANGED
@@ -13369,13 +13369,6 @@ ${feature._promptAddition}` : feature._promptAddition;
13369
13369
  availableWhenResultStatusIn: s.availableWhenResultStatusIn ?? null
13370
13370
  }))
13371
13371
  ],
13372
- computedSignalDefinitions: (config2.computedSignals ?? []).map((cs) => ({
13373
- key: cs.key,
13374
- type: cs.type,
13375
- inputSignalKeys: cs.inputSignalKeys,
13376
- configJson: cs.configJson ?? null,
13377
- availableWhenResultStatusIn: cs.availableWhenResultStatusIn ?? null
13378
- })),
13379
13372
  opencodeMcpJson: config2.mcpServers ?? null
13380
13373
  };
13381
13374
  return spec;
@@ -15804,6 +15797,27 @@ var Features = {
15804
15797
  })
15805
15798
  };
15806
15799
  // src/definitions/advancement-policies/define-advancement-policy.ts
15800
+ function makeComputed(type, inputSignalKeys, options) {
15801
+ const key = [type, ...inputSignalKeys].join("_");
15802
+ return {
15803
+ _tag: "computed_signal",
15804
+ key,
15805
+ type,
15806
+ inputSignalKeys,
15807
+ configJson: options?.configJson ?? null,
15808
+ availableWhenResultStatusIn: options?.availableWhenResultStatusIn ?? null
15809
+ };
15810
+ }
15811
+ var Computed = {
15812
+ average: (inputSignalKeys, options) => makeComputed("average", inputSignalKeys, options),
15813
+ weightedAverage: (inputSignalKeys, options) => makeComputed("weighted_average", inputSignalKeys, options),
15814
+ sum: (inputSignalKeys, options) => makeComputed("sum", inputSignalKeys, options),
15815
+ min: (inputSignalKeys, options) => makeComputed("min", inputSignalKeys, options),
15816
+ max: (inputSignalKeys, options) => makeComputed("max", inputSignalKeys, options),
15817
+ count: (inputSignalKeys, options) => makeComputed("count", inputSignalKeys, options),
15818
+ booleanAny: (inputSignalKeys, options) => makeComputed("boolean_any", inputSignalKeys, options),
15819
+ booleanAll: (inputSignalKeys, options) => makeComputed("boolean_all", inputSignalKeys, options)
15820
+ };
15807
15821
  function signal(signal2, operator, value) {
15808
15822
  return { _tag: "signal", signal: signal2, operator, value };
15809
15823
  }
@@ -15837,7 +15851,7 @@ function resolveOutcome(outcome) {
15837
15851
  function serializeCondition(condition) {
15838
15852
  if (condition._tag === "signal") {
15839
15853
  return {
15840
- fact: condition.signal,
15854
+ fact: typeof condition.signal === "string" ? condition.signal : condition.signal.key,
15841
15855
  operator: condition.operator,
15842
15856
  value: condition.value
15843
15857
  };
@@ -15879,6 +15893,46 @@ function serializeAdvancementPolicy(policy) {
15879
15893
  allowedEventTypes: [...outcomeSet]
15880
15894
  };
15881
15895
  }
15896
+ function visitSignalConditions(conditions, visit) {
15897
+ for (const c of conditions) {
15898
+ if (c._tag === "signal") {
15899
+ visit(c);
15900
+ } else {
15901
+ visitSignalConditions(c.conditions, visit);
15902
+ }
15903
+ }
15904
+ }
15905
+ function isSameComputedDefinition(a, b) {
15906
+ return a.type === b.type && a.inputSignalKeys.length === b.inputSignalKeys.length && a.inputSignalKeys.every((k, i) => k === b.inputSignalKeys[i]) && JSON.stringify(a.configJson) === JSON.stringify(b.configJson) && JSON.stringify(a.availableWhenResultStatusIn) === JSON.stringify(b.availableWhenResultStatusIn);
15907
+ }
15908
+ function extractInlineComputedSignals(policy) {
15909
+ if (!policy?.rules)
15910
+ return [];
15911
+ const byKey = new Map;
15912
+ for (const rule of policy.rules) {
15913
+ visitSignalConditions(rule.conditions, (cond) => {
15914
+ if (typeof cond.signal === "string")
15915
+ return;
15916
+ const inline = cond.signal;
15917
+ const def = {
15918
+ key: inline.key,
15919
+ type: inline.type,
15920
+ inputSignalKeys: [...inline.inputSignalKeys],
15921
+ configJson: inline.configJson,
15922
+ availableWhenResultStatusIn: inline.availableWhenResultStatusIn ? [...inline.availableWhenResultStatusIn] : null
15923
+ };
15924
+ const existing = byKey.get(def.key);
15925
+ if (existing) {
15926
+ if (!isSameComputedDefinition(existing, def)) {
15927
+ throw new Error(`Conflicting inline computed signal definitions for key "${def.key}"`);
15928
+ }
15929
+ return;
15930
+ }
15931
+ byKey.set(def.key, def);
15932
+ });
15933
+ }
15934
+ return [...byKey.values()];
15935
+ }
15882
15936
 
15883
15937
  // src/definitions/pipelines/define-pipeline.ts
15884
15938
  function fromPipelineInput(_schema, path) {
@@ -15918,7 +15972,8 @@ function definePipeline(config2) {
15918
15972
  position: index + 1,
15919
15973
  inputBindingsJson: Object.fromEntries(Object.entries(stepConfig.input ?? {}).filter((entry) => entry[1] !== undefined).map(([key, binding]) => [key, serializeBinding(binding)])),
15920
15974
  timeoutSeconds: stepConfig.timeout ?? null,
15921
- advancementPolicyDefinition: serializeAdvancementPolicy(stepConfig.advancement)
15975
+ advancementPolicyDefinition: serializeAdvancementPolicy(stepConfig.advancement),
15976
+ computedSignalDefinitions: extractInlineComputedSignals(stepConfig.advancement)
15922
15977
  }))
15923
15978
  };
15924
15979
  }
@@ -16633,6 +16688,7 @@ export {
16633
16688
  PipelineDefinitions,
16634
16689
  FeedbackRequests,
16635
16690
  Features,
16691
+ Computed,
16636
16692
  BoboddyClient,
16637
16693
  BOBODDY_CONFIG_RELATIVE_PATH,
16638
16694
  Api
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@boboddy/sdk",
4
- "version": "0.1.5-alpha",
4
+ "version": "0.1.7-alpha",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": {