docs: make workflow skills cli-first

This commit is contained in:
lda
2026-06-24 00:30:04 +07:00 Verified
parent 05dff5bc25
commit 69c39da10d
8 changed files with 68 additions and 52 deletions
+1 -1
View File
@@ -48,7 +48,7 @@ def compose_trial_prompt(
profile: InstructionProfile, profile: InstructionProfile,
wf_command_prefix: str, wf_command_prefix: str,
server_context: str, server_context: str,
workspace_path: Path, workspace_path: Path | str,
) -> RenderedPrompt: ) -> RenderedPrompt:
base_text = _BASE_PROMPT.read_text(encoding="utf-8") base_text = _BASE_PROMPT.read_text(encoding="utf-8")
profile_text = _load_profile_fragment(profile) profile_text = _load_profile_fragment(profile)
+2 -3
View File
@@ -427,8 +427,7 @@ def run_v2_trial(
server_context = ( server_context = (
"No external workflow RPC server is staged. Use the " "No external workflow RPC server is staged. Use the "
"per-trial workspace config copied to " "per-trial workspace config copied to "
f"`{config_path_display}`. Your writable trial workspace is " f"`{config_path_display}`."
f"`{workspace_path}`."
) )
rendered = compose_trial_prompt( rendered = compose_trial_prompt(
@@ -436,7 +435,7 @@ def run_v2_trial(
profile=profile, profile=profile,
wf_command_prefix=wf_command_prefix, wf_command_prefix=wf_command_prefix,
server_context=server_context, server_context=server_context,
workspace_path=workspace.root, workspace_path=workspace_path,
) )
workspace.rendered_prompt_path.write_text(rendered.text, encoding="utf-8") workspace.rendered_prompt_path.write_text(rendered.text, encoding="utf-8")
+16 -21
View File
@@ -5,11 +5,8 @@ description: Use when an agent needs to discover workflow capabilities, create o
# wf Workflow # wf Workflow
Use this skill for the workflow lifecycle, regardless of front door: Use this skill for the workflow lifecycle when the available front door is the
repo-local `wf` CLI.
- MCP tools exposed by `wf.workflow.*`
- repo-local `wf` CLI commands
- future `wf_api` callers
Prefer small discovery calls, draft workspaces, validation, and bounded trace Prefer small discovery calls, draft workspaces, validation, and bounded trace
reads. Do not write raw workflow plans unless the user explicitly asks for the reads. Do not write raw workflow plans unless the user explicitly asks for the
@@ -17,21 +14,19 @@ low-level escape hatch or you already have a complete compiler/generated plan.
## Workflow Lifecycle ## Workflow Lifecycle
1. Discover sources with `wf.admin.list_sources` or `wf cap list`. 1. Discover available capabilities with `wf cap list`.
2. Discover workflow-ready capabilities with `wf.workflow.list_capabilities`. 2. Inspect one candidate with `wf cap inspect`.
3. Inspect one candidate with `wf.workflow.inspect_capability`. 3. Call one candidate with `wf cap call` when payload shape or upstream source
4. Call one candidate with `wf.workflow.call_capability` or `wf cap call` when reachability is uncertain.
payload shape or upstream source reachability is uncertain. 4. Create a patchable draft workspace with `wf draft create-from-capability`.
5. Create a patchable draft workspace with 5. Patch targeted fields with focused draft commands or JSON Patch.
`wf.workflow.create_draft_workspace_from_capability`. 6. Validate with `wf draft validate`.
6. Patch targeted fields with focused helpers or JSON Patch. 7. Save an artifact with `wf draft save`, or import a complete raw plan with
7. Validate with `wf.workflow.validate_draft_workspace`. `wf artifact create-from-plan`.
8. Save with `wf.workflow.create_artifact_from_workspace` or 8. Save a deployment with `wf deploy save` or `wf deploy create`.
`wf.workflow.create_wrapper_from_workspace`. 9. Validate with `wf deploy validate`.
9. Save a deployment with `wf.workflow.save_deployment`. 10. Run with `wf run start`.
10. Validate with `wf.workflow.validate_deployment`. 11. Inspect stopped runs with `wf run inspect`; read bounded trace
11. Run with `wf.workflow.run_deployment`.
12. Inspect stopped runs with `wf.workflow.inspect_run`; read bounded trace
slices only when debugging. slices only when debugging.
## Rules ## Rules
@@ -44,7 +39,7 @@ low-level escape hatch or you already have a complete compiler/generated plan.
- Prefer focused draft edit commands before hand-writing JSON Patch. - Prefer focused draft edit commands before hand-writing JSON Patch.
- If a complete raw JSON/YAML plan already exists, the CLI escape hatch is - If a complete raw JSON/YAML plan already exists, the CLI escape hatch is
`wf artifact create-from-plan`; do not write helper scripts that call `wf artifact create-from-plan`; do not write helper scripts that call
`WorkflowApi.create_artifact_from_plan` directly. internal APIs directly.
- Use `artifact create-from-plan` only for complete raw plans; do not pass draft - Use `artifact create-from-plan` only for complete raw plans; do not pass draft
JSON to it. JSON to it.
- Use explicit source bindings at deployment time. - Use explicit source bindings at deployment time.
@@ -14,10 +14,10 @@ capabilities are graph-facing contracts with schemas and outcomes.
## Discovery Order ## Discovery Order
1. Use `wf.admin.list_sources` to understand owners. 1. Use `wf source list` or `wf status` when source ownership is unclear.
2. Use `wf.workflow.list_capabilities` for graph-ready capabilities. 2. Use `wf cap list --format ids` for graph-ready capabilities.
3. Use `wf.workflow.inspect_capability` for one full contract. 3. Use `wf cap inspect <capability>` for one full contract.
4. Use `wf.workflow.call_capability` to test a single workflow-facing contract. 4. Use `wf cap call <capability>` to test a single workflow-facing contract.
## Wrapper Artifacts ## Wrapper Artifacts
@@ -42,13 +42,13 @@ The plan file is the low-level workflow model. It is not a draft workspace.
```json ```json
{ {
"name": "report_case_study", "name": "example_workflow",
"input_schema": { "input_schema": {
"type": "object", "type": "object",
"properties": { "properties": {
"path": { "type": "string" } "text": { "type": "string" }
}, },
"required": ["path"] "required": ["text"]
}, },
"state_schema": { "state_schema": {
"type": "object", "type": "object",
@@ -70,11 +70,11 @@ The plan file is the low-level workflow model. It is not a draft workspace.
{ {
"id": "read", "id": "read",
"type": "node", "type": "node",
"node": "local.report.read_notes", "node": "example.source.read",
"input": [ "input": [
{ {
"path": { "root": "input", "parts": ["path"] }, "path": { "root": "input", "parts": ["text"] },
"target": { "root": "local", "parts": ["path"] } "target": { "root": "local", "parts": ["text"] }
} }
], ],
"output": [ "output": [
@@ -87,7 +87,7 @@ The plan file is the low-level workflow model. It is not a draft workspace.
{ {
"id": "extract", "id": "extract",
"type": "node", "type": "node",
"node": "local.report.extract_report", "node": "example.source.extract",
"input": [ "input": [
{ {
"path": { "root": "state", "parts": ["notes"] }, "path": { "root": "state", "parts": ["notes"] },
@@ -6,9 +6,8 @@ tool calls.
## Core Objects ## Core Objects
- **Source**: an owner of callable capabilities, such as `wf.std`, - **Source**: an owner of callable capabilities, such as `wf.std`, a configured
`local.report`, `local.browser_click`, or an MCP connection. Sources may be Python source, an MCP connection, or a future provider type.
built in, configured Python sources, MCP sources, or future provider types.
- **Capability**: a graph-facing callable contract exposed by a source. It has - **Capability**: a graph-facing callable contract exposed by a source. It has
input/output schemas and outcomes. Build workflows from workflow input/output schemas and outcomes. Build workflows from workflow
capabilities, not raw provider internals. capabilities, not raw provider internals.
@@ -30,8 +29,8 @@ live source satisfies each requirement.
Example: Example:
```text ```text
artifact requires: local.browser_click artifact requires: logical.source
deployment binds: local.browser_click -> local.browser_click deployment binds: logical.source -> concrete.source
``` ```
Platform sources such as `wf.std` are special: they can be omitted or self-bound. Platform sources such as `wf.std` are special: they can be omitted or self-bound.
@@ -6,24 +6,20 @@ validated, runnable deployment.
## Primary Path ## Primary Path
1. List sources. 1. List sources.
- MCP: `wf.admin.list_sources`
- CLI: `wf cap list --format ids` - CLI: `wf cap list --format ids`
2. List workflow capabilities. 2. List workflow capabilities.
- MCP: `wf.workflow.list_capabilities`
- CLI: `wf cap list` - CLI: `wf cap list`
3. Inspect one capability. 3. Inspect one capability.
- MCP: `wf.workflow.inspect_capability`
- CLI: `wf cap inspect <name>` - CLI: `wf cap inspect <name>`
4. Bootstrap a draft workspace. 4. Bootstrap a draft workspace.
- MCP: `wf.workflow.create_draft_workspace_from_capability`
- CLI: `wf draft create-from-capability <workspace_id> <capability>` - CLI: `wf draft create-from-capability <workspace_id> <capability>`
5. Inspect/patch/validate the workspace until valid. 5. Inspect/patch/validate the workspace until valid.
- Use focused CLI commands (`set-name`, `set-route`, `set-input`, `set-output`) - Use focused CLI commands (`set-name`, `set-route`, `set-input`, `set-output`)
for common edits. for common edits.
- Use JSON Patch only for general structural edits. - Use JSON Patch only for general structural edits.
6. Save an artifact. 6. Save an artifact.
- Full workflow: `create_artifact_from_workspace` - Draft artifact: `wf draft save`
- Reusable wrapper: `create_wrapper_from_workspace` - Complete raw plan: `wf artifact create-from-plan`
7. Save and validate a deployment. 7. Save and validate a deployment.
- `wf deploy save` (or `wf deploy create` alias) - `wf deploy save` (or `wf deploy create` alias)
8. Run the deployment. 8. Run the deployment.
@@ -67,12 +63,11 @@ wf run start <deployment_id> --input-file input.json
## Result Handling ## Result Handling
`run_deployment` returns compact status by default. Capture `run_id` even for `wf run start` returns compact status by default. Capture `run_id` even for
completed or failed runs. Use: completed or failed runs. Use:
- `inspect_run` for compact stored result. - `wf run inspect <run_id>` for compact stored result.
- `read_run_trace` for explicit debug slices, for example - `wf run trace <run_id> --from 0 --limit 25` for explicit debug slices.
`{"start": 0, "limit": 25}`. - `wf run resume <run_id>` only for interrupted runs.
- `resume_run` only for interrupted runs.
Do not ask for unbounded traces. Do not ask for unbounded traces.
@@ -61,6 +61,34 @@ def test_workflow_cli_bundle_uses_public_surfaces_not_implementation_files() ->
assert "no schema subcommands" not in contents assert "no schema subcommands" not in contents
def test_workflow_cli_bundle_uses_cli_names_not_mcp_method_names() -> None:
contents = "\n".join(
(ROOT / entry["source"]).read_text(encoding="utf-8") for entry in _entries()
)
assert "wf.workflow." not in contents
assert "wf.admin." not in contents
assert "WorkflowApi." not in contents
def test_workflow_cli_bundle_avoids_challenge_specific_names() -> None:
contents = "\n".join(
(ROOT / entry["source"]).read_text(encoding="utf-8") for entry in _entries()
)
forbidden = [
"browser_click",
"report_workflow",
"report_case_study",
"local.report",
"read_notes",
"extract_report",
"render_markdown_report",
]
for term in forbidden:
assert term not in contents
def test_bundle_destinations_form_two_skills() -> None: def test_bundle_destinations_form_two_skills() -> None:
destinations = {entry["destination"] for entry in _entries()} destinations = {entry["destination"] for entry in _entries()}