@sweny-ai/core 0.1.97 → 0.1.99
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.
- package/dist/cli/cloud-lifecycle.d.ts +24 -2
- package/dist/cli/cloud-lifecycle.js +25 -3
- package/dist/cli/config.d.ts +6 -0
- package/dist/cli/config.js +3 -0
- package/dist/cli/main.js +66 -8
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -1
- package/dist/inputs.d.ts +135 -0
- package/dist/inputs.js +256 -0
- package/dist/schema.d.ts +119 -32
- package/dist/schema.js +36 -0
- package/dist/types.d.ts +12 -0
- package/dist/types.js +1 -0
- package/package.json +1 -1
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*
|
|
16
16
|
* All errors are swallowed: cloud reporting MUST NEVER block the workflow.
|
|
17
17
|
*/
|
|
18
|
-
import type { NodeResult, Observer, Workflow } from "../types.js";
|
|
18
|
+
import type { NodeResult, Observer, Workflow, WorkflowInputs } from "../types.js";
|
|
19
19
|
export type TriggerSource = "github_action" | "gitlab_ci" | "circleci" | "buildkite" | "other_ci" | "manual" | "cron" | "mcp" | "unknown";
|
|
20
20
|
export interface CloudReportConfig {
|
|
21
21
|
cloudToken: string;
|
|
@@ -29,6 +29,17 @@ export interface StartRunInput {
|
|
|
29
29
|
trigger_metadata?: Record<string, unknown>;
|
|
30
30
|
metadata?: Record<string, unknown>;
|
|
31
31
|
run_uuid?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Declared input shape for this run: key name → declared (or observed)
|
|
34
|
+
* type. Values are intentionally NEVER included; per the workflow spec
|
|
35
|
+
* (Telemetry shape), cloud renderers may display the input contract a
|
|
36
|
+
* run was invoked with but must not receive the values themselves. A
|
|
37
|
+
* workflow that takes a token as input therefore never leaks it.
|
|
38
|
+
*
|
|
39
|
+
* Omitted when the caller didn't pass an inputs shape (e.g. legacy
|
|
40
|
+
* call sites pre-dating the inputs contract).
|
|
41
|
+
*/
|
|
42
|
+
inputs_shape?: Record<string, string>;
|
|
32
43
|
}
|
|
33
44
|
export interface StartRunResult {
|
|
34
45
|
run_id: string;
|
|
@@ -61,10 +72,18 @@ export declare function newRunUuid(): string;
|
|
|
61
72
|
/**
|
|
62
73
|
* Build a run-start payload from a Workflow + env. Pure function; the caller
|
|
63
74
|
* is responsible for passing it to `startRun()`.
|
|
75
|
+
*
|
|
76
|
+
* `inputsShape` (when provided) ships the key-name → declared-type map for
|
|
77
|
+
* the run. Values are NEVER transmitted; callers compute the shape via
|
|
78
|
+
* `summarizeInputShape` (or pass the workflow's declared `inputs` block
|
|
79
|
+
* and resolved input bag and let this helper compute it). See the
|
|
80
|
+
* Telemetry shape rule in spec/src/content/docs/workflow.mdx.
|
|
64
81
|
*/
|
|
65
82
|
export declare function buildStartRunPayload(workflow: Pick<Workflow, "id" | "workflow_type">, options: {
|
|
66
83
|
runUuid: string;
|
|
67
84
|
env?: NodeJS.ProcessEnv;
|
|
85
|
+
declaredInputs?: WorkflowInputs;
|
|
86
|
+
resolvedInputs?: Record<string, unknown>;
|
|
68
87
|
}): StartRunInput;
|
|
69
88
|
/**
|
|
70
89
|
* POST /api/runs — start a run, returning the run id (or null on failure).
|
|
@@ -120,7 +139,10 @@ export interface CloudLifecycleHandle {
|
|
|
120
139
|
export declare function beginCloudLifecycle(config: {
|
|
121
140
|
cloudToken?: string;
|
|
122
141
|
repository?: string;
|
|
123
|
-
}, workflow: Pick<Workflow, "id" | "workflow_type"
|
|
142
|
+
}, workflow: Pick<Workflow, "id" | "workflow_type">, options?: {
|
|
143
|
+
declaredInputs?: WorkflowInputs;
|
|
144
|
+
resolvedInputs?: Record<string, unknown>;
|
|
145
|
+
}): Promise<CloudLifecycleHandle | null>;
|
|
124
146
|
/**
|
|
125
147
|
* Close a cloud lifecycle session opened by `beginCloudLifecycle`.
|
|
126
148
|
*
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* All errors are swallowed: cloud reporting MUST NEVER block the workflow.
|
|
17
17
|
*/
|
|
18
18
|
import { randomUUID } from "node:crypto";
|
|
19
|
+
import { summarizeInputShape } from "../inputs.js";
|
|
19
20
|
const CLOUD_URL_DEFAULT = "https://cloud.sweny.ai";
|
|
20
21
|
const TIMEOUT_MS = 10_000;
|
|
21
22
|
// startRun runs on the critical path BEFORE execute(), so a slow cloud
|
|
@@ -85,6 +86,12 @@ export function newRunUuid() {
|
|
|
85
86
|
/**
|
|
86
87
|
* Build a run-start payload from a Workflow + env. Pure function; the caller
|
|
87
88
|
* is responsible for passing it to `startRun()`.
|
|
89
|
+
*
|
|
90
|
+
* `inputsShape` (when provided) ships the key-name → declared-type map for
|
|
91
|
+
* the run. Values are NEVER transmitted; callers compute the shape via
|
|
92
|
+
* `summarizeInputShape` (or pass the workflow's declared `inputs` block
|
|
93
|
+
* and resolved input bag and let this helper compute it). See the
|
|
94
|
+
* Telemetry shape rule in spec/src/content/docs/workflow.mdx.
|
|
88
95
|
*/
|
|
89
96
|
export function buildStartRunPayload(workflow, options) {
|
|
90
97
|
const env = options.env ?? process.env;
|
|
@@ -97,7 +104,7 @@ export function buildStartRunPayload(workflow, options) {
|
|
|
97
104
|
metadata.commit_sha = env.GITHUB_SHA;
|
|
98
105
|
if (env.GITHUB_ACTOR)
|
|
99
106
|
metadata.actor = env.GITHUB_ACTOR;
|
|
100
|
-
|
|
107
|
+
const payload = {
|
|
101
108
|
workflow_id: workflow.id,
|
|
102
109
|
workflow_type: workflow.workflow_type ?? "generic",
|
|
103
110
|
trigger_source,
|
|
@@ -105,6 +112,17 @@ export function buildStartRunPayload(workflow, options) {
|
|
|
105
112
|
metadata,
|
|
106
113
|
run_uuid: options.runUuid,
|
|
107
114
|
};
|
|
115
|
+
// Compute the shape when caller provided either a declaration or a
|
|
116
|
+
// resolved bag. Omit the key entirely when there's nothing to summarize
|
|
117
|
+
// so old cloud builds that don't model `inputs_shape` aren't surprised
|
|
118
|
+
// by an empty object.
|
|
119
|
+
if (options.declaredInputs || options.resolvedInputs) {
|
|
120
|
+
const shape = summarizeInputShape(options.declaredInputs, options.resolvedInputs);
|
|
121
|
+
if (Object.keys(shape).length > 0) {
|
|
122
|
+
payload.inputs_shape = shape;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return payload;
|
|
108
126
|
}
|
|
109
127
|
/**
|
|
110
128
|
* POST /api/runs — start a run, returning the run id (or null on failure).
|
|
@@ -204,11 +222,15 @@ export function deriveGenericMetrics(results, durationMs) {
|
|
|
204
222
|
* Pair every successful call with `finishCloudLifecycle(handle, …)` once the
|
|
205
223
|
* workflow completes (success or failure).
|
|
206
224
|
*/
|
|
207
|
-
export async function beginCloudLifecycle(config, workflow) {
|
|
225
|
+
export async function beginCloudLifecycle(config, workflow, options) {
|
|
208
226
|
if (!config.cloudToken)
|
|
209
227
|
return null;
|
|
210
228
|
const runUuid = newRunUuid();
|
|
211
|
-
const payload = buildStartRunPayload(workflow, {
|
|
229
|
+
const payload = buildStartRunPayload(workflow, {
|
|
230
|
+
runUuid,
|
|
231
|
+
declaredInputs: options?.declaredInputs,
|
|
232
|
+
resolvedInputs: options?.resolvedInputs,
|
|
233
|
+
});
|
|
212
234
|
const reportConfig = {
|
|
213
235
|
cloudToken: config.cloudToken,
|
|
214
236
|
repository: config.repository,
|
package/dist/cli/config.d.ts
CHANGED
|
@@ -52,6 +52,12 @@ export interface CliConfig {
|
|
|
52
52
|
repositoryOwner: string;
|
|
53
53
|
json: boolean;
|
|
54
54
|
stream: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* When true, print each tool call's input and output inline (human-readable,
|
|
57
|
+
* truncated). Adds a verbose tool observer alongside the spinner/progress
|
|
58
|
+
* observer. Use `stream` if you need full untruncated NDJSON instead.
|
|
59
|
+
*/
|
|
60
|
+
verbose: boolean;
|
|
55
61
|
bell: boolean;
|
|
56
62
|
cacheDir: string;
|
|
57
63
|
cacheTtl: number;
|
package/dist/cli/config.js
CHANGED
|
@@ -56,6 +56,7 @@ export function registerTriageCommand(program) {
|
|
|
56
56
|
.option("--gitlab-base-url <url>", "GitLab base URL (default: https://gitlab.com)")
|
|
57
57
|
.option("--json", "Output results as JSON", false)
|
|
58
58
|
.option("--stream", "Stream NDJSON events to stdout (for Studio / automation)", false)
|
|
59
|
+
.option("--verbose", "Print each tool call's input and output inline (human-readable, truncated). Use --stream for full untruncated NDJSON.", false)
|
|
59
60
|
.option("--bell", "Ring terminal bell on completion", false)
|
|
60
61
|
.option("--cache-dir <path>", "Step cache directory (default: .sweny/cache)")
|
|
61
62
|
.option("--cache-ttl <seconds>", "Cache TTL in seconds, 0 = infinite (default: 86400)")
|
|
@@ -163,6 +164,7 @@ export function parseCliInputs(options, fileConfig = {}) {
|
|
|
163
164
|
// Per-invocation flags: CLI only
|
|
164
165
|
json: Boolean(options.json),
|
|
165
166
|
stream: Boolean(options.stream),
|
|
167
|
+
verbose: Boolean(options.verbose),
|
|
166
168
|
bell: Boolean(options.bell),
|
|
167
169
|
cacheDir: options.cacheDir || env.SWENY_CACHE_DIR || f("cache-dir") || ".sweny/cache",
|
|
168
170
|
cacheTtl: parsePositiveInt(options.cacheTtl ?? f("cache-ttl"), 86400),
|
|
@@ -638,6 +640,7 @@ export function registerImplementCommand(program) {
|
|
|
638
640
|
.option("--review-mode <mode>", "PR merge behavior: auto (GitHub auto-merge when CI passes) | review (human approval, default)", "review")
|
|
639
641
|
.option("--additional-instructions <text>", "Extra instructions for the coding agent")
|
|
640
642
|
.option("--stream", "Stream NDJSON events to stdout (for Studio / automation)", false)
|
|
643
|
+
.option("--verbose", "Print each tool call's input and output inline (human-readable, truncated). Use --stream for full untruncated NDJSON.", false)
|
|
641
644
|
.option("--offline", "Skip URL Sources and fail fast if any are referenced", false);
|
|
642
645
|
}
|
|
643
646
|
/**
|
package/dist/cli/main.js
CHANGED
|
@@ -15,6 +15,7 @@ import { configuredSkills, configuredSkillsWithDiagnostics } from "../skills/cus
|
|
|
15
15
|
import { buildAutoMcpServers, buildSkillMcpServers, buildProviderContext } from "../mcp.js";
|
|
16
16
|
import { loadAdditionalContext } from "../templates.js";
|
|
17
17
|
import { loadAndValidateWorkflow } from "../loader.js";
|
|
18
|
+
import { validateRuntimeInput } from "../inputs.js";
|
|
18
19
|
import { stringify as stringifyYaml } from "yaml";
|
|
19
20
|
import { buildWorkflow, refineWorkflow } from "../workflow-builder.js";
|
|
20
21
|
import { toMermaidBlock } from "../mermaid.js";
|
|
@@ -355,11 +356,18 @@ triageCmd.action(async (options) => {
|
|
|
355
356
|
// node-streaming observer can attach events to the correct runId.
|
|
356
357
|
// Null when the token is unset or startRun fails — cloud reporting
|
|
357
358
|
// must never block the workflow.
|
|
358
|
-
|
|
359
|
+
//
|
|
360
|
+
// Cloud sees the input *shape* (key names + observed types), never
|
|
361
|
+
// the values. Per workflow spec Telemetry shape rule, a token in the
|
|
362
|
+
// bag never leaves the host.
|
|
363
|
+
const cloudHandle = await beginCloudLifecycle(config, triageWorkflow, {
|
|
364
|
+
declaredInputs: triageWorkflow.inputs,
|
|
365
|
+
resolvedInputs: workflowInput,
|
|
366
|
+
});
|
|
359
367
|
if (cloudHandle?.dashboardUrl) {
|
|
360
368
|
console.log(c.subtle(` cloud: ${cloudHandle.dashboardUrl}`));
|
|
361
369
|
}
|
|
362
|
-
const observer = composeObservers(progressObserver, config.stream ? createStreamObserver() : undefined, createCloudStreamObserver(config, cloudHandle));
|
|
370
|
+
const observer = composeObservers(progressObserver, config.verbose ? createVerboseToolObserver() : undefined, config.stream ? createStreamObserver() : undefined, createCloudStreamObserver(config, cloudHandle));
|
|
363
371
|
try {
|
|
364
372
|
const { results, trace } = await execute(triageWorkflow, workflowInput, {
|
|
365
373
|
skills,
|
|
@@ -527,12 +535,15 @@ implementCmd.action(async (issueId, options) => {
|
|
|
527
535
|
};
|
|
528
536
|
// Open cloud lifecycle session BEFORE composing observers so the
|
|
529
537
|
// node-streaming observer can attach to the correct runId. See
|
|
530
|
-
// triage path for rationale.
|
|
531
|
-
const implCloudHandle = await beginCloudLifecycle(config, implementWorkflow
|
|
538
|
+
// triage path for rationale. Cloud sees the input *shape* only.
|
|
539
|
+
const implCloudHandle = await beginCloudLifecycle(config, implementWorkflow, {
|
|
540
|
+
declaredInputs: implementWorkflow.inputs,
|
|
541
|
+
resolvedInputs: workflowInput,
|
|
542
|
+
});
|
|
532
543
|
if (implCloudHandle?.dashboardUrl) {
|
|
533
544
|
console.log(c.subtle(` cloud: ${implCloudHandle.dashboardUrl}`));
|
|
534
545
|
}
|
|
535
|
-
const observer = composeObservers(implProgressObserver, Boolean(options.stream) ? createStreamObserver() : undefined, createCloudStreamObserver(config, implCloudHandle));
|
|
546
|
+
const observer = composeObservers(implProgressObserver, config.verbose ? createVerboseToolObserver() : undefined, Boolean(options.stream) ? createStreamObserver() : undefined, createCloudStreamObserver(config, implCloudHandle));
|
|
536
547
|
try {
|
|
537
548
|
const { results } = await execute(implementWorkflow, workflowInput, {
|
|
538
549
|
skills,
|
|
@@ -720,14 +731,39 @@ export async function workflowRunAction(file, options) {
|
|
|
720
731
|
// Build workflow input — prefer --input JSON if provided, else fall back to config-derived input
|
|
721
732
|
let workflowInput;
|
|
722
733
|
if (options.input && typeof options.input === "string") {
|
|
734
|
+
let parsed;
|
|
723
735
|
try {
|
|
724
|
-
|
|
736
|
+
parsed = JSON.parse(options.input);
|
|
725
737
|
}
|
|
726
738
|
catch {
|
|
727
739
|
console.error(chalk.red(" --input must be valid JSON"));
|
|
728
740
|
process.exit(1);
|
|
729
741
|
return;
|
|
730
742
|
}
|
|
743
|
+
// Validate against the workflow's declared `inputs` contract (when present).
|
|
744
|
+
// Workflows without an `inputs` block pass through unchanged.
|
|
745
|
+
const validated = validateRuntimeInput(workflow.inputs, parsed);
|
|
746
|
+
if (!validated.ok) {
|
|
747
|
+
console.error(chalk.red(`\n --input does not match workflow "${workflow.id}" inputs contract:\n`));
|
|
748
|
+
for (const err of validated.errors) {
|
|
749
|
+
console.error(chalk.red(` ✗ ${err.field}: ${err.message}`));
|
|
750
|
+
}
|
|
751
|
+
if (workflow.inputs) {
|
|
752
|
+
console.error(chalk.dim(`\n Declared inputs:`));
|
|
753
|
+
for (const [name, field] of Object.entries(workflow.inputs)) {
|
|
754
|
+
const flags = [field.type];
|
|
755
|
+
if (field.required)
|
|
756
|
+
flags.push("required");
|
|
757
|
+
if (field.default !== undefined)
|
|
758
|
+
flags.push(`default=${JSON.stringify(field.default)}`);
|
|
759
|
+
console.error(chalk.dim(` - ${name} (${flags.join(", ")})${field.description ? `: ${field.description}` : ""}`));
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
console.error("");
|
|
763
|
+
process.exit(1);
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
766
|
+
workflowInput = validated.value;
|
|
731
767
|
}
|
|
732
768
|
else {
|
|
733
769
|
workflowInput = {
|
|
@@ -748,11 +784,33 @@ export async function workflowRunAction(file, options) {
|
|
|
748
784
|
}),
|
|
749
785
|
context: buildProviderCtx(config, mcpServers),
|
|
750
786
|
};
|
|
787
|
+
// If the workflow declared `inputs`, apply defaults to the config-derived bag.
|
|
788
|
+
// This lets a CI caller omit --input entirely and still get the documented
|
|
789
|
+
// defaults filled in (e.g. since_tag/until_tag pulled from a release-notes
|
|
790
|
+
// workflow's declaration).
|
|
791
|
+
if (workflow.inputs) {
|
|
792
|
+
const validated = validateRuntimeInput(workflow.inputs, workflowInput);
|
|
793
|
+
if (!validated.ok) {
|
|
794
|
+
console.error(chalk.red(`\n Workflow "${workflow.id}" declares required inputs not satisfied by default config:\n`));
|
|
795
|
+
for (const err of validated.errors) {
|
|
796
|
+
console.error(chalk.red(` ✗ ${err.field}: ${err.message}`));
|
|
797
|
+
}
|
|
798
|
+
console.error(chalk.dim(`\n Pass them via --input '{ ... }'.\n`));
|
|
799
|
+
process.exit(1);
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
workflowInput = validated.value;
|
|
803
|
+
}
|
|
751
804
|
}
|
|
752
805
|
// Open cloud lifecycle session BEFORE composing observers so the
|
|
753
806
|
// node-streaming observer can attach to the correct runId. See
|
|
754
|
-
// triage path for rationale.
|
|
755
|
-
|
|
807
|
+
// triage path for rationale. Cloud sees the input *shape* only,
|
|
808
|
+
// never the values. Enforces the workflow spec Telemetry rule
|
|
809
|
+
// even when the workflow's declared inputs include secrets.
|
|
810
|
+
const wfCloudHandle = await beginCloudLifecycle(config, workflow, {
|
|
811
|
+
declaredInputs: workflow.inputs,
|
|
812
|
+
resolvedInputs: workflowInput,
|
|
813
|
+
});
|
|
756
814
|
if (wfCloudHandle?.dashboardUrl && !isJson) {
|
|
757
815
|
console.log(c.subtle(` cloud: ${wfCloudHandle.dashboardUrl}`));
|
|
758
816
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
* })
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
|
-
export type { Skill, SkillCategory, SkillDefinition, Tool, ToolContext, ConfigField, JSONSchema, Workflow, Node, Edge, NodeResult, ToolCall, ExecutionEvent, Observer, Claude, Logger, TraceStep, TraceEdge, ExecutionTrace, ExecutionResult, Source, ResolvedSource, SourceKind, SourceResolutionMap, } from "./types.js";
|
|
24
|
+
export type { Skill, SkillCategory, SkillDefinition, Tool, ToolContext, ConfigField, JSONSchema, Workflow, Node, Edge, NodeResult, ToolCall, ExecutionEvent, Observer, Claude, Logger, TraceStep, TraceEdge, ExecutionTrace, ExecutionResult, Source, ResolvedSource, SourceKind, SourceResolutionMap, WorkflowInputs, WorkflowInputField, WorkflowInputType, InputValidationError, InputValidationResult, } from "./types.js";
|
|
25
|
+
export { WORKFLOW_INPUT_TYPES } from "./types.js";
|
|
25
26
|
export { consoleLogger } from "./types.js";
|
|
26
27
|
export { execute } from "./executor.js";
|
|
27
28
|
export type { ExecuteOptions } from "./executor.js";
|
|
@@ -30,8 +31,9 @@ export type { ClaudeClientOptions } from "./claude.js";
|
|
|
30
31
|
export { github, linear, slack, sentry, datadog, notification, supabase, builtinSkills, createSkillMap, allSkills, isSkillConfigured, configuredBuiltinSkills, validateWorkflowSkills, } from "./skills/index.js";
|
|
31
32
|
export type { SkillValidationResult } from "./skills/index.js";
|
|
32
33
|
export { loadCustomSkills, discoverSkills, configuredSkills } from "./skills/custom-loader.js";
|
|
33
|
-
export { workflowZ, nodeZ, edgeZ, skillZ, mcpServerConfigZ, skillDefinitionZ, sourceZ, parseWorkflow, validateWorkflow, workflowJsonSchema, } from "./schema.js";
|
|
34
|
+
export { workflowZ, nodeZ, edgeZ, skillZ, mcpServerConfigZ, skillDefinitionZ, sourceZ, workflowInputsZ, parseWorkflow, validateWorkflow, workflowJsonSchema, } from "./schema.js";
|
|
34
35
|
export type { WorkflowError } from "./schema.js";
|
|
36
|
+
export { validateRuntimeInput, summarizeInputShape } from "./inputs.js";
|
|
35
37
|
export { buildAutoMcpServers, buildSkillMcpServers, buildProviderContext } from "./mcp.js";
|
|
36
38
|
export type { ProviderContextOptions, SkillMcpOptions } from "./mcp.js";
|
|
37
39
|
export type { McpServerConfig, McpAutoConfig } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
* })
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
|
+
export { WORKFLOW_INPUT_TYPES } from "./types.js";
|
|
24
25
|
export { consoleLogger } from "./types.js";
|
|
25
26
|
// Executor
|
|
26
27
|
export { execute } from "./executor.js";
|
|
@@ -31,7 +32,9 @@ export { github, linear, slack, sentry, datadog, notification, supabase, builtin
|
|
|
31
32
|
// Node-only skill discovery (filesystem-based)
|
|
32
33
|
export { loadCustomSkills, discoverSkills, configuredSkills } from "./skills/custom-loader.js";
|
|
33
34
|
// Schema & validation
|
|
34
|
-
export { workflowZ, nodeZ, edgeZ, skillZ, mcpServerConfigZ, skillDefinitionZ, sourceZ, parseWorkflow, validateWorkflow, workflowJsonSchema, } from "./schema.js";
|
|
35
|
+
export { workflowZ, nodeZ, edgeZ, skillZ, mcpServerConfigZ, skillDefinitionZ, sourceZ, workflowInputsZ, parseWorkflow, validateWorkflow, workflowJsonSchema, } from "./schema.js";
|
|
36
|
+
// Workflow input validation
|
|
37
|
+
export { validateRuntimeInput, summarizeInputShape } from "./inputs.js";
|
|
35
38
|
// MCP auto-injection
|
|
36
39
|
export { buildAutoMcpServers, buildSkillMcpServers, buildProviderContext } from "./mcp.js";
|
|
37
40
|
// Workflow builder
|
package/dist/inputs.d.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow inputs — declared per-run parameter contract.
|
|
3
|
+
*
|
|
4
|
+
* A workflow YAML may declare a top-level `inputs` block describing the
|
|
5
|
+
* per-run parameters it accepts. The CLI validates `--input <json>` against
|
|
6
|
+
* this declaration, applies defaults, and rejects malformed runs at the
|
|
7
|
+
* boundary so node prompts and conditional routing receive a well-shaped
|
|
8
|
+
* `input` value.
|
|
9
|
+
*
|
|
10
|
+
* Design notes (the contract that matters for downstream consumers):
|
|
11
|
+
*
|
|
12
|
+
* 1. The `inputs` block is OPTIONAL. Workflows without one accept any
|
|
13
|
+
* JSON object (back-compat with every workflow shipped before this
|
|
14
|
+
* change). Author opts in by adding the block.
|
|
15
|
+
* 2. Types are the JSON-native primitives we can validate without a
|
|
16
|
+
* schema engine: `string`, `number`, `boolean`, plus `string[]` for
|
|
17
|
+
* multi-value cases (labels, files, etc.). This is intentionally
|
|
18
|
+
* narrower than full JSON Schema. Authors who need richer shapes can
|
|
19
|
+
* still pass an arbitrary object; declaring it just opts into the
|
|
20
|
+
* validator. We can widen later without breaking existing YAML.
|
|
21
|
+
* 3. `required: true` makes a field mandatory. Missing fields surface a
|
|
22
|
+
* single grouped error listing every gap, not one error per call.
|
|
23
|
+
* 4. `default` fills in the value when the caller omits it. The default
|
|
24
|
+
* is type-checked against the field's `type` at parse time, so
|
|
25
|
+
* authors can't ship a YAML that injects a string into a number
|
|
26
|
+
* field at run time. `required: true` and `default` are mutually
|
|
27
|
+
* exclusive: declaring both is incoherent (the default either
|
|
28
|
+
* satisfies the required check, making it vestigial, or it doesn't,
|
|
29
|
+
* making the default dead code), so the schema rejects the
|
|
30
|
+
* combination at parse time.
|
|
31
|
+
* 5. Telemetry redaction: the executor only ever sees the resolved
|
|
32
|
+
* `input` map. Cloud observers see the *shape* (key names + types)
|
|
33
|
+
* via `summarizeInputShape`, never the values, so a workflow that
|
|
34
|
+
* takes API tokens as input never leaks them.
|
|
35
|
+
*
|
|
36
|
+
* Out of scope on purpose:
|
|
37
|
+
* - No templating language (`{{input.foo}}` etc.). Workflow instructions
|
|
38
|
+
* are natural-language and the LLM already sees `input` in its context
|
|
39
|
+
* map; that path is good enough for v1 and avoids inventing a dialect.
|
|
40
|
+
* - No nested object schemas. If a single workflow needs deep input,
|
|
41
|
+
* pass a JSON blob through and document it; we can layer schemas in
|
|
42
|
+
* later. Most production use cases are flat (since_tag, until_tag,
|
|
43
|
+
* dry_run, repo, time_range, etc.).
|
|
44
|
+
*/
|
|
45
|
+
import { z } from "zod";
|
|
46
|
+
/**
|
|
47
|
+
* Supported input field types.
|
|
48
|
+
*
|
|
49
|
+
* Kept narrow on purpose. See module docstring for rationale.
|
|
50
|
+
*/
|
|
51
|
+
export declare const WORKFLOW_INPUT_TYPES: readonly ["string", "number", "boolean", "string[]"];
|
|
52
|
+
export type WorkflowInputType = (typeof WORKFLOW_INPUT_TYPES)[number];
|
|
53
|
+
/** A single declared input field. */
|
|
54
|
+
export interface WorkflowInputField {
|
|
55
|
+
/** JSON-native type. See {@link WORKFLOW_INPUT_TYPES}. */
|
|
56
|
+
type: WorkflowInputType;
|
|
57
|
+
/** Human-readable description. Surfaced by CLI help and cloud renderers. */
|
|
58
|
+
description?: string;
|
|
59
|
+
/** When true, the caller MUST provide a value. */
|
|
60
|
+
required?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Default applied when the caller omits the field. Type-checked against
|
|
63
|
+
* `type` at YAML parse time (a string default on a number field is a
|
|
64
|
+
* schema error, not a runtime surprise).
|
|
65
|
+
*/
|
|
66
|
+
default?: unknown;
|
|
67
|
+
/** Optional set of allowed values. Validated after type-check. */
|
|
68
|
+
enum?: unknown[];
|
|
69
|
+
}
|
|
70
|
+
/** Declared input contract for a workflow. Keys are field names. */
|
|
71
|
+
export type WorkflowInputs = Record<string, WorkflowInputField>;
|
|
72
|
+
export declare const workflowInputsZ: z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodObject<{
|
|
73
|
+
type: z.ZodEnum<["string", "number", "boolean", "string[]"]>;
|
|
74
|
+
description: z.ZodOptional<z.ZodString>;
|
|
75
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
76
|
+
default: z.ZodOptional<z.ZodUnknown>;
|
|
77
|
+
enum: z.ZodOptional<z.ZodArray<z.ZodUnknown, "many">>;
|
|
78
|
+
}, "strict", z.ZodTypeAny, {
|
|
79
|
+
type: "string" | "number" | "boolean" | "string[]";
|
|
80
|
+
description?: string | undefined;
|
|
81
|
+
required?: boolean | undefined;
|
|
82
|
+
default?: unknown;
|
|
83
|
+
enum?: unknown[] | undefined;
|
|
84
|
+
}, {
|
|
85
|
+
type: "string" | "number" | "boolean" | "string[]";
|
|
86
|
+
description?: string | undefined;
|
|
87
|
+
required?: boolean | undefined;
|
|
88
|
+
default?: unknown;
|
|
89
|
+
enum?: unknown[] | undefined;
|
|
90
|
+
}>, {
|
|
91
|
+
type: "string" | "number" | "boolean" | "string[]";
|
|
92
|
+
description?: string | undefined;
|
|
93
|
+
required?: boolean | undefined;
|
|
94
|
+
default?: unknown;
|
|
95
|
+
enum?: unknown[] | undefined;
|
|
96
|
+
}, {
|
|
97
|
+
type: "string" | "number" | "boolean" | "string[]";
|
|
98
|
+
description?: string | undefined;
|
|
99
|
+
required?: boolean | undefined;
|
|
100
|
+
default?: unknown;
|
|
101
|
+
enum?: unknown[] | undefined;
|
|
102
|
+
}>>;
|
|
103
|
+
/** A single validation error against the declared input contract. */
|
|
104
|
+
export interface InputValidationError {
|
|
105
|
+
field: string;
|
|
106
|
+
message: string;
|
|
107
|
+
}
|
|
108
|
+
/** Tagged result of validating raw runtime input against a declared contract. */
|
|
109
|
+
export type InputValidationResult = {
|
|
110
|
+
ok: true;
|
|
111
|
+
value: Record<string, unknown>;
|
|
112
|
+
} | {
|
|
113
|
+
ok: false;
|
|
114
|
+
errors: InputValidationError[];
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Validate the caller's raw input object against the workflow's declared
|
|
118
|
+
* `inputs` block. Applies defaults for omitted optional fields. Surfaces
|
|
119
|
+
* every problem in a single response so the CLI prints a useful message
|
|
120
|
+
* instead of failing on the first error.
|
|
121
|
+
*
|
|
122
|
+
* When no `inputs` block is declared, returns the caller's object verbatim
|
|
123
|
+
* (back-compat: every existing workflow passes through unchanged).
|
|
124
|
+
*/
|
|
125
|
+
export declare function validateRuntimeInput(declared: WorkflowInputs | undefined, raw: unknown): InputValidationResult;
|
|
126
|
+
/**
|
|
127
|
+
* Summary of an input bag suitable for telemetry: keys + observed types,
|
|
128
|
+
* never values. Cloud renderers use this to display the input contract a
|
|
129
|
+
* run was invoked with, without leaking the values themselves.
|
|
130
|
+
*
|
|
131
|
+
* `declared` shapes the output when present (so the summary stays stable
|
|
132
|
+
* across runs even when the caller omits optional fields). Falls back to
|
|
133
|
+
* the resolved values' runtime shape when no declaration exists.
|
|
134
|
+
*/
|
|
135
|
+
export declare function summarizeInputShape(declared: WorkflowInputs | undefined, resolved: Record<string, unknown> | undefined): Record<string, WorkflowInputType | "object" | "null">;
|
package/dist/inputs.js
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow inputs — declared per-run parameter contract.
|
|
3
|
+
*
|
|
4
|
+
* A workflow YAML may declare a top-level `inputs` block describing the
|
|
5
|
+
* per-run parameters it accepts. The CLI validates `--input <json>` against
|
|
6
|
+
* this declaration, applies defaults, and rejects malformed runs at the
|
|
7
|
+
* boundary so node prompts and conditional routing receive a well-shaped
|
|
8
|
+
* `input` value.
|
|
9
|
+
*
|
|
10
|
+
* Design notes (the contract that matters for downstream consumers):
|
|
11
|
+
*
|
|
12
|
+
* 1. The `inputs` block is OPTIONAL. Workflows without one accept any
|
|
13
|
+
* JSON object (back-compat with every workflow shipped before this
|
|
14
|
+
* change). Author opts in by adding the block.
|
|
15
|
+
* 2. Types are the JSON-native primitives we can validate without a
|
|
16
|
+
* schema engine: `string`, `number`, `boolean`, plus `string[]` for
|
|
17
|
+
* multi-value cases (labels, files, etc.). This is intentionally
|
|
18
|
+
* narrower than full JSON Schema. Authors who need richer shapes can
|
|
19
|
+
* still pass an arbitrary object; declaring it just opts into the
|
|
20
|
+
* validator. We can widen later without breaking existing YAML.
|
|
21
|
+
* 3. `required: true` makes a field mandatory. Missing fields surface a
|
|
22
|
+
* single grouped error listing every gap, not one error per call.
|
|
23
|
+
* 4. `default` fills in the value when the caller omits it. The default
|
|
24
|
+
* is type-checked against the field's `type` at parse time, so
|
|
25
|
+
* authors can't ship a YAML that injects a string into a number
|
|
26
|
+
* field at run time. `required: true` and `default` are mutually
|
|
27
|
+
* exclusive: declaring both is incoherent (the default either
|
|
28
|
+
* satisfies the required check, making it vestigial, or it doesn't,
|
|
29
|
+
* making the default dead code), so the schema rejects the
|
|
30
|
+
* combination at parse time.
|
|
31
|
+
* 5. Telemetry redaction: the executor only ever sees the resolved
|
|
32
|
+
* `input` map. Cloud observers see the *shape* (key names + types)
|
|
33
|
+
* via `summarizeInputShape`, never the values, so a workflow that
|
|
34
|
+
* takes API tokens as input never leaks them.
|
|
35
|
+
*
|
|
36
|
+
* Out of scope on purpose:
|
|
37
|
+
* - No templating language (`{{input.foo}}` etc.). Workflow instructions
|
|
38
|
+
* are natural-language and the LLM already sees `input` in its context
|
|
39
|
+
* map; that path is good enough for v1 and avoids inventing a dialect.
|
|
40
|
+
* - No nested object schemas. If a single workflow needs deep input,
|
|
41
|
+
* pass a JSON blob through and document it; we can layer schemas in
|
|
42
|
+
* later. Most production use cases are flat (since_tag, until_tag,
|
|
43
|
+
* dry_run, repo, time_range, etc.).
|
|
44
|
+
*/
|
|
45
|
+
import { z } from "zod";
|
|
46
|
+
/**
|
|
47
|
+
* Supported input field types.
|
|
48
|
+
*
|
|
49
|
+
* Kept narrow on purpose. See module docstring for rationale.
|
|
50
|
+
*/
|
|
51
|
+
export const WORKFLOW_INPUT_TYPES = ["string", "number", "boolean", "string[]"];
|
|
52
|
+
// ─── Zod schema ─────────────────────────────────────────────────
|
|
53
|
+
const workflowInputTypeZ = z.enum(WORKFLOW_INPUT_TYPES);
|
|
54
|
+
/**
|
|
55
|
+
* Per-field validator. Cross-field checks (default matches type, enum
|
|
56
|
+
* values match type) run in superRefine so all problems on a single field
|
|
57
|
+
* surface together rather than one-at-a-time.
|
|
58
|
+
*/
|
|
59
|
+
const workflowInputFieldZ = z
|
|
60
|
+
.object({
|
|
61
|
+
type: workflowInputTypeZ,
|
|
62
|
+
description: z.string().optional(),
|
|
63
|
+
required: z.boolean().optional(),
|
|
64
|
+
default: z.unknown().optional(),
|
|
65
|
+
enum: z.array(z.unknown()).min(1).optional(),
|
|
66
|
+
})
|
|
67
|
+
.strict()
|
|
68
|
+
.superRefine((field, ctx) => {
|
|
69
|
+
// `required: true` together with a `default` is incoherent: if the
|
|
70
|
+
// default substitutes for an omitted value, the field is effectively
|
|
71
|
+
// optional; if the required check fires, the default is dead code.
|
|
72
|
+
// Reject the combination at parse time so authors fix the YAML
|
|
73
|
+
// instead of relying on undocumented runtime tie-breaking.
|
|
74
|
+
if (field.required === true && field.default !== undefined) {
|
|
75
|
+
ctx.addIssue({
|
|
76
|
+
code: z.ZodIssueCode.custom,
|
|
77
|
+
message: "field cannot declare both `required: true` and `default`; pick one (a default makes the field optional)",
|
|
78
|
+
path: ["required"],
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (field.default !== undefined) {
|
|
82
|
+
const err = checkValueType(field.default, field.type);
|
|
83
|
+
if (err) {
|
|
84
|
+
ctx.addIssue({
|
|
85
|
+
code: z.ZodIssueCode.custom,
|
|
86
|
+
message: `default ${err}`,
|
|
87
|
+
path: ["default"],
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (field.enum) {
|
|
92
|
+
for (let i = 0; i < field.enum.length; i++) {
|
|
93
|
+
const err = checkValueType(field.enum[i], field.type);
|
|
94
|
+
if (err) {
|
|
95
|
+
ctx.addIssue({
|
|
96
|
+
code: z.ZodIssueCode.custom,
|
|
97
|
+
message: `enum[${i}] ${err}`,
|
|
98
|
+
path: ["enum", i],
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
export const workflowInputsZ = z.record(workflowInputFieldZ);
|
|
105
|
+
/**
|
|
106
|
+
* Validate the caller's raw input object against the workflow's declared
|
|
107
|
+
* `inputs` block. Applies defaults for omitted optional fields. Surfaces
|
|
108
|
+
* every problem in a single response so the CLI prints a useful message
|
|
109
|
+
* instead of failing on the first error.
|
|
110
|
+
*
|
|
111
|
+
* When no `inputs` block is declared, returns the caller's object verbatim
|
|
112
|
+
* (back-compat: every existing workflow passes through unchanged).
|
|
113
|
+
*/
|
|
114
|
+
export function validateRuntimeInput(declared, raw) {
|
|
115
|
+
// Back-compat: no declaration → accept anything.
|
|
116
|
+
if (!declared || Object.keys(declared).length === 0) {
|
|
117
|
+
if (raw == null)
|
|
118
|
+
return { ok: true, value: {} };
|
|
119
|
+
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
120
|
+
return { ok: false, errors: [{ field: "(root)", message: "input must be a JSON object" }] };
|
|
121
|
+
}
|
|
122
|
+
return { ok: true, value: raw };
|
|
123
|
+
}
|
|
124
|
+
if (raw != null && (typeof raw !== "object" || Array.isArray(raw))) {
|
|
125
|
+
return { ok: false, errors: [{ field: "(root)", message: "input must be a JSON object" }] };
|
|
126
|
+
}
|
|
127
|
+
const provided = (raw ?? {});
|
|
128
|
+
const errors = [];
|
|
129
|
+
const out = {};
|
|
130
|
+
for (const [name, field] of Object.entries(declared)) {
|
|
131
|
+
const has = Object.prototype.hasOwnProperty.call(provided, name);
|
|
132
|
+
let value = has ? provided[name] : undefined;
|
|
133
|
+
if (!has || value === undefined || value === null) {
|
|
134
|
+
if (field.default !== undefined) {
|
|
135
|
+
out[name] = field.default;
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (field.required) {
|
|
139
|
+
errors.push({ field: name, message: "required but not provided" });
|
|
140
|
+
}
|
|
141
|
+
// Optional and no default: leave unset. Downstream `priorNode.input.X`
|
|
142
|
+
// reads will see `undefined`, which JSON-serializes as absent.
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const typeErr = checkValueType(value, field.type);
|
|
146
|
+
if (typeErr) {
|
|
147
|
+
errors.push({ field: name, message: typeErr });
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (field.enum && !field.enum.some((v) => deepEqual(v, value))) {
|
|
151
|
+
errors.push({
|
|
152
|
+
field: name,
|
|
153
|
+
message: `must be one of: ${field.enum.map((v) => JSON.stringify(v)).join(", ")}`,
|
|
154
|
+
});
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
out[name] = value;
|
|
158
|
+
}
|
|
159
|
+
// Pass through caller-provided keys that aren't in the declaration.
|
|
160
|
+
// This is intentional: existing CLI flags (timeRange, dryRun, etc.)
|
|
161
|
+
// and the cascade `rules`/`context` mechanism inject extra keys into
|
|
162
|
+
// the input bag. The declaration narrows the contract for documented
|
|
163
|
+
// fields without locking down the whole object.
|
|
164
|
+
for (const [k, v] of Object.entries(provided)) {
|
|
165
|
+
if (!Object.prototype.hasOwnProperty.call(declared, k)) {
|
|
166
|
+
out[k] = v;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (errors.length > 0)
|
|
170
|
+
return { ok: false, errors };
|
|
171
|
+
return { ok: true, value: out };
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Summary of an input bag suitable for telemetry: keys + observed types,
|
|
175
|
+
* never values. Cloud renderers use this to display the input contract a
|
|
176
|
+
* run was invoked with, without leaking the values themselves.
|
|
177
|
+
*
|
|
178
|
+
* `declared` shapes the output when present (so the summary stays stable
|
|
179
|
+
* across runs even when the caller omits optional fields). Falls back to
|
|
180
|
+
* the resolved values' runtime shape when no declaration exists.
|
|
181
|
+
*/
|
|
182
|
+
export function summarizeInputShape(declared, resolved) {
|
|
183
|
+
const shape = {};
|
|
184
|
+
if (declared) {
|
|
185
|
+
for (const [name, field] of Object.entries(declared)) {
|
|
186
|
+
shape[name] = field.type;
|
|
187
|
+
}
|
|
188
|
+
return shape;
|
|
189
|
+
}
|
|
190
|
+
if (!resolved)
|
|
191
|
+
return shape;
|
|
192
|
+
for (const [name, value] of Object.entries(resolved)) {
|
|
193
|
+
shape[name] = observedType(value);
|
|
194
|
+
}
|
|
195
|
+
return shape;
|
|
196
|
+
}
|
|
197
|
+
// ─── Internals ──────────────────────────────────────────────────
|
|
198
|
+
function checkValueType(value, type) {
|
|
199
|
+
switch (type) {
|
|
200
|
+
case "string":
|
|
201
|
+
return typeof value === "string" ? null : `must be a string (got ${observedType(value)})`;
|
|
202
|
+
case "number":
|
|
203
|
+
return typeof value === "number" && Number.isFinite(value)
|
|
204
|
+
? null
|
|
205
|
+
: `must be a finite number (got ${observedType(value)})`;
|
|
206
|
+
case "boolean":
|
|
207
|
+
return typeof value === "boolean" ? null : `must be a boolean (got ${observedType(value)})`;
|
|
208
|
+
case "string[]":
|
|
209
|
+
if (!Array.isArray(value))
|
|
210
|
+
return `must be an array of strings (got ${observedType(value)})`;
|
|
211
|
+
for (let i = 0; i < value.length; i++) {
|
|
212
|
+
if (typeof value[i] !== "string") {
|
|
213
|
+
return `must be an array of strings (element ${i} is ${observedType(value[i])})`;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function observedType(value) {
|
|
220
|
+
if (value === null)
|
|
221
|
+
return "null";
|
|
222
|
+
if (Array.isArray(value)) {
|
|
223
|
+
return value.every((v) => typeof v === "string") ? "string[]" : "object";
|
|
224
|
+
}
|
|
225
|
+
switch (typeof value) {
|
|
226
|
+
case "string":
|
|
227
|
+
return "string";
|
|
228
|
+
case "number":
|
|
229
|
+
return "number";
|
|
230
|
+
case "boolean":
|
|
231
|
+
return "boolean";
|
|
232
|
+
default:
|
|
233
|
+
return "object";
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function deepEqual(a, b) {
|
|
237
|
+
if (a === b)
|
|
238
|
+
return true;
|
|
239
|
+
if (typeof a !== typeof b)
|
|
240
|
+
return false;
|
|
241
|
+
if (a == null || b == null)
|
|
242
|
+
return false;
|
|
243
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
244
|
+
if (a.length !== b.length)
|
|
245
|
+
return false;
|
|
246
|
+
return a.every((v, i) => deepEqual(v, b[i]));
|
|
247
|
+
}
|
|
248
|
+
if (typeof a === "object" && typeof b === "object") {
|
|
249
|
+
const ak = Object.keys(a);
|
|
250
|
+
const bk = Object.keys(b);
|
|
251
|
+
if (ak.length !== bk.length)
|
|
252
|
+
return false;
|
|
253
|
+
return ak.every((k) => deepEqual(a[k], b[k]));
|
|
254
|
+
}
|
|
255
|
+
return false;
|
|
256
|
+
}
|
package/dist/schema.d.ts
CHANGED
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
import { z } from "zod";
|
|
10
10
|
import type { Workflow } from "./types.js";
|
|
11
11
|
import { sourceZ } from "./sources.js";
|
|
12
|
+
import { workflowInputsZ } from "./inputs.js";
|
|
12
13
|
export { sourceZ };
|
|
14
|
+
export { workflowInputsZ };
|
|
13
15
|
export declare const jsonSchemaZ: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
14
16
|
export declare const configFieldZ: z.ZodObject<{
|
|
15
17
|
description: z.ZodString;
|
|
@@ -34,12 +36,12 @@ export declare const toolZ: z.ZodObject<{
|
|
|
34
36
|
description: z.ZodString;
|
|
35
37
|
input_schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
36
38
|
}, "strip", z.ZodTypeAny, {
|
|
37
|
-
name: string;
|
|
38
39
|
description: string;
|
|
40
|
+
name: string;
|
|
39
41
|
input_schema: Record<string, unknown>;
|
|
40
42
|
}, {
|
|
41
|
-
name: string;
|
|
42
43
|
description: string;
|
|
44
|
+
name: string;
|
|
43
45
|
input_schema: Record<string, unknown>;
|
|
44
46
|
}>;
|
|
45
47
|
export declare const skillCategoryZ: z.ZodEnum<["general", "git", "tasks", "notification", "observability", "data"]>;
|
|
@@ -120,8 +122,8 @@ export declare const skillDefinitionZ: z.ZodEffects<z.ZodObject<{
|
|
|
120
122
|
args?: string[] | undefined;
|
|
121
123
|
}>>;
|
|
122
124
|
}, "strict", z.ZodTypeAny, {
|
|
123
|
-
name?: string | undefined;
|
|
124
125
|
description?: string | undefined;
|
|
126
|
+
name?: string | undefined;
|
|
125
127
|
instruction?: string | undefined;
|
|
126
128
|
mcp?: {
|
|
127
129
|
url?: string | undefined;
|
|
@@ -132,8 +134,8 @@ export declare const skillDefinitionZ: z.ZodEffects<z.ZodObject<{
|
|
|
132
134
|
args?: string[] | undefined;
|
|
133
135
|
} | undefined;
|
|
134
136
|
}, {
|
|
135
|
-
name?: string | undefined;
|
|
136
137
|
description?: string | undefined;
|
|
138
|
+
name?: string | undefined;
|
|
137
139
|
instruction?: string | undefined;
|
|
138
140
|
mcp?: {
|
|
139
141
|
url?: string | undefined;
|
|
@@ -144,8 +146,8 @@ export declare const skillDefinitionZ: z.ZodEffects<z.ZodObject<{
|
|
|
144
146
|
args?: string[] | undefined;
|
|
145
147
|
} | undefined;
|
|
146
148
|
}>, {
|
|
147
|
-
name?: string | undefined;
|
|
148
149
|
description?: string | undefined;
|
|
150
|
+
name?: string | undefined;
|
|
149
151
|
instruction?: string | undefined;
|
|
150
152
|
mcp?: {
|
|
151
153
|
url?: string | undefined;
|
|
@@ -156,8 +158,8 @@ export declare const skillDefinitionZ: z.ZodEffects<z.ZodObject<{
|
|
|
156
158
|
args?: string[] | undefined;
|
|
157
159
|
} | undefined;
|
|
158
160
|
}, {
|
|
159
|
-
name?: string | undefined;
|
|
160
161
|
description?: string | undefined;
|
|
162
|
+
name?: string | undefined;
|
|
161
163
|
instruction?: string | undefined;
|
|
162
164
|
mcp?: {
|
|
163
165
|
url?: string | undefined;
|
|
@@ -191,12 +193,12 @@ export declare const skillZ: z.ZodEffects<z.ZodObject<{
|
|
|
191
193
|
description: z.ZodString;
|
|
192
194
|
input_schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
193
195
|
}, "strip", z.ZodTypeAny, {
|
|
194
|
-
name: string;
|
|
195
196
|
description: string;
|
|
197
|
+
name: string;
|
|
196
198
|
input_schema: Record<string, unknown>;
|
|
197
199
|
}, {
|
|
198
|
-
name: string;
|
|
199
200
|
description: string;
|
|
201
|
+
name: string;
|
|
200
202
|
input_schema: Record<string, unknown>;
|
|
201
203
|
}>, "many">>;
|
|
202
204
|
instruction: z.ZodOptional<z.ZodString>;
|
|
@@ -238,9 +240,9 @@ export declare const skillZ: z.ZodEffects<z.ZodObject<{
|
|
|
238
240
|
}>>;
|
|
239
241
|
mcpAliases: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
|
|
240
242
|
}, "strip", z.ZodTypeAny, {
|
|
241
|
-
id: string;
|
|
242
|
-
name: string;
|
|
243
243
|
description: string;
|
|
244
|
+
name: string;
|
|
245
|
+
id: string;
|
|
244
246
|
category: "general" | "git" | "tasks" | "notification" | "observability" | "data";
|
|
245
247
|
config: Record<string, {
|
|
246
248
|
description: string;
|
|
@@ -248,8 +250,8 @@ export declare const skillZ: z.ZodEffects<z.ZodObject<{
|
|
|
248
250
|
env?: string | undefined;
|
|
249
251
|
}>;
|
|
250
252
|
tools: {
|
|
251
|
-
name: string;
|
|
252
253
|
description: string;
|
|
254
|
+
name: string;
|
|
253
255
|
input_schema: Record<string, unknown>;
|
|
254
256
|
}[];
|
|
255
257
|
instruction?: string | undefined;
|
|
@@ -263,9 +265,9 @@ export declare const skillZ: z.ZodEffects<z.ZodObject<{
|
|
|
263
265
|
} | undefined;
|
|
264
266
|
mcpAliases?: Record<string, string[]> | undefined;
|
|
265
267
|
}, {
|
|
266
|
-
id: string;
|
|
267
|
-
name: string;
|
|
268
268
|
description: string;
|
|
269
|
+
name: string;
|
|
270
|
+
id: string;
|
|
269
271
|
category: "general" | "git" | "tasks" | "notification" | "observability" | "data";
|
|
270
272
|
instruction?: string | undefined;
|
|
271
273
|
mcp?: {
|
|
@@ -282,15 +284,15 @@ export declare const skillZ: z.ZodEffects<z.ZodObject<{
|
|
|
282
284
|
env?: string | undefined;
|
|
283
285
|
}> | undefined;
|
|
284
286
|
tools?: {
|
|
285
|
-
name: string;
|
|
286
287
|
description: string;
|
|
288
|
+
name: string;
|
|
287
289
|
input_schema: Record<string, unknown>;
|
|
288
290
|
}[] | undefined;
|
|
289
291
|
mcpAliases?: Record<string, string[]> | undefined;
|
|
290
292
|
}>, {
|
|
291
|
-
id: string;
|
|
292
|
-
name: string;
|
|
293
293
|
description: string;
|
|
294
|
+
name: string;
|
|
295
|
+
id: string;
|
|
294
296
|
category: "general" | "git" | "tasks" | "notification" | "observability" | "data";
|
|
295
297
|
config: Record<string, {
|
|
296
298
|
description: string;
|
|
@@ -298,8 +300,8 @@ export declare const skillZ: z.ZodEffects<z.ZodObject<{
|
|
|
298
300
|
env?: string | undefined;
|
|
299
301
|
}>;
|
|
300
302
|
tools: {
|
|
301
|
-
name: string;
|
|
302
303
|
description: string;
|
|
304
|
+
name: string;
|
|
303
305
|
input_schema: Record<string, unknown>;
|
|
304
306
|
}[];
|
|
305
307
|
instruction?: string | undefined;
|
|
@@ -313,9 +315,9 @@ export declare const skillZ: z.ZodEffects<z.ZodObject<{
|
|
|
313
315
|
} | undefined;
|
|
314
316
|
mcpAliases?: Record<string, string[]> | undefined;
|
|
315
317
|
}, {
|
|
316
|
-
id: string;
|
|
317
|
-
name: string;
|
|
318
318
|
description: string;
|
|
319
|
+
name: string;
|
|
320
|
+
id: string;
|
|
319
321
|
category: "general" | "git" | "tasks" | "notification" | "observability" | "data";
|
|
320
322
|
instruction?: string | undefined;
|
|
321
323
|
mcp?: {
|
|
@@ -332,8 +334,8 @@ export declare const skillZ: z.ZodEffects<z.ZodObject<{
|
|
|
332
334
|
env?: string | undefined;
|
|
333
335
|
}> | undefined;
|
|
334
336
|
tools?: {
|
|
335
|
-
name: string;
|
|
336
337
|
description: string;
|
|
338
|
+
name: string;
|
|
337
339
|
input_schema: Record<string, unknown>;
|
|
338
340
|
}[] | undefined;
|
|
339
341
|
mcpAliases?: Record<string, string[]> | undefined;
|
|
@@ -2041,8 +2043,8 @@ export declare const workflowZ: z.ZodObject<{
|
|
|
2041
2043
|
args?: string[] | undefined;
|
|
2042
2044
|
}>>;
|
|
2043
2045
|
}, "strict", z.ZodTypeAny, {
|
|
2044
|
-
name?: string | undefined;
|
|
2045
2046
|
description?: string | undefined;
|
|
2047
|
+
name?: string | undefined;
|
|
2046
2048
|
instruction?: string | undefined;
|
|
2047
2049
|
mcp?: {
|
|
2048
2050
|
url?: string | undefined;
|
|
@@ -2053,8 +2055,8 @@ export declare const workflowZ: z.ZodObject<{
|
|
|
2053
2055
|
args?: string[] | undefined;
|
|
2054
2056
|
} | undefined;
|
|
2055
2057
|
}, {
|
|
2056
|
-
name?: string | undefined;
|
|
2057
2058
|
description?: string | undefined;
|
|
2059
|
+
name?: string | undefined;
|
|
2058
2060
|
instruction?: string | undefined;
|
|
2059
2061
|
mcp?: {
|
|
2060
2062
|
url?: string | undefined;
|
|
@@ -2065,8 +2067,8 @@ export declare const workflowZ: z.ZodObject<{
|
|
|
2065
2067
|
args?: string[] | undefined;
|
|
2066
2068
|
} | undefined;
|
|
2067
2069
|
}>, {
|
|
2068
|
-
name?: string | undefined;
|
|
2069
2070
|
description?: string | undefined;
|
|
2071
|
+
name?: string | undefined;
|
|
2070
2072
|
instruction?: string | undefined;
|
|
2071
2073
|
mcp?: {
|
|
2072
2074
|
url?: string | undefined;
|
|
@@ -2077,8 +2079,8 @@ export declare const workflowZ: z.ZodObject<{
|
|
|
2077
2079
|
args?: string[] | undefined;
|
|
2078
2080
|
} | undefined;
|
|
2079
2081
|
}, {
|
|
2080
|
-
name?: string | undefined;
|
|
2081
2082
|
description?: string | undefined;
|
|
2083
|
+
name?: string | undefined;
|
|
2082
2084
|
instruction?: string | undefined;
|
|
2083
2085
|
mcp?: {
|
|
2084
2086
|
url?: string | undefined;
|
|
@@ -2135,13 +2137,44 @@ export declare const workflowZ: z.ZodObject<{
|
|
|
2135
2137
|
}>]>, "many">>;
|
|
2136
2138
|
judge_model: z.ZodOptional<z.ZodString>;
|
|
2137
2139
|
judge_budget: z.ZodOptional<z.ZodNumber>;
|
|
2140
|
+
inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodObject<{
|
|
2141
|
+
type: z.ZodEnum<["string", "number", "boolean", "string[]"]>;
|
|
2142
|
+
description: z.ZodOptional<z.ZodString>;
|
|
2143
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
2144
|
+
default: z.ZodOptional<z.ZodUnknown>;
|
|
2145
|
+
enum: z.ZodOptional<z.ZodArray<z.ZodUnknown, "many">>;
|
|
2146
|
+
}, "strict", z.ZodTypeAny, {
|
|
2147
|
+
type: "string" | "number" | "boolean" | "string[]";
|
|
2148
|
+
description?: string | undefined;
|
|
2149
|
+
required?: boolean | undefined;
|
|
2150
|
+
default?: unknown;
|
|
2151
|
+
enum?: unknown[] | undefined;
|
|
2152
|
+
}, {
|
|
2153
|
+
type: "string" | "number" | "boolean" | "string[]";
|
|
2154
|
+
description?: string | undefined;
|
|
2155
|
+
required?: boolean | undefined;
|
|
2156
|
+
default?: unknown;
|
|
2157
|
+
enum?: unknown[] | undefined;
|
|
2158
|
+
}>, {
|
|
2159
|
+
type: "string" | "number" | "boolean" | "string[]";
|
|
2160
|
+
description?: string | undefined;
|
|
2161
|
+
required?: boolean | undefined;
|
|
2162
|
+
default?: unknown;
|
|
2163
|
+
enum?: unknown[] | undefined;
|
|
2164
|
+
}, {
|
|
2165
|
+
type: "string" | "number" | "boolean" | "string[]";
|
|
2166
|
+
description?: string | undefined;
|
|
2167
|
+
required?: boolean | undefined;
|
|
2168
|
+
default?: unknown;
|
|
2169
|
+
enum?: unknown[] | undefined;
|
|
2170
|
+
}>>>;
|
|
2138
2171
|
}, "strip", z.ZodTypeAny, {
|
|
2139
|
-
id: string;
|
|
2140
|
-
name: string;
|
|
2141
2172
|
description: string;
|
|
2173
|
+
name: string;
|
|
2174
|
+
id: string;
|
|
2142
2175
|
skills: Record<string, {
|
|
2143
|
-
name?: string | undefined;
|
|
2144
2176
|
description?: string | undefined;
|
|
2177
|
+
name?: string | undefined;
|
|
2145
2178
|
instruction?: string | undefined;
|
|
2146
2179
|
mcp?: {
|
|
2147
2180
|
url?: string | undefined;
|
|
@@ -2267,9 +2300,16 @@ export declare const workflowZ: z.ZodObject<{
|
|
|
2267
2300
|
judge_model?: string | undefined;
|
|
2268
2301
|
workflow_type?: "pr_review" | "e2e_test" | "content_generation" | "monitor" | "data_sync" | "generic" | undefined;
|
|
2269
2302
|
judge_budget?: number | undefined;
|
|
2303
|
+
inputs?: Record<string, {
|
|
2304
|
+
type: "string" | "number" | "boolean" | "string[]";
|
|
2305
|
+
description?: string | undefined;
|
|
2306
|
+
required?: boolean | undefined;
|
|
2307
|
+
default?: unknown;
|
|
2308
|
+
enum?: unknown[] | undefined;
|
|
2309
|
+
}> | undefined;
|
|
2270
2310
|
}, {
|
|
2271
|
-
id: string;
|
|
2272
2311
|
name: string;
|
|
2312
|
+
id: string;
|
|
2273
2313
|
nodes: Record<string, {
|
|
2274
2314
|
name: string;
|
|
2275
2315
|
instruction: string | {
|
|
@@ -2368,8 +2408,8 @@ export declare const workflowZ: z.ZodObject<{
|
|
|
2368
2408
|
entry: string;
|
|
2369
2409
|
description?: string | undefined;
|
|
2370
2410
|
skills?: Record<string, {
|
|
2371
|
-
name?: string | undefined;
|
|
2372
2411
|
description?: string | undefined;
|
|
2412
|
+
name?: string | undefined;
|
|
2373
2413
|
instruction?: string | undefined;
|
|
2374
2414
|
mcp?: {
|
|
2375
2415
|
url?: string | undefined;
|
|
@@ -2399,15 +2439,22 @@ export declare const workflowZ: z.ZodObject<{
|
|
|
2399
2439
|
judge_model?: string | undefined;
|
|
2400
2440
|
workflow_type?: "pr_review" | "e2e_test" | "content_generation" | "monitor" | "data_sync" | "generic" | undefined;
|
|
2401
2441
|
judge_budget?: number | undefined;
|
|
2442
|
+
inputs?: Record<string, {
|
|
2443
|
+
type: "string" | "number" | "boolean" | "string[]";
|
|
2444
|
+
description?: string | undefined;
|
|
2445
|
+
required?: boolean | undefined;
|
|
2446
|
+
default?: unknown;
|
|
2447
|
+
enum?: unknown[] | undefined;
|
|
2448
|
+
}> | undefined;
|
|
2402
2449
|
}>;
|
|
2403
2450
|
/** Parse + validate a raw object as a Workflow. Throws on invalid input. */
|
|
2404
2451
|
export declare function parseWorkflow(raw: unknown): {
|
|
2405
|
-
id: string;
|
|
2406
|
-
name: string;
|
|
2407
2452
|
description: string;
|
|
2453
|
+
name: string;
|
|
2454
|
+
id: string;
|
|
2408
2455
|
skills: Record<string, {
|
|
2409
|
-
name?: string | undefined;
|
|
2410
2456
|
description?: string | undefined;
|
|
2457
|
+
name?: string | undefined;
|
|
2411
2458
|
instruction?: string | undefined;
|
|
2412
2459
|
mcp?: {
|
|
2413
2460
|
url?: string | undefined;
|
|
@@ -2533,6 +2580,13 @@ export declare function parseWorkflow(raw: unknown): {
|
|
|
2533
2580
|
judge_model?: string | undefined;
|
|
2534
2581
|
workflow_type?: "pr_review" | "e2e_test" | "content_generation" | "monitor" | "data_sync" | "generic" | undefined;
|
|
2535
2582
|
judge_budget?: number | undefined;
|
|
2583
|
+
inputs?: Record<string, {
|
|
2584
|
+
type: "string" | "number" | "boolean" | "string[]";
|
|
2585
|
+
description?: string | undefined;
|
|
2586
|
+
required?: boolean | undefined;
|
|
2587
|
+
default?: unknown;
|
|
2588
|
+
enum?: unknown[] | undefined;
|
|
2589
|
+
}> | undefined;
|
|
2536
2590
|
};
|
|
2537
2591
|
export interface WorkflowError {
|
|
2538
2592
|
code: "MISSING_ENTRY" | "UNKNOWN_EDGE_SOURCE" | "UNKNOWN_EDGE_TARGET" | "UNREACHABLE_NODE" | "UNKNOWN_SKILL" | "SELF_LOOP" | "UNBOUNDED_CYCLE" | "INVALID_INLINE_SKILL";
|
|
@@ -2802,6 +2856,39 @@ export declare const workflowJsonSchema: {
|
|
|
2802
2856
|
readonly default: 50;
|
|
2803
2857
|
readonly description: "Soft cap on expected judge calls per workflow run. Executor warns at load time if exceeded; not a hard runtime cap in v1.";
|
|
2804
2858
|
};
|
|
2859
|
+
readonly inputs: {
|
|
2860
|
+
readonly type: "object";
|
|
2861
|
+
readonly description: "Declared per-run input contract. Each entry names a parameter the caller may supply via --input. The CLI validates against this declaration, applies defaults for omitted optional fields, and rejects unknown types before the executor runs. Optional; workflows without an inputs block accept any JSON object (back-compat).";
|
|
2862
|
+
readonly additionalProperties: {
|
|
2863
|
+
readonly type: "object";
|
|
2864
|
+
readonly required: readonly ["type"];
|
|
2865
|
+
readonly additionalProperties: false;
|
|
2866
|
+
readonly properties: {
|
|
2867
|
+
readonly type: {
|
|
2868
|
+
readonly type: "string";
|
|
2869
|
+
readonly enum: readonly ["string", "number", "boolean", "string[]"];
|
|
2870
|
+
readonly description: "JSON-native type. Use a flat object if you need richer shapes.";
|
|
2871
|
+
};
|
|
2872
|
+
readonly description: {
|
|
2873
|
+
readonly type: "string";
|
|
2874
|
+
readonly description: "Human-readable purpose. Shown in CLI help and cloud renderers.";
|
|
2875
|
+
};
|
|
2876
|
+
readonly required: {
|
|
2877
|
+
readonly type: "boolean";
|
|
2878
|
+
readonly default: false;
|
|
2879
|
+
readonly description: "When true, the caller must provide a value.";
|
|
2880
|
+
};
|
|
2881
|
+
readonly default: {
|
|
2882
|
+
readonly description: "Value applied when the caller omits the field. Type-checked at parse time against 'type'.";
|
|
2883
|
+
};
|
|
2884
|
+
readonly enum: {
|
|
2885
|
+
readonly type: "array";
|
|
2886
|
+
readonly minItems: 1;
|
|
2887
|
+
readonly description: "Optional set of allowed values. Validated after the type check.";
|
|
2888
|
+
};
|
|
2889
|
+
};
|
|
2890
|
+
};
|
|
2891
|
+
};
|
|
2805
2892
|
readonly nodes: {
|
|
2806
2893
|
readonly type: "object";
|
|
2807
2894
|
readonly additionalProperties: {
|
package/dist/schema.js
CHANGED
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
import { z } from "zod";
|
|
10
10
|
import { EVALUATOR_KINDS, EVAL_POLICIES, MCP_TRANSPORTS, REQUIRES_ON_FAIL, SKILL_CATEGORIES, SKILL_ID_MAX_LENGTH, SKILL_ID_PATTERN, } from "./types.js";
|
|
11
11
|
import { sourceZ } from "./sources.js";
|
|
12
|
+
import { workflowInputsZ, WORKFLOW_INPUT_TYPES } from "./inputs.js";
|
|
12
13
|
export { sourceZ };
|
|
14
|
+
export { workflowInputsZ };
|
|
13
15
|
// ─── Zod Schemas ─────────────────────────────────────────────────
|
|
14
16
|
export const jsonSchemaZ = z.record(z.unknown());
|
|
15
17
|
export const configFieldZ = z.object({
|
|
@@ -241,6 +243,7 @@ export const workflowZ = z.object({
|
|
|
241
243
|
context: z.array(sourceZ).optional(),
|
|
242
244
|
judge_model: z.string().min(1).optional(),
|
|
243
245
|
judge_budget: z.number().int().min(0).optional(),
|
|
246
|
+
inputs: workflowInputsZ.optional(),
|
|
244
247
|
});
|
|
245
248
|
const LEGACY_VERIFY_MESSAGE = "uses the legacy 'verify:' field. It was renamed to 'eval:' in @sweny-ai/core v0.2.0 with a different shape (named evaluators with kind: value | function | judge). " +
|
|
246
249
|
"Migration guide: https://spec.sweny.ai/nodes/#eval";
|
|
@@ -572,6 +575,39 @@ export const workflowJsonSchema = {
|
|
|
572
575
|
default: 50,
|
|
573
576
|
description: "Soft cap on expected judge calls per workflow run. Executor warns at load time if exceeded; not a hard runtime cap in v1.",
|
|
574
577
|
},
|
|
578
|
+
inputs: {
|
|
579
|
+
type: "object",
|
|
580
|
+
description: "Declared per-run input contract. Each entry names a parameter the caller may supply via --input. The CLI validates against this declaration, applies defaults for omitted optional fields, and rejects unknown types before the executor runs. Optional; workflows without an inputs block accept any JSON object (back-compat).",
|
|
581
|
+
additionalProperties: {
|
|
582
|
+
type: "object",
|
|
583
|
+
required: ["type"],
|
|
584
|
+
additionalProperties: false,
|
|
585
|
+
properties: {
|
|
586
|
+
type: {
|
|
587
|
+
type: "string",
|
|
588
|
+
enum: [...WORKFLOW_INPUT_TYPES],
|
|
589
|
+
description: "JSON-native type. Use a flat object if you need richer shapes.",
|
|
590
|
+
},
|
|
591
|
+
description: {
|
|
592
|
+
type: "string",
|
|
593
|
+
description: "Human-readable purpose. Shown in CLI help and cloud renderers.",
|
|
594
|
+
},
|
|
595
|
+
required: {
|
|
596
|
+
type: "boolean",
|
|
597
|
+
default: false,
|
|
598
|
+
description: "When true, the caller must provide a value.",
|
|
599
|
+
},
|
|
600
|
+
default: {
|
|
601
|
+
description: "Value applied when the caller omits the field. Type-checked at parse time against 'type'.",
|
|
602
|
+
},
|
|
603
|
+
enum: {
|
|
604
|
+
type: "array",
|
|
605
|
+
minItems: 1,
|
|
606
|
+
description: "Optional set of allowed values. Validated after the type check.",
|
|
607
|
+
},
|
|
608
|
+
},
|
|
609
|
+
},
|
|
610
|
+
},
|
|
575
611
|
nodes: {
|
|
576
612
|
type: "object",
|
|
577
613
|
additionalProperties: {
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export type { Source, ResolvedSource, SourceKind, SourceResolutionMap } from "./sources.js";
|
|
2
|
+
export type { WorkflowInputs, WorkflowInputField, WorkflowInputType, InputValidationError, InputValidationResult, } from "./inputs.js";
|
|
3
|
+
export { WORKFLOW_INPUT_TYPES } from "./inputs.js";
|
|
2
4
|
import type { Source as _Source, ResolvedSource as _ResolvedSource } from "./sources.js";
|
|
3
5
|
export type JSONSchema = Record<string, unknown>;
|
|
4
6
|
/** Context passed to tool handlers at execution time */
|
|
@@ -311,6 +313,16 @@ export interface Workflow {
|
|
|
311
313
|
judge_model?: string;
|
|
312
314
|
/** Soft cap on expected judge calls per workflow run. Warning at load time when exceeded. */
|
|
313
315
|
judge_budget?: number;
|
|
316
|
+
/**
|
|
317
|
+
* Declared per-run input contract. When present, the CLI validates the
|
|
318
|
+
* caller-provided `--input` JSON against this declaration, applies defaults
|
|
319
|
+
* for omitted optional fields, and rejects malformed input before the
|
|
320
|
+
* executor runs. Workflows without an `inputs` block accept any JSON
|
|
321
|
+
* object (back-compat).
|
|
322
|
+
*
|
|
323
|
+
* See `src/inputs.ts` for the field shape and validation rules.
|
|
324
|
+
*/
|
|
325
|
+
inputs?: import("./inputs.js").WorkflowInputs;
|
|
314
326
|
}
|
|
315
327
|
/**
|
|
316
328
|
* Inline skill definition in a workflow's `skills` block.
|
package/dist/types.js
CHANGED