@boboddy/sdk 0.5.0 → 0.5.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.
@@ -43,3 +43,32 @@ export declare function enumeratePaths(node: JsonSchemaNode, root: JsonSchemaNod
43
43
  * `$ref`s are resolved against the root.
44
44
  */
45
45
  export declare function resolveSourcePath(schema: JsonSchemaNode, sourcePath: string): PathResolution;
46
+ /**
47
+ * The type vocabulary a schema node is reduced to. `"integer"` (a JSON
48
+ * Schema refinement Zod emits for `z.number().int()`) collapses into
49
+ * `"number"`; anything the schema doesn't pin to exactly one of these is
50
+ * `"unknown"`.
51
+ */
52
+ export type SchemaType = "string" | "number" | "boolean" | "object" | "array" | "null" | "unknown";
53
+ /**
54
+ * Reduces a JSON Schema node to its top-level type, per `SchemaType`.
55
+ *
56
+ * Follows the same `$ref` / `anyOf` / `oneOf` / `allOf` flattening
57
+ * `resolveSourcePath` uses, so a `$ref` is resolved against `root` (default:
58
+ * `node` itself — pass the document root explicitly when `node` came from
59
+ * deeper inside it). Returns `"unknown"` — never a guess — when: the schema
60
+ * is absent (`{}`, e.g. `z.unknown()`) or a boolean schema (`true` / `false`);
61
+ * a `$ref` fails to resolve; or the branches disagree on type (a union of
62
+ * a string and a number, say). A false "this is definitely a string" is
63
+ * worse than an honest "unknown" here, same bias as path resolution.
64
+ */
65
+ export declare function resolveSchemaType(node: JsonSchemaNode, root?: JsonSchemaNode): SchemaType;
66
+ /**
67
+ * The type `sourcePath` resolves to within `schema` — `"unknown"` whenever
68
+ * the path doesn't provably resolve to a single node (indeterminate or
69
+ * invalid) or the node it resolves to doesn't pin down a single type.
70
+ *
71
+ * Pass the step's `resultSchemaJson` as `schema`; `$ref`s are resolved
72
+ * against it as the document root, matching `resolveSourcePath`.
73
+ */
74
+ export declare function resolvePathType(schema: JsonSchemaNode, sourcePath: string): SchemaType;
@@ -1,5 +1,6 @@
1
1
  import { type PipelineDefinitionSpec } from "../pipelines/define-pipeline";
2
2
  import type { StepDefinitionSpec } from "../steps/define-step";
3
+ import { type DefinitionValidationIssue } from "./validation-issue";
3
4
  export type DefinitionSpecSet = {
4
5
  readonly pipelines: readonly PipelineDefinitionSpec[];
5
6
  readonly steps: readonly StepDefinitionSpec[];
@@ -12,32 +13,20 @@ export type ValidateDefinitionSpecsOptions = {
12
13
  */
13
14
  readonly knownPipelineKeys?: readonly string[];
14
15
  };
15
- export type DefinitionValidationIssue = {
16
- readonly check: "signal-source-path" | "route-target" | "signal-binding" | "health-check-mcp-server" | "health-check-double-qualified";
17
- readonly message: string;
18
- /**
19
- * The pipeline this issue belongs to, when the check is pipeline-scoped
20
- * (`route-target`/`signal-binding`) — absent for step-only checks
21
- * (`signal-source-path`/`health-check-*`), which have no pipeline
22
- * context of their own. Required before the designer (Phase 5) can
23
- * attach an error to the right graph node.
24
- */
25
- readonly pipelineKey?: string;
26
- /** The node this issue is about, when pipeline-scoped. */
27
- readonly nodeKey?: string;
28
- /**
29
- * A second, related node this issue is about — e.g. `signal-binding`'s
30
- * producer node, when different from `nodeKey`'s consumer. Absent when
31
- * the issue is about a single node, or when the "other end" isn't a
32
- * node in this pipeline at all (`route-target`'s target is a different
33
- * *pipeline*, not a node).
34
- */
35
- readonly targetNodeKey?: string;
36
- };
37
16
  /**
38
17
  * Runs every offline check over a batch of definitions and returns the issues
39
18
  * found, in check order. An empty array means the batch is clean.
40
19
  */
41
20
  export declare function validateDefinitionSpecs(specs: DefinitionSpecSet, options?: ValidateDefinitionSpecsOptions): DefinitionValidationIssue[];
42
- /** `validateDefinitionSpecs`, but throws a single aggregated error. */
21
+ /**
22
+ * `validateDefinitionSpecs`, but throws a single aggregated error.
23
+ *
24
+ * Only counts and lists `severity: "error"` issues — `"warning"`-tier issues
25
+ * (`binding-type-mismatch`) and `"info"`-tier issues (`binding-target-field`'s
26
+ * unbound-field-name sub-check) never block a push and are silently dropped
27
+ * from both the header count and the body here. They're still present in
28
+ * `validateDefinitionSpecs`'s own return value for any caller that wants to
29
+ * surface them (e.g. the designer, in a later phase); this is the one entry
30
+ * point whose whole job is "should this push be blocked."
31
+ */
43
32
  export declare function assertValidDefinitionSpecs(specs: DefinitionSpecSet, options?: ValidateDefinitionSpecsOptions): void;
@@ -0,0 +1,7 @@
1
+ import { type PipelineDefinitionSpec } from "../pipelines/define-pipeline";
2
+ import type { StepDefinitionSpec } from "../steps/define-step";
3
+ import { type DefinitionValidationIssue } from "./validation-issue";
4
+ declare function checkUnboundRequiredInputs(pipelines: readonly PipelineDefinitionSpec[], stepsByKey: Map<string, readonly StepDefinitionSpec[]>): DefinitionValidationIssue[];
5
+ declare function checkBindingTargetFields(pipelines: readonly PipelineDefinitionSpec[], stepsByKey: Map<string, readonly StepDefinitionSpec[]>): DefinitionValidationIssue[];
6
+ declare function checkBindingTypeCompatibility(pipelines: readonly PipelineDefinitionSpec[], stepsByKey: Map<string, readonly StepDefinitionSpec[]>): DefinitionValidationIssue[];
7
+ export { checkBindingTargetFields, checkBindingTypeCompatibility, checkUnboundRequiredInputs, };
@@ -0,0 +1,52 @@
1
+ export type DefinitionValidationIssue = {
2
+ readonly check: "signal-source-path" | "route-target" | "signal-binding" | "health-check-mcp-server" | "health-check-double-qualified" | "unbound-required-input" | "binding-target-field" | "binding-type-mismatch";
3
+ /**
4
+ * Whether this issue blocks a push. The 4 original checks are all
5
+ * unconditionally `"error"`, matching their implicit all-blocking
6
+ * behavior before this field existed. `"binding-type-mismatch"` is a
7
+ * `"warning"`-tier check — a resolved type disagreement is worth
8
+ * surfacing but, per §4's own bias, never provably a runtime failure the
9
+ * way an unresolved binding or a missing required input is.
10
+ * `"binding-target-field"`'s "unbound field name isn't a declared
11
+ * `additionalInput`" sub-check is `"info"`-tier — passing extra context
12
+ * a step doesn't declare as an `additionalInput` is allowed (the value is
13
+ * just dropped), so it's worth surfacing for awareness but never rises to
14
+ * even a warning. Only `assertValidDefinitionSpecs` treats these tiers
15
+ * differently: it blocks a push on `"error"` alone.
16
+ */
17
+ readonly severity: "error" | "warning" | "info";
18
+ readonly message: string;
19
+ /**
20
+ * The pipeline this issue belongs to, when the check is pipeline-scoped
21
+ * (`route-target`/`signal-binding`/the three Phase 2 binding checks) —
22
+ * absent for step-only checks (`signal-source-path`/`health-check-*`),
23
+ * which have no pipeline context of their own. Required before the
24
+ * designer (Phase 5) can attach an error to the right graph node.
25
+ */
26
+ readonly pipelineKey?: string;
27
+ /** The node this issue is about, when pipeline-scoped. */
28
+ readonly nodeKey?: string;
29
+ /**
30
+ * A second, related node this issue is about — e.g. `signal-binding`'s
31
+ * producer node, when different from `nodeKey`'s consumer. Absent when
32
+ * the issue is about a single node, or when the "other end" isn't a
33
+ * node in this pipeline at all (`route-target`'s target is a different
34
+ * *pipeline*, not a node).
35
+ */
36
+ readonly targetNodeKey?: string;
37
+ /**
38
+ * The specific `parallel` branch this issue is about, when `nodeKey`
39
+ * names a `parallel` node — one of that node's `branches` keys. Set only
40
+ * by the three Phase 2 binding checks (`unbound-required-input`/
41
+ * `binding-target-field`/`binding-type-mismatch`) when the
42
+ * `BindingContext` they're walking is a `parallel` branch's own bindings
43
+ * (`bindingContexts`' `ctx.branchKey`), not the node's own bindings.
44
+ * Absent for every other check, and absent for those three checks' own
45
+ * non-`parallel` (`step`/`fanOut`/`loop`) cases — without this, issues
46
+ * from two different branches of the same `parallel` node are
47
+ * indistinguishable by branch.
48
+ */
49
+ readonly branchKey?: string;
50
+ };
51
+ /** Formats a path list for an error message, capped so it stays readable. */
52
+ export declare function listPaths(paths: readonly string[], limit?: number): string;
@@ -4814,6 +4814,7 @@ export type PostApiPipelineDefinitionsData = {
4814
4814
  [key: string]: unknown;
4815
4815
  } | unknown;
4816
4816
  }>;
4817
+ entryNodeKey?: string;
4817
4818
  };
4818
4819
  path?: never;
4819
4820
  query?: never;
@@ -5260,6 +5261,7 @@ export type PutApiPipelineDefinitionsData = {
5260
5261
  [key: string]: unknown;
5261
5262
  } | unknown;
5262
5263
  }>;
5264
+ entryNodeKey?: string;
5263
5265
  };
5264
5266
  path?: never;
5265
5267
  query?: never;