feat: authorize workflow contract authoring
This commit is contained in:
@@ -246,6 +246,198 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AuthoringContractInventoryPayload": {
|
||||
"description": "Revision-scoped readable sources and writable authoring targets.",
|
||||
"properties": {
|
||||
"entry_steps": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringStepContractPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"readable_sources": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"revision": {
|
||||
"type": "integer"
|
||||
},
|
||||
"selected_step_id": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"state_targets": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"step_input_targets": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"step_output_sources": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"warnings": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"workflow_outcomes": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"workflow_output_targets": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"workspace_id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"workspace_id",
|
||||
"revision",
|
||||
"selected_step_id",
|
||||
"readable_sources",
|
||||
"step_input_targets",
|
||||
"step_output_sources",
|
||||
"state_targets",
|
||||
"workflow_output_targets",
|
||||
"entry_steps",
|
||||
"workflow_outcomes",
|
||||
"warnings"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AuthoringPathAvailability": {
|
||||
"enum": [
|
||||
"available",
|
||||
"conditional"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AuthoringPathOptionPayload": {
|
||||
"description": "One schema-derived source or target available to an author.",
|
||||
"properties": {
|
||||
"availability": {
|
||||
"$ref": "#/components/schemas/AuthoringPathAvailability"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"origin": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOrigin"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string"
|
||||
},
|
||||
"required": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/JsonObject"
|
||||
},
|
||||
"uses": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathUse"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"label",
|
||||
"origin",
|
||||
"schema",
|
||||
"required",
|
||||
"availability",
|
||||
"uses"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AuthoringPathOrigin": {
|
||||
"enum": [
|
||||
"workflow_input",
|
||||
"workflow_state",
|
||||
"runtime_context",
|
||||
"step_input",
|
||||
"step_output",
|
||||
"workflow_output"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AuthoringPathUse": {
|
||||
"enum": [
|
||||
"step_input",
|
||||
"step_output_source",
|
||||
"state_target",
|
||||
"workflow_output"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AuthoringStepContractPayload": {
|
||||
"description": "Compact executable-step choice used by authoring inventories.",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"input_targets": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"outcomes": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"output_sources": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"step_id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"step_id",
|
||||
"label"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"BinaryCondition": {
|
||||
"description": "Condition that compares two operands.",
|
||||
"properties": {
|
||||
@@ -6953,6 +7145,65 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"action": "inspect_authoring_contract",
|
||||
"errors": [
|
||||
{
|
||||
"$ref": "#/components/errors/5000"
|
||||
}
|
||||
],
|
||||
"method": "workflow.draft_workspaces.inspect_authoring_contract",
|
||||
"namespace": [
|
||||
"workflow",
|
||||
"draft_workspaces"
|
||||
],
|
||||
"params": [
|
||||
{
|
||||
"name": "workspace_id",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"minLength": 1,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "revision",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"minimum": 1,
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "selected_step_id",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"minLength": 1,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/AuthoringContractInventoryPayload"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/DraftWorkspaceResult"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"action": "list",
|
||||
"errors": [
|
||||
|
||||
@@ -255,9 +255,7 @@ def manifest_from_openrpc(document: Mapping[str, object]) -> ContractManifest:
|
||||
params.append(
|
||||
{
|
||||
"name": _string(parameter.get("name"), f"{parameter_path}.name"),
|
||||
"required": _boolean(
|
||||
raw_required, f"{parameter_path}.required"
|
||||
),
|
||||
"required": _boolean(raw_required, f"{parameter_path}.required"),
|
||||
"schema": _schema(
|
||||
parameter.get("schema"), f"{parameter_path}.schema"
|
||||
),
|
||||
@@ -271,12 +269,21 @@ def manifest_from_openrpc(document: Mapping[str, object]) -> ContractManifest:
|
||||
f"{result_path}.schema", "missing success result schema"
|
||||
)
|
||||
raw_result_schema = result["schema"]
|
||||
if not isinstance(raw_result_schema, Mapping) or (
|
||||
set(raw_result_schema) != {"$ref"}
|
||||
or not (
|
||||
isinstance(raw_result_schema.get("$ref"), str)
|
||||
and raw_result_schema["$ref"].startswith("#/components/schemas/")
|
||||
if not isinstance(raw_result_schema, Mapping):
|
||||
raise ManifestError(
|
||||
f"{result_path}.schema",
|
||||
"success result must be a schema object",
|
||||
)
|
||||
named_result = (
|
||||
set(raw_result_schema) == {"$ref"}
|
||||
and isinstance(raw_result_schema.get("$ref"), str)
|
||||
and raw_result_schema["$ref"].startswith("#/components/schemas/")
|
||||
)
|
||||
# This inspection RPC returns either its inventory or the standard
|
||||
# revision-conflict workspace payload, so its OpenRPC result is a union.
|
||||
if (
|
||||
not named_result
|
||||
and method_name != "workflow.draft_workspaces.inspect_authoring_contract"
|
||||
):
|
||||
raise ManifestError(
|
||||
f"{result_path}.schema",
|
||||
|
||||
@@ -89,14 +89,24 @@ def test_generates_the_complete_real_workflow_contract() -> None:
|
||||
manifest = generate_manifest()
|
||||
schemas = manifest["components"]["schemas"]
|
||||
|
||||
assert len(manifest["operations"]) == 70
|
||||
assert len({operation["method"] for operation in manifest["operations"]}) == 70
|
||||
assert len(schemas) == 134
|
||||
assert len(manifest["operations"]) == 71
|
||||
assert len({operation["method"] for operation in manifest["operations"]}) == 71
|
||||
assert len(schemas) == 140
|
||||
assert len(manifest["components"]["errors"]) == 1
|
||||
assert all(
|
||||
set(operation["result"]["schema"]) == {"$ref"}
|
||||
or operation["method"] == "workflow.draft_workspaces.inspect_authoring_contract"
|
||||
for operation in manifest["operations"]
|
||||
)
|
||||
inspection = next(
|
||||
operation
|
||||
for operation in manifest["operations"]
|
||||
if operation["method"] == "workflow.draft_workspaces.inspect_authoring_contract"
|
||||
)
|
||||
assert inspection["result"]["schema"]["anyOf"] == [
|
||||
{"$ref": "#/components/schemas/AuthoringContractInventoryPayload"},
|
||||
{"$ref": "#/components/schemas/DraftWorkspaceResult"},
|
||||
]
|
||||
assert {name for name in UNION_RESULTS if "anyOf" in schemas[name]} == UNION_RESULTS
|
||||
|
||||
|
||||
@@ -175,6 +185,17 @@ def test_manifest_contains_the_two_focused_step_binding_operations() -> None:
|
||||
} <= methods
|
||||
|
||||
|
||||
def test_manifest_contains_the_four_browser_authoring_operations() -> None:
|
||||
methods = {operation["method"] for operation in generate_manifest()["operations"]}
|
||||
|
||||
assert {
|
||||
"workflow.draft_workspaces.inspect_authoring_contract",
|
||||
"workflow.draft_workspaces.set_contract",
|
||||
"workflow.draft_workspaces.set_start",
|
||||
"workflow.draft_workspaces.set_workflow_output_bindings",
|
||||
} <= methods
|
||||
|
||||
|
||||
def test_generated_contract_preserves_security_and_extension_boundaries() -> None:
|
||||
manifest = generate_manifest()
|
||||
schemas = manifest["components"]["schemas"]
|
||||
|
||||
@@ -48,14 +48,18 @@ const OperationNameSchema = v.union([
|
||||
v.literal("workflow.capabilities.call"),
|
||||
v.literal("workflow.draft_workspaces.list"),
|
||||
v.literal("workflow.draft_workspaces.get"),
|
||||
v.literal("workflow.draft_workspaces.inspect_authoring_contract"),
|
||||
v.literal("workflow.draft_workspaces.create_empty"),
|
||||
v.literal("workflow.draft_workspaces.create_from_capability"),
|
||||
v.literal("workflow.draft_workspaces.add_step_from_capability"),
|
||||
v.literal("workflow.draft_workspaces.update_capability_step"),
|
||||
v.literal("workflow.draft_workspaces.set_route"),
|
||||
v.literal("workflow.draft_workspaces.set_contract"),
|
||||
v.literal("workflow.draft_workspaces.set_start"),
|
||||
v.literal("workflow.draft_workspaces.set_step_input_bindings"),
|
||||
v.literal("workflow.draft_workspaces.set_step_output_bindings"),
|
||||
v.literal("workflow.draft_workspaces.validate"),
|
||||
v.literal("workflow.draft_workspaces.set_workflow_output_bindings"),
|
||||
v.literal("workflow.artifacts.list"),
|
||||
v.literal("workflow.artifacts.inspect"),
|
||||
v.literal("workflow.deployments.list"),
|
||||
|
||||
@@ -260,6 +260,10 @@ describe("POST /api/rpc", () => {
|
||||
operation: "workflow.draft_workspaces.get",
|
||||
params: { workspace_id: "draft-1" },
|
||||
},
|
||||
{
|
||||
operation: "workflow.draft_workspaces.inspect_authoring_contract",
|
||||
params: { workspace_id: "draft-1", revision: 1 },
|
||||
},
|
||||
{
|
||||
operation: "workflow.draft_workspaces.create_empty",
|
||||
params: { workspace_id: "draft-1", name: "draft.workflow" },
|
||||
@@ -299,6 +303,14 @@ describe("POST /api/rpc", () => {
|
||||
target: "__end__",
|
||||
},
|
||||
},
|
||||
{
|
||||
operation: "workflow.draft_workspaces.set_contract",
|
||||
params: { workspace_id: "draft-1", revision: 1, outcomes: ["ok"] },
|
||||
},
|
||||
{
|
||||
operation: "workflow.draft_workspaces.set_start",
|
||||
params: { workspace_id: "draft-1", revision: 1, step_id: "echo" },
|
||||
},
|
||||
{
|
||||
operation: "workflow.draft_workspaces.set_step_input_bindings",
|
||||
params: {
|
||||
@@ -321,6 +333,14 @@ describe("POST /api/rpc", () => {
|
||||
operation: "workflow.draft_workspaces.validate",
|
||||
params: { workspace_id: "draft-1" },
|
||||
},
|
||||
{
|
||||
operation: "workflow.draft_workspaces.set_workflow_output_bindings",
|
||||
params: {
|
||||
workspace_id: "draft-1",
|
||||
revision: 1,
|
||||
bindings: [{ source: "result", target: "state.result" }],
|
||||
},
|
||||
},
|
||||
{ operation: "workflow.runs.start", params: {} },
|
||||
{ operation: "workflow.runs.resume", params: {} },
|
||||
] as const)("authorizes the allowlisted operation $operation", async ({
|
||||
@@ -467,6 +487,24 @@ describe("POST /api/rpc", () => {
|
||||
expect(body.error.code).toBe("unknown_operation");
|
||||
});
|
||||
|
||||
it.each(["workflow.draft_workspaces.patch", "workflow.draft_workspaces.replace_document"])(
|
||||
"does not authorize adjacent generic operation %s",
|
||||
async (operation) => {
|
||||
const res = await app.request("/api/rpc", {
|
||||
method: "POST",
|
||||
headers: validConsoleHeaders,
|
||||
body: JSON.stringify({
|
||||
operation,
|
||||
target: "http://127.0.0.1:8000/rpc",
|
||||
}),
|
||||
});
|
||||
|
||||
expect(res.status).toBe(400);
|
||||
const body = await res.json();
|
||||
expect(body.error.code).toBe("unknown_operation");
|
||||
},
|
||||
);
|
||||
|
||||
it("returns 400 for invalid JSON body", async () => {
|
||||
const res = await app.request("/api/rpc", {
|
||||
method: "POST",
|
||||
|
||||
@@ -15,14 +15,18 @@ describe("browser operation policy", () => {
|
||||
"workflow.capabilities.inspect",
|
||||
"workflow.draft_workspaces.list",
|
||||
"workflow.draft_workspaces.get",
|
||||
"workflow.draft_workspaces.inspect_authoring_contract",
|
||||
"workflow.draft_workspaces.create_empty",
|
||||
"workflow.draft_workspaces.create_from_capability",
|
||||
"workflow.draft_workspaces.add_step_from_capability",
|
||||
"workflow.draft_workspaces.update_capability_step",
|
||||
"workflow.draft_workspaces.set_route",
|
||||
"workflow.draft_workspaces.set_contract",
|
||||
"workflow.draft_workspaces.set_start",
|
||||
"workflow.draft_workspaces.set_step_input_bindings",
|
||||
"workflow.draft_workspaces.set_step_output_bindings",
|
||||
"workflow.draft_workspaces.validate",
|
||||
"workflow.draft_workspaces.set_workflow_output_bindings",
|
||||
"workflow.artifacts.list",
|
||||
"workflow.artifacts.inspect",
|
||||
"workflow.deployments.list",
|
||||
@@ -41,6 +45,9 @@ describe("browser operation policy", () => {
|
||||
expect(browserAllowedOperationNames).not.toContain(
|
||||
"workflow.draft_workspaces.replace_document",
|
||||
);
|
||||
expect(browserAllowedOperationNames).not.toContain(
|
||||
"workflow.draft_workspaces.patch",
|
||||
);
|
||||
expect(browserAllowedOperationNames).not.toContain(
|
||||
"workflow.draft_workspaces.remove_step",
|
||||
);
|
||||
|
||||
@@ -13,14 +13,18 @@ export const browserAllowedOperationNames = defineBrowserOperationNames([
|
||||
"workflow.capabilities.inspect",
|
||||
"workflow.draft_workspaces.list",
|
||||
"workflow.draft_workspaces.get",
|
||||
"workflow.draft_workspaces.inspect_authoring_contract",
|
||||
"workflow.draft_workspaces.create_empty",
|
||||
"workflow.draft_workspaces.create_from_capability",
|
||||
"workflow.draft_workspaces.add_step_from_capability",
|
||||
"workflow.draft_workspaces.update_capability_step",
|
||||
"workflow.draft_workspaces.set_route",
|
||||
"workflow.draft_workspaces.set_contract",
|
||||
"workflow.draft_workspaces.set_start",
|
||||
"workflow.draft_workspaces.set_step_input_bindings",
|
||||
"workflow.draft_workspaces.set_step_output_bindings",
|
||||
"workflow.draft_workspaces.validate",
|
||||
"workflow.draft_workspaces.set_workflow_output_bindings",
|
||||
"workflow.artifacts.list",
|
||||
"workflow.artifacts.inspect",
|
||||
"workflow.deployments.list",
|
||||
|
||||
@@ -155,11 +155,15 @@ const runtimeOperationNames = [
|
||||
"workflow.draft_workspaces.create_from_capability",
|
||||
"workflow.draft_workspaces.list",
|
||||
"workflow.draft_workspaces.get",
|
||||
"workflow.draft_workspaces.inspect_authoring_contract",
|
||||
"workflow.draft_workspaces.set_route",
|
||||
"workflow.draft_workspaces.set_contract",
|
||||
"workflow.draft_workspaces.set_start",
|
||||
"workflow.draft_workspaces.set_step_input_bindings",
|
||||
"workflow.draft_workspaces.set_step_output_bindings",
|
||||
"workflow.draft_workspaces.update_capability_step",
|
||||
"workflow.draft_workspaces.validate",
|
||||
"workflow.draft_workspaces.set_workflow_output_bindings",
|
||||
"workflow.artifacts.list",
|
||||
"workflow.artifacts.inspect",
|
||||
"workflow.deployments.list",
|
||||
@@ -320,6 +324,10 @@ describe("workflow contract generator", () => {
|
||||
});
|
||||
|
||||
it.each([
|
||||
"workflow.draft_workspaces.inspect_authoring_contract",
|
||||
"workflow.draft_workspaces.set_contract",
|
||||
"workflow.draft_workspaces.set_start",
|
||||
"workflow.draft_workspaces.set_workflow_output_bindings",
|
||||
"workflow.draft_workspaces.set_step_input_bindings",
|
||||
"workflow.draft_workspaces.set_step_output_bindings",
|
||||
])("rejects a manifest missing focused operation %s", async (method) => {
|
||||
@@ -352,6 +360,14 @@ describe("workflow contract generator", () => {
|
||||
expect(runtimeSource).toContain(
|
||||
'"workflow.draft_workspaces.set_step_output_bindings"',
|
||||
);
|
||||
expect(runtimeSource).toContain(
|
||||
'"workflow.draft_workspaces.inspect_authoring_contract"',
|
||||
);
|
||||
expect(runtimeSource).toContain('"workflow.draft_workspaces.set_contract"');
|
||||
expect(runtimeSource).toContain('"workflow.draft_workspaces.set_start"');
|
||||
expect(runtimeSource).toContain(
|
||||
'"workflow.draft_workspaces.set_workflow_output_bindings"',
|
||||
);
|
||||
expect(runtimeSource).toContain('"InputPathBinding"');
|
||||
expect(runtimeSource).toContain('"InputValueBinding"');
|
||||
expect(runtimeSource).toContain('"StepInputBinding"');
|
||||
@@ -420,6 +436,6 @@ describe("workflow contract generator", () => {
|
||||
|
||||
const generatedSource = await generateWorkflowContractSource(manifestText);
|
||||
expect(generatedSource).toBe(checkedSource);
|
||||
expect(generatedSource.match(/^ \| "workflow\./gm)).toHaveLength(70);
|
||||
expect(generatedSource.match(/^ \| "workflow\./gm)).toHaveLength(71);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -94,11 +94,15 @@ const runtimeOperationNameList = [
|
||||
"workflow.draft_workspaces.create_from_capability",
|
||||
"workflow.draft_workspaces.list",
|
||||
"workflow.draft_workspaces.get",
|
||||
"workflow.draft_workspaces.inspect_authoring_contract",
|
||||
"workflow.draft_workspaces.set_contract",
|
||||
"workflow.draft_workspaces.set_route",
|
||||
"workflow.draft_workspaces.set_start",
|
||||
"workflow.draft_workspaces.set_step_input_bindings",
|
||||
"workflow.draft_workspaces.set_step_output_bindings",
|
||||
"workflow.draft_workspaces.update_capability_step",
|
||||
"workflow.draft_workspaces.validate",
|
||||
"workflow.draft_workspaces.set_workflow_output_bindings",
|
||||
"workflow.artifacts.list",
|
||||
"workflow.artifacts.inspect",
|
||||
"workflow.deployments.list",
|
||||
|
||||
@@ -15,8 +15,8 @@ import {
|
||||
|
||||
describe("generated workflow contract", () => {
|
||||
it("contains every operation exactly once", () => {
|
||||
expect(workflowOperationNames).toHaveLength(70);
|
||||
expect(new Set(workflowOperationNames)).toHaveLength(70);
|
||||
expect(workflowOperationNames).toHaveLength(71);
|
||||
expect(new Set(workflowOperationNames)).toHaveLength(71);
|
||||
});
|
||||
|
||||
it("contains every authored Effect operation without broadening its boundary", () => {
|
||||
@@ -30,13 +30,17 @@ describe("generated workflow contract", () => {
|
||||
"workflow.capabilities.call",
|
||||
"workflow.draft_workspaces.list",
|
||||
"workflow.draft_workspaces.get",
|
||||
"workflow.draft_workspaces.inspect_authoring_contract",
|
||||
"workflow.draft_workspaces.create_empty",
|
||||
"workflow.draft_workspaces.create_from_capability",
|
||||
"workflow.draft_workspaces.add_step_from_capability",
|
||||
"workflow.draft_workspaces.update_capability_step",
|
||||
"workflow.draft_workspaces.set_route",
|
||||
"workflow.draft_workspaces.set_contract",
|
||||
"workflow.draft_workspaces.set_start",
|
||||
"workflow.draft_workspaces.set_step_input_bindings",
|
||||
"workflow.draft_workspaces.set_step_output_bindings",
|
||||
"workflow.draft_workspaces.set_workflow_output_bindings",
|
||||
"workflow.draft_workspaces.validate",
|
||||
"workflow.artifacts.list",
|
||||
"workflow.artifacts.inspect",
|
||||
|
||||
@@ -42,6 +42,7 @@ export type WorkflowOperationName =
|
||||
| "workflow.draft_workspaces.delete"
|
||||
| "workflow.draft_workspaces.get"
|
||||
| "workflow.draft_workspaces.handle"
|
||||
| "workflow.draft_workspaces.inspect_authoring_contract"
|
||||
| "workflow.draft_workspaces.list"
|
||||
| "workflow.draft_workspaces.patch"
|
||||
| "workflow.draft_workspaces.remove_binding"
|
||||
@@ -114,6 +115,7 @@ export const workflowOperationNames: readonly WorkflowOperationName[] = [
|
||||
"workflow.draft_workspaces.delete",
|
||||
"workflow.draft_workspaces.get",
|
||||
"workflow.draft_workspaces.handle",
|
||||
"workflow.draft_workspaces.inspect_authoring_contract",
|
||||
"workflow.draft_workspaces.list",
|
||||
"workflow.draft_workspaces.patch",
|
||||
"workflow.draft_workspaces.remove_binding",
|
||||
@@ -193,6 +195,22 @@ export type CompileDraftWorkspaceResult = CompileDraftWorkspaceSuccess | Invalid
|
||||
* via the `definition` "CreateArtifactFromWorkspaceResult".
|
||||
*/
|
||||
export type CreateArtifactFromWorkspaceResult = SavedDraftArtifactResult | UnsavedDraftArtifactResult;
|
||||
/**
|
||||
* This interface was referenced by `WorkflowContractMap`'s JSON-Schema
|
||||
* via the `definition` "AuthoringPathAvailability".
|
||||
*/
|
||||
export type AuthoringPathAvailability = "available" | "conditional";
|
||||
/**
|
||||
* This interface was referenced by `WorkflowContractMap`'s JSON-Schema
|
||||
* via the `definition` "AuthoringPathOrigin".
|
||||
*/
|
||||
export type AuthoringPathOrigin =
|
||||
"workflow_input" | "workflow_state" | "runtime_context" | "step_input" | "step_output" | "workflow_output";
|
||||
/**
|
||||
* This interface was referenced by `WorkflowContractMap`'s JSON-Schema
|
||||
* via the `definition` "AuthoringPathUse".
|
||||
*/
|
||||
export type AuthoringPathUse = "step_input" | "step_output_source" | "state_target" | "workflow_output";
|
||||
/**
|
||||
* This interface was referenced by `WorkflowContractMap`'s JSON-Schema
|
||||
* via the `definition` "PatchDraftResult".
|
||||
@@ -599,6 +617,14 @@ export interface WorkflowContractMap {
|
||||
};
|
||||
result: DraftWorkspaceResult;
|
||||
};
|
||||
"workflow.draft_workspaces.inspect_authoring_contract": {
|
||||
params: {
|
||||
workspace_id: string;
|
||||
revision: number;
|
||||
selected_step_id?: string | null;
|
||||
};
|
||||
result: AuthoringContractInventoryPayload | DraftWorkspaceResult;
|
||||
};
|
||||
"workflow.draft_workspaces.list": {
|
||||
params: Record<string, never>;
|
||||
result: ListDraftWorkspacesResult;
|
||||
@@ -2201,6 +2227,59 @@ export interface HandleDraftBranch {
|
||||
outcome: string;
|
||||
step_id: string;
|
||||
}
|
||||
/**
|
||||
* Revision-scoped readable sources and writable authoring targets.
|
||||
*
|
||||
* This interface was referenced by `WorkflowContractMap`'s JSON-Schema
|
||||
* via the `definition` "AuthoringContractInventoryPayload".
|
||||
*/
|
||||
export interface AuthoringContractInventoryPayload {
|
||||
entry_steps: AuthoringStepContractPayload[];
|
||||
readable_sources: AuthoringPathOptionPayload[];
|
||||
revision: number;
|
||||
selected_step_id: string | null;
|
||||
state_targets: AuthoringPathOptionPayload[];
|
||||
step_input_targets: AuthoringPathOptionPayload[];
|
||||
step_output_sources: AuthoringPathOptionPayload[];
|
||||
warnings: string[];
|
||||
workflow_outcomes: string[];
|
||||
workflow_output_targets: AuthoringPathOptionPayload[];
|
||||
workspace_id: string;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
/**
|
||||
* Compact executable-step choice used by authoring inventories.
|
||||
*
|
||||
* This interface was referenced by `WorkflowContractMap`'s JSON-Schema
|
||||
* via the `definition` "AuthoringStepContractPayload".
|
||||
*/
|
||||
export interface AuthoringStepContractPayload {
|
||||
description?: string;
|
||||
input_targets?: AuthoringPathOptionPayload[];
|
||||
label: string;
|
||||
outcomes?: string[];
|
||||
output_sources?: AuthoringPathOptionPayload[];
|
||||
step_id: string;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
/**
|
||||
* One schema-derived source or target available to an author.
|
||||
*
|
||||
* This interface was referenced by `WorkflowContractMap`'s JSON-Schema
|
||||
* via the `definition` "AuthoringPathOptionPayload".
|
||||
*/
|
||||
export interface AuthoringPathOptionPayload {
|
||||
availability: AuthoringPathAvailability;
|
||||
description?: string;
|
||||
label: string;
|
||||
origin: AuthoringPathOrigin;
|
||||
path: string;
|
||||
reason?: string;
|
||||
required: boolean;
|
||||
schema: JsonObject;
|
||||
uses: AuthoringPathUse[];
|
||||
[k: string]: unknown;
|
||||
}
|
||||
/**
|
||||
* All persisted draft-workspace summaries.
|
||||
*
|
||||
@@ -2772,6 +2851,198 @@ export const workflowRuntimeContract = {
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AuthoringContractInventoryPayload": {
|
||||
"description": "Revision-scoped readable sources and writable authoring targets.",
|
||||
"properties": {
|
||||
"entry_steps": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringStepContractPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"readable_sources": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"revision": {
|
||||
"type": "integer"
|
||||
},
|
||||
"selected_step_id": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"state_targets": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"step_input_targets": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"step_output_sources": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"warnings": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"workflow_outcomes": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"workflow_output_targets": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"workspace_id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"workspace_id",
|
||||
"revision",
|
||||
"selected_step_id",
|
||||
"readable_sources",
|
||||
"step_input_targets",
|
||||
"step_output_sources",
|
||||
"state_targets",
|
||||
"workflow_output_targets",
|
||||
"entry_steps",
|
||||
"workflow_outcomes",
|
||||
"warnings"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AuthoringPathAvailability": {
|
||||
"enum": [
|
||||
"available",
|
||||
"conditional"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AuthoringPathOptionPayload": {
|
||||
"description": "One schema-derived source or target available to an author.",
|
||||
"properties": {
|
||||
"availability": {
|
||||
"$ref": "#/components/schemas/AuthoringPathAvailability"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"origin": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOrigin"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string"
|
||||
},
|
||||
"required": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/JsonObject"
|
||||
},
|
||||
"uses": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathUse"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"label",
|
||||
"origin",
|
||||
"schema",
|
||||
"required",
|
||||
"availability",
|
||||
"uses"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AuthoringPathOrigin": {
|
||||
"enum": [
|
||||
"workflow_input",
|
||||
"workflow_state",
|
||||
"runtime_context",
|
||||
"step_input",
|
||||
"step_output",
|
||||
"workflow_output"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AuthoringPathUse": {
|
||||
"enum": [
|
||||
"step_input",
|
||||
"step_output_source",
|
||||
"state_target",
|
||||
"workflow_output"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AuthoringStepContractPayload": {
|
||||
"description": "Compact executable-step choice used by authoring inventories.",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"input_targets": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"outcomes": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"output_sources": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"step_id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"step_id",
|
||||
"label"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"CapabilityCallResult": {
|
||||
"description": "Outcome returned by a direct node-spec or wrapper capability call.",
|
||||
"properties": {
|
||||
@@ -5780,6 +6051,48 @@ export const workflowRuntimeContract = {
|
||||
"$ref": "#/components/schemas/DraftWorkspaceResult"
|
||||
}
|
||||
},
|
||||
"workflow.draft_workspaces.inspect_authoring_contract": {
|
||||
"payload": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"workspace_id": {
|
||||
"minLength": 1,
|
||||
"type": "string"
|
||||
},
|
||||
"revision": {
|
||||
"minimum": 1,
|
||||
"type": "integer"
|
||||
},
|
||||
"selected_step_id": {
|
||||
"anyOf": [
|
||||
{
|
||||
"minLength": 1,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"workspace_id",
|
||||
"revision"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"success": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/AuthoringContractInventoryPayload"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/DraftWorkspaceResult"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"workflow.draft_workspaces.list": {
|
||||
"payload": {
|
||||
"additionalProperties": false,
|
||||
@@ -5791,6 +6104,79 @@ export const workflowRuntimeContract = {
|
||||
"$ref": "#/components/schemas/ListDraftWorkspacesResult"
|
||||
}
|
||||
},
|
||||
"workflow.draft_workspaces.set_contract": {
|
||||
"payload": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"workspace_id": {
|
||||
"minLength": 1,
|
||||
"type": "string"
|
||||
},
|
||||
"revision": {
|
||||
"minimum": 1,
|
||||
"type": "integer"
|
||||
},
|
||||
"input_schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": true,
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"state_schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": true,
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"output_schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": true,
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"outcomes": {
|
||||
"anyOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"workspace_id",
|
||||
"revision"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"success": {
|
||||
"$ref": "#/components/schemas/DraftWorkspaceResult"
|
||||
}
|
||||
},
|
||||
"workflow.draft_workspaces.set_route": {
|
||||
"payload": {
|
||||
"additionalProperties": false,
|
||||
@@ -5829,6 +6215,34 @@ export const workflowRuntimeContract = {
|
||||
"$ref": "#/components/schemas/DraftWorkspaceResult"
|
||||
}
|
||||
},
|
||||
"workflow.draft_workspaces.set_start": {
|
||||
"payload": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"workspace_id": {
|
||||
"minLength": 1,
|
||||
"type": "string"
|
||||
},
|
||||
"revision": {
|
||||
"minimum": 1,
|
||||
"type": "integer"
|
||||
},
|
||||
"step_id": {
|
||||
"minLength": 1,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"workspace_id",
|
||||
"revision",
|
||||
"step_id"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"success": {
|
||||
"$ref": "#/components/schemas/DraftWorkspaceResult"
|
||||
}
|
||||
},
|
||||
"workflow.draft_workspaces.set_step_input_bindings": {
|
||||
"payload": {
|
||||
"additionalProperties": false,
|
||||
@@ -5899,6 +6313,44 @@ export const workflowRuntimeContract = {
|
||||
"$ref": "#/components/schemas/DraftWorkspaceResult"
|
||||
}
|
||||
},
|
||||
"workflow.draft_workspaces.set_workflow_output_bindings": {
|
||||
"payload": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"workspace_id": {
|
||||
"minLength": 1,
|
||||
"type": "string"
|
||||
},
|
||||
"revision": {
|
||||
"minimum": 1,
|
||||
"type": "integer"
|
||||
},
|
||||
"bindings": {
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/InputPathBinding"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/InputValueBinding"
|
||||
}
|
||||
],
|
||||
"description": "Simple canonical binding for node inputs or workflow outputs. Use either a path binding with `path`, or a literal binding with `value`; composite `expression` bindings are node-local only."
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"workspace_id",
|
||||
"revision",
|
||||
"bindings"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"success": {
|
||||
"$ref": "#/components/schemas/DraftWorkspaceResult"
|
||||
}
|
||||
},
|
||||
"workflow.draft_workspaces.update_capability_step": {
|
||||
"payload": {
|
||||
"additionalProperties": false,
|
||||
|
||||
@@ -29,13 +29,17 @@ export {
|
||||
WorkflowCapabilitiesCall,
|
||||
WorkflowDraftWorkspacesList,
|
||||
WorkflowDraftWorkspacesGet,
|
||||
WorkflowDraftWorkspacesInspectAuthoringContract,
|
||||
WorkflowDraftWorkspacesCreateEmpty,
|
||||
WorkflowDraftWorkspacesCreateFromCapability,
|
||||
WorkflowDraftWorkspacesAddStepFromCapability,
|
||||
WorkflowDraftWorkspacesUpdateCapabilityStep,
|
||||
WorkflowDraftWorkspacesSetRoute,
|
||||
WorkflowDraftWorkspacesSetContract,
|
||||
WorkflowDraftWorkspacesSetStart,
|
||||
WorkflowDraftWorkspacesSetStepInputBindings,
|
||||
WorkflowDraftWorkspacesSetStepOutputBindings,
|
||||
WorkflowDraftWorkspacesSetWorkflowOutputBindings,
|
||||
WorkflowDraftWorkspacesValidate,
|
||||
WorkflowArtifactsList,
|
||||
WorkflowArtifactsInspect,
|
||||
@@ -57,6 +61,8 @@ export {
|
||||
WorkflowDraftWorkspacesListResultSchema,
|
||||
WorkflowDraftWorkspacesGetPayloadSchema,
|
||||
WorkflowDraftWorkspacesGetResultSchema,
|
||||
WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
|
||||
WorkflowDraftWorkspacesInspectAuthoringContractResultSchema,
|
||||
WorkflowDraftWorkspacesCreateEmptyPayloadSchema,
|
||||
WorkflowDraftWorkspacesCreateEmptyResultSchema,
|
||||
WorkflowDraftWorkspacesCreateFromCapabilityPayloadSchema,
|
||||
@@ -67,10 +73,16 @@ export {
|
||||
WorkflowDraftWorkspacesUpdateCapabilityStepResultSchema,
|
||||
WorkflowDraftWorkspacesSetRoutePayloadSchema,
|
||||
WorkflowDraftWorkspacesSetRouteResultSchema,
|
||||
WorkflowDraftWorkspacesSetContractPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetContractResultSchema,
|
||||
WorkflowDraftWorkspacesSetStartPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetStartResultSchema,
|
||||
WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetStepInputBindingsResultSchema,
|
||||
WorkflowDraftWorkspacesSetStepOutputBindingsPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetStepOutputBindingsResultSchema,
|
||||
WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetWorkflowOutputBindingsResultSchema,
|
||||
WorkflowDraftWorkspacesValidatePayloadSchema,
|
||||
WorkflowDraftWorkspacesValidateResultSchema,
|
||||
WorkflowRpcs,
|
||||
|
||||
@@ -157,6 +157,55 @@ const DraftWorkspaceSchema = Schema.Struct({
|
||||
workspace_id: Schema.String,
|
||||
});
|
||||
|
||||
const AuthoringPathOptionSchema = Schema.Struct({
|
||||
path: Schema.String,
|
||||
label: Schema.String,
|
||||
origin: Schema.Literal(
|
||||
"workflow_input",
|
||||
"workflow_state",
|
||||
"runtime_context",
|
||||
"step_input",
|
||||
"step_output",
|
||||
"workflow_output",
|
||||
),
|
||||
schema: JsonObjectSchema,
|
||||
required: Schema.Boolean,
|
||||
availability: Schema.Literal("available", "conditional"),
|
||||
uses: Schema.Array(
|
||||
Schema.Literal(
|
||||
"step_input",
|
||||
"step_output_source",
|
||||
"state_target",
|
||||
"workflow_output",
|
||||
),
|
||||
),
|
||||
description: Schema.optional(Schema.String),
|
||||
reason: Schema.optional(Schema.String),
|
||||
});
|
||||
|
||||
const AuthoringStepContractSchema = Schema.Struct({
|
||||
step_id: Schema.String,
|
||||
label: Schema.String,
|
||||
description: Schema.optional(Schema.String),
|
||||
input_targets: Schema.optional(Schema.Array(AuthoringPathOptionSchema)),
|
||||
output_sources: Schema.optional(Schema.Array(AuthoringPathOptionSchema)),
|
||||
outcomes: Schema.optional(Schema.Array(Schema.String)),
|
||||
});
|
||||
|
||||
const AuthoringContractInventorySchema = Schema.Struct({
|
||||
workspace_id: Schema.String,
|
||||
revision: PositiveIntegerSchema,
|
||||
selected_step_id: Schema.NullOr(Schema.String),
|
||||
readable_sources: Schema.Array(AuthoringPathOptionSchema),
|
||||
step_input_targets: Schema.Array(AuthoringPathOptionSchema),
|
||||
step_output_sources: Schema.Array(AuthoringPathOptionSchema),
|
||||
state_targets: Schema.Array(AuthoringPathOptionSchema),
|
||||
workflow_output_targets: Schema.Array(AuthoringPathOptionSchema),
|
||||
entry_steps: Schema.Array(AuthoringStepContractSchema),
|
||||
workflow_outcomes: Schema.Array(Schema.String),
|
||||
warnings: Schema.Array(Schema.String),
|
||||
});
|
||||
|
||||
// Effect's empty Struct does not traverse excess keys; the impossible optional
|
||||
// field keeps the authored empty payload strict under onExcessProperty:error.
|
||||
const EmptyPayloadSchema = Schema.Struct({
|
||||
@@ -478,6 +527,14 @@ export const authoredRpcSchemas = {
|
||||
}),
|
||||
success: DraftWorkspaceSchema,
|
||||
},
|
||||
"workflow.draft_workspaces.inspect_authoring_contract": {
|
||||
payload: Schema.Struct({
|
||||
workspace_id: Schema.String.pipe(Schema.minLength(1)),
|
||||
revision: PositiveIntegerSchema,
|
||||
selected_step_id: Schema.optional(Schema.NullOr(Schema.String)),
|
||||
}),
|
||||
success: Schema.Union(AuthoringContractInventorySchema, DraftWorkspaceSchema),
|
||||
},
|
||||
"workflow.draft_workspaces.create_empty": {
|
||||
payload: Schema.Struct({
|
||||
workspace_id: Schema.String.pipe(Schema.minLength(1)),
|
||||
@@ -490,6 +547,25 @@ export const authoredRpcSchemas = {
|
||||
}),
|
||||
success: DraftWorkspaceSchema,
|
||||
},
|
||||
"workflow.draft_workspaces.set_contract": {
|
||||
payload: Schema.Struct({
|
||||
workspace_id: Schema.String.pipe(Schema.minLength(1)),
|
||||
revision: PositiveIntegerSchema,
|
||||
input_schema: Schema.optional(Schema.NullOr(JsonObjectSchema)),
|
||||
state_schema: Schema.optional(Schema.NullOr(JsonObjectSchema)),
|
||||
output_schema: Schema.optional(Schema.NullOr(JsonObjectSchema)),
|
||||
outcomes: Schema.optional(Schema.NullOr(Schema.Array(Schema.String))),
|
||||
}),
|
||||
success: DraftWorkspaceSchema,
|
||||
},
|
||||
"workflow.draft_workspaces.set_start": {
|
||||
payload: Schema.Struct({
|
||||
workspace_id: Schema.String.pipe(Schema.minLength(1)),
|
||||
revision: PositiveIntegerSchema,
|
||||
step_id: Schema.String.pipe(Schema.minLength(1)),
|
||||
}),
|
||||
success: DraftWorkspaceSchema,
|
||||
},
|
||||
"workflow.draft_workspaces.create_from_capability": {
|
||||
payload: Schema.Struct({
|
||||
workspace_id: Schema.String.pipe(Schema.minLength(1)),
|
||||
@@ -574,6 +650,14 @@ export const authoredRpcSchemas = {
|
||||
}),
|
||||
success: DraftWorkspaceSchema,
|
||||
},
|
||||
"workflow.draft_workspaces.set_workflow_output_bindings": {
|
||||
payload: Schema.Struct({
|
||||
workspace_id: Schema.String.pipe(Schema.minLength(1)),
|
||||
revision: PositiveIntegerSchema,
|
||||
bindings: Schema.Array(Schema.Union(InputPathBindingSchema, InputValueBindingSchema)),
|
||||
}),
|
||||
success: DraftWorkspaceSchema,
|
||||
},
|
||||
"workflow.draft_workspaces.validate": {
|
||||
payload: Schema.Struct({
|
||||
workspace_id: Schema.String.pipe(Schema.minLength(1)),
|
||||
|
||||
@@ -13,14 +13,22 @@ import {
|
||||
WorkflowDraftWorkspacesCreateFromCapabilityResultSchema,
|
||||
WorkflowDraftWorkspacesGetPayloadSchema,
|
||||
WorkflowDraftWorkspacesGetResultSchema,
|
||||
WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
|
||||
WorkflowDraftWorkspacesInspectAuthoringContractResultSchema,
|
||||
WorkflowDraftWorkspacesListPayloadSchema,
|
||||
WorkflowDraftWorkspacesListResultSchema,
|
||||
WorkflowDraftWorkspacesSetContractPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetContractResultSchema,
|
||||
WorkflowDraftWorkspacesSetRoutePayloadSchema,
|
||||
WorkflowDraftWorkspacesSetRouteResultSchema,
|
||||
WorkflowDraftWorkspacesSetStartPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetStartResultSchema,
|
||||
WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetStepInputBindingsResultSchema,
|
||||
WorkflowDraftWorkspacesSetStepOutputBindingsPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetStepOutputBindingsResultSchema,
|
||||
WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetWorkflowOutputBindingsResultSchema,
|
||||
WorkflowDraftWorkspacesUpdateCapabilityStepPayloadSchema,
|
||||
WorkflowDraftWorkspacesUpdateCapabilityStepResultSchema,
|
||||
WorkflowDraftWorkspacesValidatePayloadSchema,
|
||||
@@ -203,6 +211,66 @@ const draftWorkspace = {
|
||||
},
|
||||
};
|
||||
|
||||
const authoringPathOption = {
|
||||
path: "input.title",
|
||||
label: "Title",
|
||||
origin: "workflow_input",
|
||||
schema: { type: "string" },
|
||||
required: true,
|
||||
availability: "available",
|
||||
uses: ["step_input"],
|
||||
};
|
||||
|
||||
const authoringContractInventory = {
|
||||
workspace_id: "console.demo",
|
||||
revision: 7,
|
||||
selected_step_id: "render",
|
||||
readable_sources: [authoringPathOption],
|
||||
step_input_targets: [
|
||||
{
|
||||
...authoringPathOption,
|
||||
path: "local.title",
|
||||
origin: "step_input",
|
||||
uses: ["step_input"],
|
||||
},
|
||||
],
|
||||
step_output_sources: [
|
||||
{
|
||||
...authoringPathOption,
|
||||
path: "local.markdown",
|
||||
origin: "step_output",
|
||||
uses: ["step_output_source"],
|
||||
},
|
||||
],
|
||||
state_targets: [
|
||||
{
|
||||
...authoringPathOption,
|
||||
path: "state.report",
|
||||
origin: "workflow_state",
|
||||
uses: ["state_target", "workflow_output"],
|
||||
},
|
||||
],
|
||||
workflow_output_targets: [
|
||||
{
|
||||
...authoringPathOption,
|
||||
path: "output.report",
|
||||
origin: "workflow_output",
|
||||
uses: ["workflow_output"],
|
||||
},
|
||||
],
|
||||
entry_steps: [
|
||||
{
|
||||
step_id: "render",
|
||||
label: "Render report",
|
||||
input_targets: [],
|
||||
output_sources: [],
|
||||
outcomes: ["ok", "error"],
|
||||
},
|
||||
],
|
||||
workflow_outcomes: ["ok", "error"],
|
||||
warnings: [],
|
||||
};
|
||||
|
||||
const createFromCapabilityResult = {
|
||||
...draftWorkspace,
|
||||
next_actions: {
|
||||
@@ -460,6 +528,22 @@ const parityCases: ReadonlyArray<ParityCase> = [
|
||||
draft: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.inspect_authoring_contract",
|
||||
payload: WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
|
||||
success: WorkflowDraftWorkspacesInspectAuthoringContractResultSchema,
|
||||
validPayload: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 7,
|
||||
selected_step_id: "render",
|
||||
},
|
||||
invalidPayload: { workspace_id: "console.demo", revision: 0 },
|
||||
validSuccess: authoringContractInventory,
|
||||
invalidSuccess: {
|
||||
...authoringContractInventory,
|
||||
entry_steps: [{ step_id: "render" }],
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.create_empty",
|
||||
payload: WorkflowDraftWorkspacesCreateEmptyPayloadSchema,
|
||||
@@ -590,6 +674,41 @@ const parityCases: ReadonlyArray<ParityCase> = [
|
||||
summary: { ...draftWorkspace.summary, steps: [1] },
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.set_contract",
|
||||
payload: WorkflowDraftWorkspacesSetContractPayloadSchema,
|
||||
success: WorkflowDraftWorkspacesSetContractResultSchema,
|
||||
validPayload: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 7,
|
||||
input_schema: { type: "object" },
|
||||
state_schema: { type: "object" },
|
||||
output_schema: { type: "object" },
|
||||
outcomes: ["ok", "error"],
|
||||
},
|
||||
invalidPayload: { workspace_id: "console.demo", revision: 0 },
|
||||
validSuccess: draftWorkspace,
|
||||
invalidSuccess: {
|
||||
...draftWorkspace,
|
||||
summary: { ...draftWorkspace.summary, steps: [1] },
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.set_start",
|
||||
payload: WorkflowDraftWorkspacesSetStartPayloadSchema,
|
||||
success: WorkflowDraftWorkspacesSetStartResultSchema,
|
||||
validPayload: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 7,
|
||||
step_id: "render",
|
||||
},
|
||||
invalidPayload: { workspace_id: "console.demo", revision: 7, step_id: "" },
|
||||
validSuccess: draftWorkspace,
|
||||
invalidSuccess: {
|
||||
...draftWorkspace,
|
||||
summary: { ...draftWorkspace.summary, steps: [1] },
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.set_step_input_bindings",
|
||||
payload: WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema,
|
||||
@@ -640,6 +759,29 @@ const parityCases: ReadonlyArray<ParityCase> = [
|
||||
summary: { ...draftWorkspace.summary, steps: [1] },
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.set_workflow_output_bindings",
|
||||
payload: WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
|
||||
success: WorkflowDraftWorkspacesSetWorkflowOutputBindingsResultSchema,
|
||||
validPayload: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 7,
|
||||
bindings: [
|
||||
{ path: "state.report", target: "report" },
|
||||
{ target: "format", value: "markdown" },
|
||||
],
|
||||
},
|
||||
invalidPayload: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 7,
|
||||
bindings: [{ expression: { kind: "literal", value: "bad" } }],
|
||||
},
|
||||
validSuccess: draftWorkspace,
|
||||
invalidSuccess: {
|
||||
...draftWorkspace,
|
||||
summary: { ...draftWorkspace.summary, steps: [1] },
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.validate",
|
||||
payload: WorkflowDraftWorkspacesValidatePayloadSchema,
|
||||
@@ -1188,13 +1330,17 @@ describe("authored RPC and manifest schema parity", () => {
|
||||
"workflow.capabilities.call",
|
||||
"workflow.draft_workspaces.list",
|
||||
"workflow.draft_workspaces.get",
|
||||
"workflow.draft_workspaces.inspect_authoring_contract",
|
||||
"workflow.draft_workspaces.create_empty",
|
||||
"workflow.draft_workspaces.create_from_capability",
|
||||
"workflow.draft_workspaces.add_step_from_capability",
|
||||
"workflow.draft_workspaces.update_capability_step",
|
||||
"workflow.draft_workspaces.set_route",
|
||||
"workflow.draft_workspaces.set_contract",
|
||||
"workflow.draft_workspaces.set_start",
|
||||
"workflow.draft_workspaces.set_step_input_bindings",
|
||||
"workflow.draft_workspaces.set_step_output_bindings",
|
||||
"workflow.draft_workspaces.set_workflow_output_bindings",
|
||||
"workflow.draft_workspaces.validate",
|
||||
"workflow.artifacts.list",
|
||||
"workflow.artifacts.inspect",
|
||||
@@ -1231,6 +1377,7 @@ describe("authored RPC and manifest schema parity", () => {
|
||||
"workflow.draft_workspaces.update_capability_step:payload:oneOf@#/components/schemas/InputPathBinding.properties.path",
|
||||
"workflow.draft_workspaces.set_step_input_bindings:payload:oneOf@#/components/schemas/InputPathBinding.properties.path",
|
||||
"workflow.draft_workspaces.set_step_output_bindings:payload:oneOf@#/components/schemas/OutputBinding.properties.source",
|
||||
"workflow.draft_workspaces.set_workflow_output_bindings:payload:oneOf@#/components/schemas/InputPathBinding.properties.path",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,10 +27,14 @@ describe("runtimeSchemasFor", () => {
|
||||
"workflow.draft_workspaces.create_empty",
|
||||
"workflow.draft_workspaces.create_from_capability",
|
||||
"workflow.draft_workspaces.get",
|
||||
"workflow.draft_workspaces.inspect_authoring_contract",
|
||||
"workflow.draft_workspaces.list",
|
||||
"workflow.draft_workspaces.set_contract",
|
||||
"workflow.draft_workspaces.set_route",
|
||||
"workflow.draft_workspaces.set_start",
|
||||
"workflow.draft_workspaces.set_step_input_bindings",
|
||||
"workflow.draft_workspaces.set_step_output_bindings",
|
||||
"workflow.draft_workspaces.set_workflow_output_bindings",
|
||||
"workflow.draft_workspaces.update_capability_step",
|
||||
"workflow.draft_workspaces.validate",
|
||||
"workflow.health",
|
||||
|
||||
@@ -306,6 +306,52 @@ describe("run operation registry", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.set_contract" as const,
|
||||
params: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 5,
|
||||
outcomes: ["ok", "error"],
|
||||
},
|
||||
cli: "uv run wf draft set-contract console.demo --revision 5 --outcome ok --outcome error",
|
||||
result: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 6,
|
||||
title: "Console demo",
|
||||
status: "valid" as const,
|
||||
diagnostics: [],
|
||||
summary: {
|
||||
name: "console.demo",
|
||||
start: "echo",
|
||||
step_count: 1,
|
||||
route_count: 1,
|
||||
steps: ["echo"],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.set_start" as const,
|
||||
params: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 6,
|
||||
step_id: "echo",
|
||||
},
|
||||
cli: "uv run wf draft set-start console.demo --revision 6 --step echo",
|
||||
result: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 7,
|
||||
title: "Console demo",
|
||||
status: "valid" as const,
|
||||
diagnostics: [],
|
||||
summary: {
|
||||
name: "console.demo",
|
||||
start: "echo",
|
||||
step_count: 1,
|
||||
route_count: 1,
|
||||
steps: ["echo"],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.set_step_input_bindings" as const,
|
||||
params: {
|
||||
@@ -367,6 +413,32 @@ describe("run operation registry", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.set_workflow_output_bindings" as const,
|
||||
params: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 7,
|
||||
bindings: [
|
||||
{ path: "state.report", target: "report" },
|
||||
{ target: "format", value: "markdown" },
|
||||
],
|
||||
},
|
||||
cli: "uv run wf draft set-workflow-output console.demo --revision 7 --map state.report=report --value 'format=\"markdown\"'",
|
||||
result: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 8,
|
||||
title: "Console demo",
|
||||
status: "valid" as const,
|
||||
diagnostics: [],
|
||||
summary: {
|
||||
name: "console.demo",
|
||||
start: "echo",
|
||||
step_count: 1,
|
||||
route_count: 1,
|
||||
steps: ["echo"],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.validate" as const,
|
||||
params: { workspace_id: "console.demo" },
|
||||
@@ -522,6 +594,44 @@ describe("run operation registry", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("registers authoring inspection as a read operation", async () => {
|
||||
const { getOperationMeta } = await import("./method-registry.js");
|
||||
const operation = getOperationMeta(
|
||||
"workflow.draft_workspaces.inspect_authoring_contract",
|
||||
);
|
||||
if (operation === undefined) throw new Error("missing authoring inspection");
|
||||
|
||||
expect(operation.idempotency).toBe("read");
|
||||
expect(
|
||||
operation.equivalentCli({
|
||||
workspace_id: "console.demo",
|
||||
revision: 8,
|
||||
selected_step_id: "render",
|
||||
}),
|
||||
).toBe(
|
||||
"uv run wf draft inspect console.demo --include-draft [non-equivalent: unavailable CLI representation for revision, selected_step_id]",
|
||||
);
|
||||
expect(
|
||||
operation.interpret({
|
||||
workspace_id: "console.demo",
|
||||
revision: 8,
|
||||
selected_step_id: null,
|
||||
readable_sources: [],
|
||||
step_input_targets: [],
|
||||
step_output_sources: [],
|
||||
state_targets: [],
|
||||
workflow_output_targets: [],
|
||||
entry_steps: [],
|
||||
workflow_outcomes: ["ok"],
|
||||
warnings: [],
|
||||
}),
|
||||
).toMatchObject({
|
||||
workspaceId: "console.demo",
|
||||
selectedStepId: null,
|
||||
workflowOutcomes: ["ok"],
|
||||
});
|
||||
});
|
||||
|
||||
it("does not flatten composite bindings into a fake inline CLI value", async () => {
|
||||
const { getOperationMeta } = await import("./method-registry.js");
|
||||
const operation = getOperationMeta(
|
||||
|
||||
@@ -2,6 +2,8 @@ import { Schema } from "effect";
|
||||
import type {
|
||||
NodeSpecCapabilitySummary,
|
||||
StepInputBinding,
|
||||
AuthoringContractInventoryPayload,
|
||||
AuthoringPathOptionPayload,
|
||||
WorkflowOperationName,
|
||||
WrapperArtifactCapabilitySummary,
|
||||
} from "./generated/workflow-contract.js";
|
||||
@@ -18,6 +20,8 @@ import {
|
||||
WorkflowDraftWorkspacesListResultSchema,
|
||||
WorkflowDraftWorkspacesGetPayloadSchema,
|
||||
WorkflowDraftWorkspacesGetResultSchema,
|
||||
WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
|
||||
WorkflowDraftWorkspacesInspectAuthoringContractResultSchema,
|
||||
WorkflowDraftWorkspacesCreateEmptyPayloadSchema,
|
||||
WorkflowDraftWorkspacesCreateEmptyResultSchema,
|
||||
WorkflowDraftWorkspacesCreateFromCapabilityPayloadSchema,
|
||||
@@ -28,10 +32,16 @@ import {
|
||||
WorkflowDraftWorkspacesUpdateCapabilityStepResultSchema,
|
||||
WorkflowDraftWorkspacesSetRoutePayloadSchema,
|
||||
WorkflowDraftWorkspacesSetRouteResultSchema,
|
||||
WorkflowDraftWorkspacesSetContractPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetContractResultSchema,
|
||||
WorkflowDraftWorkspacesSetStartPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetStartResultSchema,
|
||||
WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetStepInputBindingsResultSchema,
|
||||
WorkflowDraftWorkspacesSetStepOutputBindingsPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetStepOutputBindingsResultSchema,
|
||||
WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetWorkflowOutputBindingsResultSchema,
|
||||
WorkflowDraftWorkspacesValidatePayloadSchema,
|
||||
WorkflowDraftWorkspacesValidateResultSchema,
|
||||
WorkflowArtifactsListPayloadSchema,
|
||||
@@ -141,6 +151,27 @@ export type DraftWorkspaceInterpreted = {
|
||||
readonly draft: Readonly<Record<string, unknown>> | null;
|
||||
};
|
||||
|
||||
export type AuthoringContractInterpreted = {
|
||||
readonly workspaceId: string;
|
||||
readonly revision: number;
|
||||
readonly selectedStepId: string | null;
|
||||
readonly readableSources: ReadonlyArray<ReturnType<typeof interpretAuthoringPathOption>>;
|
||||
readonly stepInputTargets: ReadonlyArray<ReturnType<typeof interpretAuthoringPathOption>>;
|
||||
readonly stepOutputSources: ReadonlyArray<ReturnType<typeof interpretAuthoringPathOption>>;
|
||||
readonly stateTargets: ReadonlyArray<ReturnType<typeof interpretAuthoringPathOption>>;
|
||||
readonly workflowOutputTargets: ReadonlyArray<ReturnType<typeof interpretAuthoringPathOption>>;
|
||||
readonly entrySteps: ReadonlyArray<{
|
||||
readonly stepId: string;
|
||||
readonly label: string;
|
||||
readonly description?: string;
|
||||
readonly inputTargets?: ReadonlyArray<ReturnType<typeof interpretAuthoringPathOption>>;
|
||||
readonly outputSources?: ReadonlyArray<ReturnType<typeof interpretAuthoringPathOption>>;
|
||||
readonly outcomes?: ReadonlyArray<string>;
|
||||
}>;
|
||||
readonly workflowOutcomes: ReadonlyArray<string>;
|
||||
readonly warnings: ReadonlyArray<string>;
|
||||
};
|
||||
|
||||
const interpretNextActions = (nextActions: {
|
||||
readonly can_continue: boolean;
|
||||
readonly can_save_now: boolean | null;
|
||||
@@ -301,6 +332,49 @@ const interpretDraftWorkspace = (decoded: {
|
||||
draft: decoded.draft ?? null,
|
||||
});
|
||||
|
||||
const interpretAuthoringPathOption = (option: AuthoringPathOptionPayload) => ({
|
||||
path: option.path,
|
||||
label: option.label,
|
||||
origin: option.origin,
|
||||
schema: option.schema,
|
||||
required: option.required,
|
||||
availability: option.availability,
|
||||
uses: option.uses,
|
||||
...(option.description === undefined
|
||||
? {}
|
||||
: { description: option.description }),
|
||||
...(option.reason === undefined ? {} : { reason: option.reason }),
|
||||
});
|
||||
|
||||
const interpretAuthoringContract = (
|
||||
decoded: AuthoringContractInventoryPayload,
|
||||
): AuthoringContractInterpreted => ({
|
||||
workspaceId: decoded.workspace_id,
|
||||
revision: decoded.revision,
|
||||
selectedStepId: decoded.selected_step_id,
|
||||
readableSources: decoded.readable_sources.map(interpretAuthoringPathOption),
|
||||
stepInputTargets: decoded.step_input_targets.map(interpretAuthoringPathOption),
|
||||
stepOutputSources: decoded.step_output_sources.map(interpretAuthoringPathOption),
|
||||
stateTargets: decoded.state_targets.map(interpretAuthoringPathOption),
|
||||
workflowOutputTargets: decoded.workflow_output_targets.map(
|
||||
interpretAuthoringPathOption,
|
||||
),
|
||||
entrySteps: decoded.entry_steps.map((step) => ({
|
||||
stepId: step.step_id,
|
||||
label: step.label,
|
||||
...(step.description === undefined ? {} : { description: step.description }),
|
||||
...(step.input_targets === undefined
|
||||
? {}
|
||||
: { inputTargets: step.input_targets.map(interpretAuthoringPathOption) }),
|
||||
...(step.output_sources === undefined
|
||||
? {}
|
||||
: { outputSources: step.output_sources.map(interpretAuthoringPathOption) }),
|
||||
...(step.outcomes === undefined ? {} : { outcomes: step.outcomes }),
|
||||
})),
|
||||
workflowOutcomes: decoded.workflow_outcomes,
|
||||
warnings: decoded.warnings,
|
||||
});
|
||||
|
||||
/** Adapts a snake_case run detail from the server into camelCase for the browser. */
|
||||
const interpretRunDetail = (decoded: {
|
||||
readonly run_id: string | null;
|
||||
@@ -533,6 +607,33 @@ const operationEntries = defineOperationEntries([
|
||||
return interpretDraftWorkspace(decoded);
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.inspect_authoring_contract",
|
||||
label: "Inspect draft authoring contract",
|
||||
explanation: "Inspect schema-derived sources and targets for a draft workspace",
|
||||
idempotency: "read",
|
||||
equivalentCli: (params) => {
|
||||
const p = Schema.decodeUnknownSync(
|
||||
WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
|
||||
)(params, { onExcessProperty: "error" });
|
||||
return nonEquivalentCli(
|
||||
`uv run wf draft inspect ${shellArg(p.workspace_id)} --include-draft`,
|
||||
[
|
||||
"revision",
|
||||
...(p.selected_step_id == null ? [] : ["selected_step_id"]),
|
||||
],
|
||||
);
|
||||
},
|
||||
interpret: (result) => {
|
||||
const decoded = Schema.decodeUnknownSync(
|
||||
WorkflowDraftWorkspacesInspectAuthoringContractResultSchema,
|
||||
)(result);
|
||||
if (isRecord(decoded) && "readable_sources" in decoded) {
|
||||
return interpretAuthoringContract(decoded as AuthoringContractInventoryPayload);
|
||||
}
|
||||
return interpretDraftWorkspace(decoded);
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.create_empty",
|
||||
label: "Create empty draft workspace",
|
||||
@@ -722,6 +823,55 @@ const operationEntries = defineOperationEntries([
|
||||
return interpretDraftWorkspace(decoded);
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.set_contract",
|
||||
label: "Set draft contract",
|
||||
explanation: "Replace selected workflow input, state, output, or outcome contract fields",
|
||||
idempotency: "write",
|
||||
equivalentCli: (params) => {
|
||||
const p = Schema.decodeUnknownSync(
|
||||
WorkflowDraftWorkspacesSetContractPayloadSchema,
|
||||
)(params, { onExcessProperty: "error" });
|
||||
const parts = [
|
||||
"uv run wf draft set-contract",
|
||||
shellArg(p.workspace_id),
|
||||
"--revision",
|
||||
String(p.revision),
|
||||
];
|
||||
const unavailable: string[] = [];
|
||||
if (p.input_schema != null) unavailable.push("input_schema (use --input-schema-file)");
|
||||
if (p.state_schema != null) unavailable.push("state_schema (use --state-schema-file)");
|
||||
if (p.output_schema != null) unavailable.push("output_schema (use --output-schema-file)");
|
||||
for (const outcome of p.outcomes ?? []) {
|
||||
parts.push("--outcome", shellArg(outcome));
|
||||
}
|
||||
return nonEquivalentCli(parts.join(" "), unavailable);
|
||||
},
|
||||
interpret: (result) => {
|
||||
const decoded = Schema.decodeUnknownSync(
|
||||
WorkflowDraftWorkspacesSetContractResultSchema,
|
||||
)(result);
|
||||
return interpretDraftWorkspace(decoded);
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.set_start",
|
||||
label: "Set draft start",
|
||||
explanation: "Set the entry step for a persisted workflow draft",
|
||||
idempotency: "write",
|
||||
equivalentCli: (params) => {
|
||||
const p = Schema.decodeUnknownSync(
|
||||
WorkflowDraftWorkspacesSetStartPayloadSchema,
|
||||
)(params, { onExcessProperty: "error" });
|
||||
return `uv run wf draft set-start ${shellArg(p.workspace_id)} --revision ${p.revision} --step ${shellArg(p.step_id)}`;
|
||||
},
|
||||
interpret: (result) => {
|
||||
const decoded = Schema.decodeUnknownSync(
|
||||
WorkflowDraftWorkspacesSetStartResultSchema,
|
||||
)(result);
|
||||
return interpretDraftWorkspace(decoded);
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.set_step_input_bindings",
|
||||
label: "Set step input bindings",
|
||||
@@ -788,6 +938,36 @@ const operationEntries = defineOperationEntries([
|
||||
return interpretDraftWorkspace(decoded);
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.set_workflow_output_bindings",
|
||||
label: "Set workflow output bindings",
|
||||
explanation: "Replace the ordered public workflow output bindings",
|
||||
idempotency: "write",
|
||||
equivalentCli: (params) => {
|
||||
const p = Schema.decodeUnknownSync(
|
||||
WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
|
||||
)(params, { onExcessProperty: "error" });
|
||||
const parts = [
|
||||
"uv run wf draft set-workflow-output",
|
||||
shellArg(p.workspace_id),
|
||||
"--revision",
|
||||
String(p.revision),
|
||||
];
|
||||
if (p.bindings.length === 0) {
|
||||
parts.push("--clear");
|
||||
return parts.join(" ");
|
||||
}
|
||||
const rendered = inputBindingCliArgs(p.bindings, "--map");
|
||||
parts.push(...rendered.args);
|
||||
return nonEquivalentCli(parts.join(" "), rendered.unavailable);
|
||||
},
|
||||
interpret: (result) => {
|
||||
const decoded = Schema.decodeUnknownSync(
|
||||
WorkflowDraftWorkspacesSetWorkflowOutputBindingsResultSchema,
|
||||
)(result);
|
||||
return interpretDraftWorkspace(decoded);
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "workflow.draft_workspaces.validate",
|
||||
label: "Validate draft workspace",
|
||||
|
||||
@@ -107,6 +107,23 @@ export const WorkflowDraftWorkspacesGet = Rpc.make(
|
||||
},
|
||||
);
|
||||
|
||||
const draftWorkspacesInspectAuthoringContractSchemas = runtimeSchemasFor(
|
||||
"workflow.draft_workspaces.inspect_authoring_contract",
|
||||
);
|
||||
export const WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema =
|
||||
draftWorkspacesInspectAuthoringContractSchemas.payload;
|
||||
export const WorkflowDraftWorkspacesInspectAuthoringContractResultSchema =
|
||||
draftWorkspacesInspectAuthoringContractSchemas.success;
|
||||
|
||||
export const WorkflowDraftWorkspacesInspectAuthoringContract = Rpc.make(
|
||||
"workflow.draft_workspaces.inspect_authoring_contract",
|
||||
{
|
||||
payload: WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
|
||||
success: WorkflowDraftWorkspacesInspectAuthoringContractResultSchema,
|
||||
error: Schema.Never,
|
||||
},
|
||||
);
|
||||
|
||||
// Artifacts
|
||||
const artifactListSchemas = runtimeSchemasFor("workflow.artifacts.list");
|
||||
export const WorkflowArtifactsListPayloadSchema = artifactListSchemas.payload;
|
||||
@@ -203,6 +220,40 @@ export const WorkflowDraftWorkspacesSetRoute = Rpc.make(
|
||||
},
|
||||
);
|
||||
|
||||
const draftWorkspacesSetContractSchemas = runtimeSchemasFor(
|
||||
"workflow.draft_workspaces.set_contract",
|
||||
);
|
||||
export const WorkflowDraftWorkspacesSetContractPayloadSchema =
|
||||
draftWorkspacesSetContractSchemas.payload;
|
||||
export const WorkflowDraftWorkspacesSetContractResultSchema =
|
||||
draftWorkspacesSetContractSchemas.success;
|
||||
|
||||
export const WorkflowDraftWorkspacesSetContract = Rpc.make(
|
||||
"workflow.draft_workspaces.set_contract",
|
||||
{
|
||||
payload: WorkflowDraftWorkspacesSetContractPayloadSchema,
|
||||
success: WorkflowDraftWorkspacesSetContractResultSchema,
|
||||
error: Schema.Never,
|
||||
},
|
||||
);
|
||||
|
||||
const draftWorkspacesSetStartSchemas = runtimeSchemasFor(
|
||||
"workflow.draft_workspaces.set_start",
|
||||
);
|
||||
export const WorkflowDraftWorkspacesSetStartPayloadSchema =
|
||||
draftWorkspacesSetStartSchemas.payload;
|
||||
export const WorkflowDraftWorkspacesSetStartResultSchema =
|
||||
draftWorkspacesSetStartSchemas.success;
|
||||
|
||||
export const WorkflowDraftWorkspacesSetStart = Rpc.make(
|
||||
"workflow.draft_workspaces.set_start",
|
||||
{
|
||||
payload: WorkflowDraftWorkspacesSetStartPayloadSchema,
|
||||
success: WorkflowDraftWorkspacesSetStartResultSchema,
|
||||
error: Schema.Never,
|
||||
},
|
||||
);
|
||||
|
||||
const setStepInputBindingsSchemas = runtimeSchemasFor(
|
||||
"workflow.draft_workspaces.set_step_input_bindings",
|
||||
);
|
||||
@@ -237,6 +288,23 @@ export const WorkflowDraftWorkspacesSetStepOutputBindings = Rpc.make(
|
||||
},
|
||||
);
|
||||
|
||||
const draftWorkspacesSetWorkflowOutputBindingsSchemas = runtimeSchemasFor(
|
||||
"workflow.draft_workspaces.set_workflow_output_bindings",
|
||||
);
|
||||
export const WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema =
|
||||
draftWorkspacesSetWorkflowOutputBindingsSchemas.payload;
|
||||
export const WorkflowDraftWorkspacesSetWorkflowOutputBindingsResultSchema =
|
||||
draftWorkspacesSetWorkflowOutputBindingsSchemas.success;
|
||||
|
||||
export const WorkflowDraftWorkspacesSetWorkflowOutputBindings = Rpc.make(
|
||||
"workflow.draft_workspaces.set_workflow_output_bindings",
|
||||
{
|
||||
payload: WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
|
||||
success: WorkflowDraftWorkspacesSetWorkflowOutputBindingsResultSchema,
|
||||
error: Schema.Never,
|
||||
},
|
||||
);
|
||||
|
||||
const draftWorkspacesValidateSchemas = runtimeSchemasFor(
|
||||
"workflow.draft_workspaces.validate",
|
||||
);
|
||||
@@ -365,13 +433,17 @@ export const WorkflowRpcs = RpcGroup.make(
|
||||
WorkflowCapabilitiesCall,
|
||||
WorkflowDraftWorkspacesList,
|
||||
WorkflowDraftWorkspacesGet,
|
||||
WorkflowDraftWorkspacesInspectAuthoringContract,
|
||||
WorkflowDraftWorkspacesCreateEmpty,
|
||||
WorkflowDraftWorkspacesCreateFromCapability,
|
||||
WorkflowDraftWorkspacesAddStepFromCapability,
|
||||
WorkflowDraftWorkspacesUpdateCapabilityStep,
|
||||
WorkflowDraftWorkspacesSetRoute,
|
||||
WorkflowDraftWorkspacesSetContract,
|
||||
WorkflowDraftWorkspacesSetStart,
|
||||
WorkflowDraftWorkspacesSetStepInputBindings,
|
||||
WorkflowDraftWorkspacesSetStepOutputBindings,
|
||||
WorkflowDraftWorkspacesSetWorkflowOutputBindings,
|
||||
WorkflowDraftWorkspacesValidate,
|
||||
WorkflowArtifactsList,
|
||||
WorkflowArtifactsInspect,
|
||||
|
||||
@@ -219,6 +219,15 @@ const lifecycleCases = [
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
operation: "workflow.draft_workspaces.inspect_authoring_contract" as const,
|
||||
params: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 1,
|
||||
selected_step_id: "echo",
|
||||
},
|
||||
result: draftWorkspaceResult,
|
||||
},
|
||||
{
|
||||
operation: "workflow.draft_workspaces.create_empty" as const,
|
||||
params: {
|
||||
@@ -278,6 +287,24 @@ const lifecycleCases = [
|
||||
},
|
||||
result: draftWorkspaceResult,
|
||||
},
|
||||
{
|
||||
operation: "workflow.draft_workspaces.set_contract" as const,
|
||||
params: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 2,
|
||||
outcomes: ["ok", "error"],
|
||||
},
|
||||
result: draftWorkspaceResult,
|
||||
},
|
||||
{
|
||||
operation: "workflow.draft_workspaces.set_start" as const,
|
||||
params: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 3,
|
||||
step_id: "echo",
|
||||
},
|
||||
result: draftWorkspaceResult,
|
||||
},
|
||||
{
|
||||
operation: "workflow.draft_workspaces.set_step_input_bindings" as const,
|
||||
params: {
|
||||
@@ -306,6 +333,18 @@ const lifecycleCases = [
|
||||
params: { workspace_id: "console.demo" },
|
||||
result: draftWorkspaceResult,
|
||||
},
|
||||
{
|
||||
operation: "workflow.draft_workspaces.set_workflow_output_bindings" as const,
|
||||
params: {
|
||||
workspace_id: "console.demo",
|
||||
revision: 4,
|
||||
bindings: [
|
||||
{ path: "state.report", target: "report" },
|
||||
{ target: "format", value: "markdown" },
|
||||
],
|
||||
},
|
||||
result: draftWorkspaceResult,
|
||||
},
|
||||
{
|
||||
operation: "workflow.artifacts.list" as const,
|
||||
params: { limit: 50 },
|
||||
|
||||
@@ -36,13 +36,17 @@ import {
|
||||
WorkflowCapabilitiesCallPayloadSchema,
|
||||
WorkflowDraftWorkspacesListPayloadSchema,
|
||||
WorkflowDraftWorkspacesGetPayloadSchema,
|
||||
WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
|
||||
WorkflowDraftWorkspacesCreateEmptyPayloadSchema,
|
||||
WorkflowDraftWorkspacesCreateFromCapabilityPayloadSchema,
|
||||
WorkflowDraftWorkspacesAddStepFromCapabilityPayloadSchema,
|
||||
WorkflowDraftWorkspacesUpdateCapabilityStepPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetRoutePayloadSchema,
|
||||
WorkflowDraftWorkspacesSetContractPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetStartPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetStepOutputBindingsPayloadSchema,
|
||||
WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
|
||||
WorkflowDraftWorkspacesValidatePayloadSchema,
|
||||
WorkflowArtifactsListPayloadSchema,
|
||||
WorkflowArtifactsInspectPayloadSchema,
|
||||
@@ -324,6 +328,15 @@ const executeImpl =
|
||||
);
|
||||
return yield* client.workflow["draft_workspaces.get"](payload);
|
||||
}
|
||||
case "workflow.draft_workspaces.inspect_authoring_contract": {
|
||||
const payload = yield* decodeParams(
|
||||
WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
|
||||
params,
|
||||
);
|
||||
return yield* client.workflow[
|
||||
"draft_workspaces.inspect_authoring_contract"
|
||||
](payload);
|
||||
}
|
||||
case "workflow.draft_workspaces.create_empty": {
|
||||
const payload = yield* decodeParams(
|
||||
WorkflowDraftWorkspacesCreateEmptyPayloadSchema,
|
||||
@@ -365,6 +378,20 @@ const executeImpl =
|
||||
);
|
||||
return yield* client.workflow["draft_workspaces.set_route"](payload);
|
||||
}
|
||||
case "workflow.draft_workspaces.set_contract": {
|
||||
const payload = yield* decodeParams(
|
||||
WorkflowDraftWorkspacesSetContractPayloadSchema,
|
||||
params,
|
||||
);
|
||||
return yield* client.workflow["draft_workspaces.set_contract"](payload);
|
||||
}
|
||||
case "workflow.draft_workspaces.set_start": {
|
||||
const payload = yield* decodeParams(
|
||||
WorkflowDraftWorkspacesSetStartPayloadSchema,
|
||||
params,
|
||||
);
|
||||
return yield* client.workflow["draft_workspaces.set_start"](payload);
|
||||
}
|
||||
case "workflow.draft_workspaces.set_step_input_bindings": {
|
||||
const payload = yield* decodeParams(
|
||||
WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema,
|
||||
@@ -383,6 +410,15 @@ const executeImpl =
|
||||
"draft_workspaces.set_step_output_bindings"
|
||||
](payload);
|
||||
}
|
||||
case "workflow.draft_workspaces.set_workflow_output_bindings": {
|
||||
const payload = yield* decodeParams(
|
||||
WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
|
||||
params,
|
||||
);
|
||||
return yield* client.workflow[
|
||||
"draft_workspaces.set_workflow_output_bindings"
|
||||
](payload);
|
||||
}
|
||||
case "workflow.draft_workspaces.validate": {
|
||||
const payload = yield* decodeParams(
|
||||
WorkflowDraftWorkspacesValidatePayloadSchema,
|
||||
|
||||
Reference in New Issue
Block a user