/** * Engine-neutral params coercion + validation for workflow execution. * * Used by: * - IM `/workflow run key=value …` (key=value strings from chat) * - CLI `botmux workflow run --param key=value [--param-json key=]` * * Behaviour contract (matches the schema in `ParamDefSchema`, but is kept * structurally independent from the legacy WorkflowDefinition so the v3 * Saved Workflow model can reuse the same coercion core): * - Unknown param names → throw `unknown param` (don't silently pass through; * the workflow author hasn't declared them, so any binding would be a * latent typo). * - Missing required → throw. * - Missing optional + has `default` → fill with default verbatim. * - Missing optional + no default → omit (downstream `${params.X}` lookup * surfaces a `BindingError` on use, which is the right place to fail). * - Present + type=string → keep as string. * - Present + type=number → `Number(raw)`; reject NaN / Infinity. * - Present + type=boolean → accept `true/1/yes/y` / `false/0/no/n` (case * insensitive); reject anything else. * - Present + type=object|array → only valid via the JSON channel; the * plain string channel throws to tell the caller to use `--param-json` * (CLI) or pre-decoded JSON (programmatic). */ export type WorkflowParamType = 'string' | 'number' | 'boolean' | 'object' | 'array'; /** * Engine-neutral parameter declaration. * * This intentionally mirrors the legacy `ParamDefSchema` structurally rather * than importing it. A v2 `WorkflowDefinition` is therefore assignable to * {@link WorkflowParamSchemaOwner} unchanged, while v3 definitions can consume * the coercion module without depending on the engine that is being retired. * `sensitive` is an opt-in for the new definition model; legacy JSON can express * the same no-default rule with `format: "secret"` (or another recognized * secret format) without changing its schema. */ export interface WorkflowParamDefinition { type: WorkflowParamType; format?: string; required?: boolean; default?: unknown; description?: string; sensitive?: boolean; } export interface WorkflowParamSchemaOwner { params?: Readonly>; } /** Matches the segment grammar already accepted by `params.` refs. */ export declare const WORKFLOW_PARAM_NAME_PATTERN: RegExp; export type RawParamInput = { kind: 'string'; value: string; } | { kind: 'json'; value: unknown; }; export type ParamCoerceError = { /** Param name that failed; undefined for whole-record-shape errors. */ name?: string; /** Machine code for the failure category. */ code: 'unknown_param' | 'missing_required' | 'type_mismatch' | 'unsupported_string_channel' | 'invalid_json' | 'invalid_param_name' | 'invalid_param_type' | 'invalid_param_default' | 'sensitive_default'; /** Human-readable Chinese-localized message (matches existing CLI/IM output). */ message: string; }; export declare class ParamCoerceFailure extends Error { readonly issues: ParamCoerceError[]; constructor(issues: ParamCoerceError[]); } /** * Validate the declaration itself before looking at caller input. * * The legacy schema deliberately leaves `default` as `unknown`. Callers that * own a strict definition schema (Saved Workflow v3) invoke this explicitly; * the generic coercion functions do not, because v2 remains compatible for * its one-release migration window with definitions that were valid under the * old permissive schema. */ export declare function validateWorkflowParamSchema(owner: WorkflowParamSchemaOwner): void; /** * Validate + coerce raw caller input against the workflow's `params` schema. * * `rawParams` accepts a mixed map of `{ kind: 'string' | 'json' }` so that * the CLI can pipe `--param-json` through the same code path as `--param`. * The IM `/workflow run` legacy entry calls `coerceWorkflowParamsFromStrings` * below which wraps every value as `{ kind: 'string' }`. * * All errors are aggregated into a single `ParamCoerceFailure` so the caller * can render every issue at once instead of one-by-one Enter-key fixes. */ export declare function coerceWorkflowParams(def: WorkflowParamSchemaOwner, rawParams: Record): Record; /** * Legacy convenience: when every input is a raw string (IM chat path), wrap * each value into `{ kind: 'string' }` and delegate to `coerceWorkflowParams`. */ export declare function coerceWorkflowParamsFromStrings(def: WorkflowParamSchemaOwner, rawParams: Record): Record; //# sourceMappingURL=params.d.ts.map