@boboddy/sdk 0.2.12-alpha → 0.2.13-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.
@@ -15,11 +15,6 @@ export type BoboddyServiceDefinition = {
15
15
  targetPort: number;
16
16
  protocol: string;
17
17
  };
18
- healthcheck: {
19
- protocol: string;
20
- path: string | null;
21
- expectedStatus: number | null;
22
- };
23
18
  };
24
19
  export type BoboddyConfig = {
25
20
  commands: BoboddyCommandDefinition[];
@@ -147,7 +147,6 @@ var parseServices = (raw) => {
147
147
  return [];
148
148
  return Object.entries(raw).map(([name, entry]) => {
149
149
  const expose = entry.expose ?? {};
150
- const healthcheck = entry.healthcheck ?? {};
151
150
  const dependsOn = Array.isArray(entry.dependsOn) ? entry.dependsOn.filter((d) => typeof d === "string") : [];
152
151
  return {
153
152
  name,
@@ -158,11 +157,6 @@ var parseServices = (raw) => {
158
157
  expose: {
159
158
  targetPort: asNumber(expose.targetPort) ?? 0,
160
159
  protocol: asString(expose.protocol) ?? "http"
161
- },
162
- healthcheck: {
163
- protocol: asString(healthcheck.protocol) ?? "http",
164
- path: asString(healthcheck.path) ?? null,
165
- expectedStatus: asNumber(healthcheck.expectedStatus) ?? null
166
160
  }
167
161
  };
168
162
  });
@@ -29,6 +29,25 @@ type OpenCodeMcpServers = Record<string, {
29
29
  type OpenCodePluginEntry = string | [string, Record<string, unknown>];
30
30
  /** Full value of the OpenCode `plugin` config field. */
31
31
  type OpenCodePlugins = OpenCodePluginEntry[];
32
+ type HealthCheckSeverity = "required" | "warn";
33
+ /**
34
+ * A single step-declared health check: a real tool call made against the
35
+ * launched environment before the agent starts working.
36
+ *
37
+ * `tool` is a bare name when `mcp` is set (resolved at runtime to
38
+ * `${mcp}_${tool}`); otherwise it is a flat tool id. `mcp`, when present,
39
+ * must name a server declared in this step's `mcpServers`.
40
+ */
41
+ type HealthCheck = {
42
+ tool: string;
43
+ mcp?: string;
44
+ name?: string;
45
+ args?: Record<string, unknown>;
46
+ severity?: HealthCheckSeverity;
47
+ timeoutMs?: number;
48
+ };
49
+ /** Full value of a step's `healthChecks` field. */
50
+ type HealthChecks = HealthCheck[];
32
51
  type SignalTypeStr = "string" | "number" | "boolean" | "object" | "array";
33
52
  export type DotPaths<T, D extends readonly unknown[] = []> = D["length"] extends 4 ? string : unknown extends T ? string : T extends readonly unknown[] ? string : T extends object ? {
34
53
  [K in keyof T & string]: K | (NonNullable<T[K]> extends object ? `${K}.${DotPaths<NonNullable<T[K]>, [...D, unknown]> & string}` : never);
@@ -63,6 +82,7 @@ export type DefineStepInput<TInput extends ZodType = ZodType, TResult extends Zo
63
82
  features?: AnyStepFeature[];
64
83
  mcpServers?: OpenCodeMcpServers | null;
65
84
  plugins?: OpenCodePlugins | null;
85
+ healthChecks?: HealthChecks | null;
66
86
  status?: "draft" | "active";
67
87
  executionMode?: "workspace" | "no_workspace";
68
88
  };
@@ -94,6 +114,7 @@ export type StepDefinitionSpec = {
94
114
  }>;
95
115
  opencodeMcpJson: OpenCodeMcpServers | null;
96
116
  opencodePluginJson: OpenCodePlugins | null;
117
+ healthChecksJson: HealthChecks | null;
97
118
  };
98
119
  export type SignalTypeStrToTs<T extends SignalTypeStr> = T extends "string" ? string : T extends "number" ? number : T extends "boolean" ? boolean : T extends "array" ? unknown[] : T extends "object" ? object : unknown;
99
120
  export type SignalTypeMapOf<TSignals extends readonly unknown[], TResult> = {
@@ -12075,7 +12075,8 @@ ${feature._promptAddition}` : feature._promptAddition;
12075
12075
  }))
12076
12076
  ],
12077
12077
  opencodeMcpJson: config2.mcpServers ?? null,
12078
- opencodePluginJson: config2.plugins ?? null
12078
+ opencodePluginJson: config2.plugins ?? null,
12079
+ healthChecksJson: config2.healthChecks ?? null
12079
12080
  };
12080
12081
  return spec;
12081
12082
  }
@@ -48,6 +48,16 @@ declare const buildStepDefinitionsClient: (stepDefinitions: StepDefinitions) =>
48
48
  };
49
49
  } | unknown;
50
50
  opencodePluginJson: Array<string | Array<unknown>> | unknown;
51
+ healthChecksJson: Array<{
52
+ tool: string;
53
+ mcp?: string;
54
+ name?: string;
55
+ args?: {
56
+ [key: string]: unknown;
57
+ };
58
+ severity: "required" | "warn";
59
+ timeoutMs: number;
60
+ }> | unknown;
51
61
  status: "draft" | "active" | "archived";
52
62
  signalExtractorDefinitions: Array<{
53
63
  id: string;
@@ -102,6 +112,16 @@ declare const buildStepDefinitionsClient: (stepDefinitions: StepDefinitions) =>
102
112
  };
103
113
  } | unknown;
104
114
  opencodePluginJson: Array<string | Array<unknown>> | unknown;
115
+ healthChecksJson: Array<{
116
+ tool: string;
117
+ mcp?: string;
118
+ name?: string;
119
+ args?: {
120
+ [key: string]: unknown;
121
+ };
122
+ severity: "required" | "warn";
123
+ timeoutMs: number;
124
+ }> | unknown;
105
125
  status: "draft" | "active" | "archived";
106
126
  signalExtractorDefinitions: Array<{
107
127
  id: string;
@@ -161,6 +181,16 @@ declare const buildStepDefinitionsClient: (stepDefinitions: StepDefinitions) =>
161
181
  };
162
182
  } | unknown;
163
183
  opencodePluginJson: Array<string | Array<unknown>> | unknown;
184
+ healthChecksJson: Array<{
185
+ tool: string;
186
+ mcp?: string;
187
+ name?: string;
188
+ args?: {
189
+ [key: string]: unknown;
190
+ };
191
+ severity: "required" | "warn";
192
+ timeoutMs: number;
193
+ }> | unknown;
164
194
  status: "draft" | "active" | "archived";
165
195
  signalExtractorDefinitions: Array<{
166
196
  id: string;
@@ -269,6 +269,36 @@ function checkSignalSourcePaths(steps) {
269
269
  }
270
270
  return issues;
271
271
  }
272
+ function checkHealthChecks(steps) {
273
+ const issues = [];
274
+ for (const step of steps) {
275
+ const checks = step.healthChecksJson ?? [];
276
+ if (checks.length === 0)
277
+ continue;
278
+ const mcpServerKeys = Object.keys(step.opencodeMcpJson ?? {});
279
+ const mcpServerKeySet = new Set(mcpServerKeys);
280
+ checks.forEach((check, index) => {
281
+ const label = check.name ?? check.tool;
282
+ const where = `Step "${step.key}" health check #${String(index + 1)} ("${label}")`;
283
+ if (!check.mcp)
284
+ return;
285
+ if (!mcpServerKeySet.has(check.mcp)) {
286
+ issues.push({
287
+ check: "health-check-mcp-server",
288
+ message: `${where} names MCP server "${check.mcp}", but the step declares no ` + `such server in mcpServers. Declared servers: ${mcpServerKeys.length > 0 ? listPaths([...mcpServerKeys].sort()) : "(none)"}.`
289
+ });
290
+ }
291
+ const prefix = `${check.mcp}_`;
292
+ if (check.tool.startsWith(prefix)) {
293
+ issues.push({
294
+ check: "health-check-double-qualified",
295
+ message: `${where} sets mcp "${check.mcp}" and tool "${check.tool}", which already ` + `starts with "${prefix}". When "mcp" is set, "tool" should be the bare tool ` + `name \u2014 OpenCode resolves it to "${prefix}${check.tool}". Did you mean ` + `tool: "${check.tool.slice(prefix.length)}"?`
296
+ });
297
+ }
298
+ });
299
+ }
300
+ return issues;
301
+ }
272
302
  function routeTargets(policy) {
273
303
  const keys = [];
274
304
  if (policy.defaultEventType === "route" && typeof policy.defaultEventParamsJson?.["pipelineKey"] === "string") {
@@ -388,6 +418,7 @@ function validateDefinitionSpecs(specs, options = {}) {
388
418
  }
389
419
  return [
390
420
  ...checkSignalSourcePaths(specs.steps),
421
+ ...checkHealthChecks(specs.steps),
391
422
  ...checkRouteTargets(specs.pipelines, options.knownPipelineKeys ?? []),
392
423
  ...checkSignalBindings(specs.pipelines, stepsByKey)
393
424
  ];
@@ -13,7 +13,7 @@ export type ValidateDefinitionSpecsOptions = {
13
13
  readonly knownPipelineKeys?: readonly string[];
14
14
  };
15
15
  export type DefinitionValidationIssue = {
16
- readonly check: "signal-source-path" | "route-target" | "signal-binding";
16
+ readonly check: "signal-source-path" | "route-target" | "signal-binding" | "health-check-mcp-server" | "health-check-double-qualified";
17
17
  readonly message: string;
18
18
  };
19
19
  /**
@@ -1409,6 +1409,16 @@ export type GetApiStepDefinitionsResponses = {
1409
1409
  };
1410
1410
  } | unknown;
1411
1411
  opencodePluginJson: Array<string | Array<unknown>> | unknown;
1412
+ healthChecksJson: Array<{
1413
+ tool: string;
1414
+ mcp?: string;
1415
+ name?: string;
1416
+ args?: {
1417
+ [key: string]: unknown;
1418
+ };
1419
+ severity: 'required' | 'warn';
1420
+ timeoutMs: number;
1421
+ }> | unknown;
1412
1422
  status: 'draft' | 'active' | 'archived';
1413
1423
  signalExtractorDefinitions: Array<{
1414
1424
  id: string;
@@ -1465,6 +1475,16 @@ export type PostApiStepDefinitionsData = {
1465
1475
  };
1466
1476
  } | unknown;
1467
1477
  opencodePluginJson?: Array<string | Array<unknown>> | unknown;
1478
+ healthChecksJson?: Array<{
1479
+ tool: string;
1480
+ mcp?: string;
1481
+ name?: string;
1482
+ args?: {
1483
+ [key: string]: unknown;
1484
+ };
1485
+ severity: 'required' | 'warn';
1486
+ timeoutMs: number;
1487
+ }> | unknown;
1468
1488
  status: 'draft' | 'active' | 'archived';
1469
1489
  signalExtractorDefinitions: Array<{
1470
1490
  key: string;
@@ -1637,6 +1657,16 @@ export type PostApiStepDefinitionsResponses = {
1637
1657
  };
1638
1658
  } | unknown;
1639
1659
  opencodePluginJson: Array<string | Array<unknown>> | unknown;
1660
+ healthChecksJson: Array<{
1661
+ tool: string;
1662
+ mcp?: string;
1663
+ name?: string;
1664
+ args?: {
1665
+ [key: string]: unknown;
1666
+ };
1667
+ severity: 'required' | 'warn';
1668
+ timeoutMs: number;
1669
+ }> | unknown;
1640
1670
  status: 'draft' | 'active' | 'archived';
1641
1671
  signalExtractorDefinitions: Array<{
1642
1672
  id: string;
@@ -1693,6 +1723,16 @@ export type PutApiStepDefinitionsData = {
1693
1723
  };
1694
1724
  } | unknown;
1695
1725
  opencodePluginJson?: Array<string | Array<unknown>> | unknown;
1726
+ healthChecksJson?: Array<{
1727
+ tool: string;
1728
+ mcp?: string;
1729
+ name?: string;
1730
+ args?: {
1731
+ [key: string]: unknown;
1732
+ };
1733
+ severity: 'required' | 'warn';
1734
+ timeoutMs: number;
1735
+ }> | unknown;
1696
1736
  status: 'draft' | 'active' | 'archived';
1697
1737
  signalExtractorDefinitions: Array<{
1698
1738
  key: string;
@@ -1833,6 +1873,16 @@ export type PutApiStepDefinitionsResponses = {
1833
1873
  };
1834
1874
  } | unknown;
1835
1875
  opencodePluginJson: Array<string | Array<unknown>> | unknown;
1876
+ healthChecksJson: Array<{
1877
+ tool: string;
1878
+ mcp?: string;
1879
+ name?: string;
1880
+ args?: {
1881
+ [key: string]: unknown;
1882
+ };
1883
+ severity: 'required' | 'warn';
1884
+ timeoutMs: number;
1885
+ }> | unknown;
1836
1886
  status: 'draft' | 'active' | 'archived';
1837
1887
  signalExtractorDefinitions: Array<{
1838
1888
  id: string;
@@ -1984,6 +2034,16 @@ export type GetApiStepDefinitionsByStepDefinitionIdResponses = {
1984
2034
  };
1985
2035
  } | unknown;
1986
2036
  opencodePluginJson: Array<string | Array<unknown>> | unknown;
2037
+ healthChecksJson: Array<{
2038
+ tool: string;
2039
+ mcp?: string;
2040
+ name?: string;
2041
+ args?: {
2042
+ [key: string]: unknown;
2043
+ };
2044
+ severity: 'required' | 'warn';
2045
+ timeoutMs: number;
2046
+ }> | unknown;
1987
2047
  status: 'draft' | 'active' | 'archived';
1988
2048
  signalExtractorDefinitions: Array<{
1989
2049
  id: string;
@@ -2135,6 +2195,16 @@ export type PutApiStepDefinitionsByStepDefinitionIdArchiveResponses = {
2135
2195
  };
2136
2196
  } | unknown;
2137
2197
  opencodePluginJson: Array<string | Array<unknown>> | unknown;
2198
+ healthChecksJson: Array<{
2199
+ tool: string;
2200
+ mcp?: string;
2201
+ name?: string;
2202
+ args?: {
2203
+ [key: string]: unknown;
2204
+ };
2205
+ severity: 'required' | 'warn';
2206
+ timeoutMs: number;
2207
+ }> | unknown;
2138
2208
  status: 'draft' | 'active' | 'archived';
2139
2209
  signalExtractorDefinitions: Array<{
2140
2210
  id: string;
@@ -3352,11 +3422,6 @@ export type PostApiStepExecutionsByStepExecutionIdWorkerContextResponses = {
3352
3422
  targetPort: number;
3353
3423
  protocol: 'tcp' | 'http';
3354
3424
  };
3355
- healthcheck: {
3356
- protocol: 'tcp' | 'http';
3357
- path: string | unknown;
3358
- expectedStatus: number | unknown;
3359
- };
3360
3425
  }>;
3361
3426
  };
3362
3427
  stepExecution: {
@@ -3402,6 +3467,16 @@ export type PostApiStepExecutionsByStepExecutionIdWorkerContextResponses = {
3402
3467
  };
3403
3468
  } | unknown;
3404
3469
  opencodePluginJson: Array<string | Array<unknown>> | unknown;
3470
+ healthChecksJson: Array<{
3471
+ tool: string;
3472
+ mcp?: string;
3473
+ name?: string;
3474
+ args?: {
3475
+ [key: string]: unknown;
3476
+ };
3477
+ severity: 'required' | 'warn';
3478
+ timeoutMs: number;
3479
+ }> | unknown;
3405
3480
  };
3406
3481
  agentPrompt: {
3407
3482
  sessionTitle: string;
@@ -11542,6 +11617,16 @@ export type GetApiStepDefinitionTemplatesResponses = {
11542
11617
  };
11543
11618
  } | unknown;
11544
11619
  opencodePluginJson: Array<string | Array<unknown>> | unknown;
11620
+ healthChecksJson: Array<{
11621
+ tool: string;
11622
+ mcp?: string;
11623
+ name?: string;
11624
+ args?: {
11625
+ [key: string]: unknown;
11626
+ };
11627
+ severity: 'required' | 'warn';
11628
+ timeoutMs: number;
11629
+ }> | unknown;
11545
11630
  signalExtractorDefinitions: Array<{
11546
11631
  key: string;
11547
11632
  sourcePath: string;
@@ -11678,6 +11763,16 @@ export type GetApiStepDefinitionTemplatesByStepDefinitionTemplateIdResponses = {
11678
11763
  };
11679
11764
  } | unknown;
11680
11765
  opencodePluginJson: Array<string | Array<unknown>> | unknown;
11766
+ healthChecksJson: Array<{
11767
+ tool: string;
11768
+ mcp?: string;
11769
+ name?: string;
11770
+ args?: {
11771
+ [key: string]: unknown;
11772
+ };
11773
+ severity: 'required' | 'warn';
11774
+ timeoutMs: number;
11775
+ }> | unknown;
11681
11776
  signalExtractorDefinitions: Array<{
11682
11777
  key: string;
11683
11778
  sourcePath: string;
@@ -11872,6 +11967,16 @@ export type PostApiStepDefinitionTemplatesByStepDefinitionTemplateIdInstantiateR
11872
11967
  };
11873
11968
  } | unknown;
11874
11969
  opencodePluginJson: Array<string | Array<unknown>> | unknown;
11970
+ healthChecksJson: Array<{
11971
+ tool: string;
11972
+ mcp?: string;
11973
+ name?: string;
11974
+ args?: {
11975
+ [key: string]: unknown;
11976
+ };
11977
+ severity: 'required' | 'warn';
11978
+ timeoutMs: number;
11979
+ }> | unknown;
11875
11980
  status: 'draft' | 'active' | 'archived';
11876
11981
  signalExtractorDefinitions: Array<{
11877
11982
  id: string;
@@ -0,0 +1,45 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Severity of a step-declared health check.
4
+ *
5
+ * `required` (default) fails the step immediately if the check fails.
6
+ * `warn` is advisory — it is reported but never fails the step.
7
+ */
8
+ export declare const healthCheckSeverityValues: readonly ["required", "warn"];
9
+ export type HealthCheckSeverity = (typeof healthCheckSeverityValues)[number];
10
+ /**
11
+ * A single step-declared health check: a real tool call made against the
12
+ * launched environment before the agent starts working.
13
+ *
14
+ * `tool` is a bare tool name when `mcp` is set (resolved at runtime to
15
+ * `${mcp}_${tool}`, matching OpenCode's MCP tool-naming convention), or a flat
16
+ * tool id otherwise (plugin tools, standalone tools, built-ins already share
17
+ * one flat namespace, so no qualifier applies).
18
+ */
19
+ export declare const healthCheckSchema: z.ZodObject<{
20
+ tool: z.ZodString;
21
+ mcp: z.ZodOptional<z.ZodString>;
22
+ name: z.ZodOptional<z.ZodString>;
23
+ args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
24
+ severity: z.ZodDefault<z.ZodEnum<{
25
+ required: "required";
26
+ warn: "warn";
27
+ }>>;
28
+ timeoutMs: z.ZodDefault<z.ZodInt>;
29
+ }, z.core.$strict>;
30
+ /**
31
+ * The full value of a step's `healthChecks` field.
32
+ */
33
+ export declare const healthChecksSchema: z.ZodArray<z.ZodObject<{
34
+ tool: z.ZodString;
35
+ mcp: z.ZodOptional<z.ZodString>;
36
+ name: z.ZodOptional<z.ZodString>;
37
+ args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
38
+ severity: z.ZodDefault<z.ZodEnum<{
39
+ required: "required";
40
+ warn: "warn";
41
+ }>>;
42
+ timeoutMs: z.ZodDefault<z.ZodInt>;
43
+ }, z.core.$strict>>;
44
+ export type HealthCheck = z.infer<typeof healthCheckSchema>;
45
+ export type HealthChecks = z.infer<typeof healthChecksSchema>;