diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 00000000..3941dd25 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,255 @@ +# Plan — Unify "workflow" vs "pipeline" nomenclature (task 4664) + +## Goal & decision + +The same concept is called a **workflow** in the README, docs, and TUI, but a +**pipeline** in the CLI command (`ty pipeline`), the MCP tool +(`taskyou_create_pipeline`), the `internal/pipeline` package, and assorted +help/flag text. Settle on **`workflow`** as the single user-facing term and make +the user-facing surface consistent — **while keeping `pipeline` working as a +backward-compatible alias** so existing scripts and muscle memory don't break. + +This is a **naming/wording-only** change. **No behavior changes.** + +--- + +## Scope + +### In scope (user-facing surface → say "workflow") + +1. **CLI command** `cmd/task/main.go` — rename the `pipeline` command to + `workflow`, register `pipeline` as a cobra alias, and reword its Short/Long + help, examples, and flag descriptions. +2. **MCP tool** `internal/mcp/server.go` — advertise `taskyou_create_workflow`, + keep `taskyou_create_pipeline` as an (unadvertised) working alias in the call + dispatch, and reword the description + a couple of user-facing strings. +3. **Docs** — `README.md`, `docs/mcp-tools-reference.md`, `skills/taskyou/SKILL.md` + — switch example command names to `ty workflow …` and the MCP tool name to + `taskyou_create_workflow`, noting the `pipeline` alias still works. + +### Explicitly NOT changed — these are **data/behavior**, not wording + +Changing any of these would alter runtime behavior or break existing tasks/branches, +which the task forbids: + +- **The `"pipeline"` task tag** that marks a task as belonging to a workflow — + `internal/pipeline/pipeline.go:275` (`Tags: "pipeline"`) and the matcher + `hasPipelineTag` in `internal/pipeline/group.go:37-45`. Existing workflow tasks + in the DB are tagged `pipeline`; renaming the tag would orphan them from board + grouping. +- **The `pipeline/` git branch prefix** — `internal/pipeline/pipeline.go:285` + (`fmt.Sprintf("pipeline/%d-%s", …)`). This is the shared-branch namespace every + step checks out (this very task runs on `pipeline/4664-…`). Leave it. +- **The `"pipeline"` fallback branch slug** — `internal/pipeline/pipeline.go:434`. +- **The `internal/pipeline` Go package name and all exported identifiers** + (`pipeline.Create`, `Options`, `Definitions`, `DefaultDefinition`, `Group`, + `GroupWorkflows`, `WorkflowsDir`, etc.) and TUI internal identifiers + (`FieldPipeline`, `m.pipeline`, `pipelineOptions()`, `pendingPipeline`). Internal + renames are **optional and lower priority** per the task; skipping them keeps the + diff focused and low-risk. (See Follow-ups.) +- **The `ty-email` extension** (`extensions/ty-email/**`) — its "pipeline" wording + refers to the unrelated email-processing pipeline concept. Out of scope. +- Internal code comments that happen to say "pipeline" (e.g. + `internal/executor/executor.go:5718`). Not user-facing; leave unless trivially + adjacent to an edit. + +### Already correct (no change needed) + +- TUI new-task form selector already renders the label **"Workflow"** + (`internal/ui/form.go:2074`) with a "runs as a workflow…" hint (line 2077). +- Board/notification strings already say "workflow" (`internal/ui/app.go:1180`, + `internal/ui/kanban.go`). +- CLI success/notification strings already say "workflow" + (`cmd/task/main.go:950`, `1051`). +- `docs/mcp-tools-reference.md` body prose already says "workflow"; only the tool + **name** and the JSON example need updating. + +--- + +## Exact changes, staged + +### Stage 1 — CLI command (`cmd/task/main.go`, ~lines 814–1128) + +Primary edit target: the `pipelineCmd` definition. + +- **Line 815–816**: change `Use: "pipeline [goal]"` → `Use: "workflow [goal]"` + and add `Aliases: []string{"pipeline"}` to the `cobra.Command` literal. +- **Line 817** `Short`: "Create a multi-model plan → code → review **pipeline** + for a goal" → "…**workflow** for a goal". +- **Long (818–840)**: replace the remaining "pipeline" wording and switch the + example verb from `task pipeline …` to `ty workflow …`. Add one line noting the + alias, e.g. `(the 'pipeline' command name still works as an alias)`. Keep the + step/DAG explanation as-is. +- **Line 864** (the `--list` footer): `task pipeline new ""` → + `ty workflow new ""`. +- **Line 972** flag help: `"Pipeline definition to use"` → `"Workflow definition to use"`. +- Comment on **814** (`// Pipeline subcommand …`) → "Workflow subcommand …" (cheap alignment). +- **`pipelineNewCmd` (984–1070)**: reword `Long`/examples (`task pipeline new` → + `ty workflow new`; line 1064 run-hint `task pipeline ""` → `ty workflow ""`). +- **`pipelineEditCmd` (1073–1126)**: reword `Long`/examples (`task pipeline edit` + → `ty workflow edit`; line 1122 run-hint likewise). + +Leave the Go variable names (`pipelineCmd`, `pipelineNewCmd`, `pipelineEditCmd`) +as-is — they're internal. Do **not** rename flags (`--definition`/`-d`, `--list`, +`--no-execute`, `--body`, `--project`, `--json`, `--permission-mode`, +`--dangerous`): renaming flags would break scripts and isn't required. + +**Why an alias, not a rename:** cobra resolves `Aliases` during command traversal, +so `ty pipeline`, `ty pipeline --list`, `ty pipeline new …`, and `ty pipeline edit …` +all continue to resolve to the renamed command and its subcommands unchanged. + +### Stage 2 — MCP tool (`internal/mcp/server.go`) + +- **Line 261**: tool `Name: "taskyou_create_pipeline"` → `"taskyou_create_workflow"`. +- **Line 262**: reword the `Description` to lead with "workflow" and reference + `ty workflow new` instead of `ty pipeline new`. +- **Line 276**: param `definition` description `"Pipeline definition name …"` → + `"Workflow definition name …"`. +- **Line 580 (dispatch switch)**: change + `case "taskyou_create_pipeline":` → `case "taskyou_create_workflow", "taskyou_create_pipeline":` + so old callers keep working (backward-compatible, unadvertised alias — mirrors + the CLI alias). +- **Line 606**: error string `"Failed to create pipeline: %v"` → `"Failed to create workflow: %v"`. + +### Stage 3 — Docs + +- **`README.md`** (lines ~116–150): `ty pipeline …` → `ty workflow …` throughout + the "Running a workflow" / "Custom workflows" blocks. Add a short note after the + first example: `# 'ty pipeline' still works as an alias`. +- **`docs/mcp-tools-reference.md`** (heading line 131 + JSON example ~line 144): + `taskyou_create_pipeline` → `taskyou_create_workflow`; optionally note the old + name is accepted for compatibility. +- **`skills/taskyou/SKILL.md`** (lines 65–66, 252): `ty pipeline …` → `ty workflow …` + and `taskyou_create_pipeline` → `taskyou_create_workflow` (mention alias). + +--- + +## Ordered steps + +1. Stage 1 — edit `cmd/task/main.go` (command rename + alias + help wording). +2. `make build` and smoke-test the CLI help + alias (see Verification). +3. Stage 2 — edit `internal/mcp/server.go` (tool name + dispatch alias + strings). +4. Stage 3 — edit the three docs files. +5. `gofmt`/`goimports` (`.golangci.yml` uses goimports w/ local-prefix + `github.com/bborn/workflow`) and run `golangci-lint run` — **Lint must stay green**. + Watch the gofmt smart-quote landmine: don't put adjacent quotes in doc comments. +6. `go build ./...` and targeted tests: `go test ./internal/mcp/... ./internal/pipeline/... ./cmd/...` + (run in small batches — `go test ./...` all-at-once can OOM/exit 137 locally). +7. Manual verification (below), then commit and push the shared branch. + +--- + +## Edge cases + +- **Cobra alias + subcommands:** verify `ty pipeline new` and `ty pipeline edit` + still resolve (they do — alias is matched before subcommand lookup). Include in + the smoke test. +- **Shell completion:** completion is generated for the canonical name `workflow`; + `ty pipeline …` still executes but may not tab-complete. Acceptable — note it, + don't chase it. +- **MCP old-name callers:** any agent/script still sending `taskyou_create_pipeline` + must keep working → guaranteed by the dual `case`. The old name is intentionally + *not* re-advertised in `tools/list` to avoid a confusing duplicate. +- **Don't touch the `pipeline` tag / `pipeline/` branch prefix / fallback slug** — + re-read the "NOT changed" list before editing `internal/pipeline/*`. +- **Behavior invariance:** the `workflow` command must produce byte-identical + behavior to the old `pipeline` command — same branch name, same tags, same task + rows. Only strings change. + +--- + +## Manual verification (prove it works by hand) + +Build first: + +```bash +make build # produces ./ty (and ./taskd) +``` + +### CLI — new name is primary, old name still works + +```bash +./ty workflow --help # EXPECT: Usage "ty workflow [goal]"; an "Aliases: + # workflow, pipeline" line; help text says "workflow", + # examples read "ty workflow …"; no stray "pipeline" + # except the alias note. +./ty pipeline --help # EXPECT: identical help (alias resolves to same command). +./ty workflow --list # EXPECT: lists definitions (e.g. plan-code-review …). +./ty pipeline --list # EXPECT: same list — alias works. +./ty workflow new "spike three approaches, build the best, then test" --print + # EXPECT: prints generated YAML (needs anthropic_api_key + # set; otherwise an auth error is fine — proves routing). +./ty pipeline new "…" --print # EXPECT: same behavior via alias. +./ty workflow edit --print # EXPECT: prints the plan-code-review YAML. +./ty pipeline edit --print # EXPECT: same via alias. +``` + +Confirm **no other** top-level command regressed: + +```bash +./ty --help | grep -A1 -i workflow # EXPECT: "workflow" listed among commands. +``` + +### CLI — behavior unchanged (branch/tag invariance) + +In a throwaway git-worktree project registered with `ty`: + +```bash +./ty workflow "tiny no-op goal" --project --no-execute --json | jq . +# EXPECT: JSON with "branch":"pipeline/-tiny-no-op-goal" (prefix UNCHANGED), +# one step per definition step, statuses present. Then confirm the created +# tasks are tagged "pipeline" and the board folds them into a single ⇄ card: +./ty # open TUI; EXPECT the workflow shows as one "⇄ … · N/M" lead card. +``` + +The `pipeline/` branch prefix and `pipeline` tag appearing here is **correct and +intended** — that's the data layer we deliberately did not rename. + +### MCP — new tool advertised, old name still dispatches + +Drive the internal MCP server over stdio (JSON-RPC). Use a real task ID from your +DB (`./ty list` / TUI) for `--task-id`: + +```bash +# tools/list should advertise the new name and NOT the old one: +printf '%s\n' \ + '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \ + '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \ + | ./ty mcp-server --task-id 2>/dev/null | grep -o 'taskyou_create_[a-z]*' +# EXPECT: "taskyou_create_workflow" present; "taskyou_create_pipeline" absent +# from the advertised list. +``` + +Backward-compat dispatch (old name still handled) is guaranteed by the +`case "taskyou_create_workflow", "taskyou_create_pipeline":` line; confirm with +`go test ./internal/mcp/...` (green) and, optionally, a `tools/call` using the old +name against a git-worktree project returns "Created … workflow on branch …" +rather than "method not found". + +### Docs + +```bash +grep -rn "ty pipeline\|taskyou_create_pipeline" README.md docs/mcp-tools-reference.md skills/taskyou/SKILL.md +# EXPECT: only intentional "alias still works" mentions remain; primary examples +# now read "ty workflow" / "taskyou_create_workflow". +``` + +### Gate + +```bash +golangci-lint run # EXPECT: clean (Lint must stay green) +go build ./... # EXPECT: builds +go test ./internal/mcp/... ./internal/pipeline/... ./cmd/... # EXPECT: pass +``` + +--- + +## Follow-ups (optional, out of scope for this task) + +- Rename the `internal/pipeline` package → `internal/workflow` and its exported + identifiers, plus TUI internals (`FieldPipeline`, `pipelineOptions`, + `pendingPipeline`). Purely internal; larger churn; deliberately deferred to keep + this diff focused and behavior-safe. +- Optionally migrate the task tag `pipeline` → `workflow` **with a + read-both-write-new compatibility shim + data migration** — a behavior change, + so it needs its own task, not this one. diff --git a/README.md b/README.md index 5c433c27..5938bacb 100644 --- a/README.md +++ b/README.md @@ -113,9 +113,10 @@ Steps advance with no human in the loop; a workflow only pauses when a step genu ```bash # CLI -ty pipeline "Add rate limiting to the API" --project myapp -ty pipeline --list # show available workflows -ty pipeline "..." --no-execute # stage without starting +ty workflow "Add rate limiting to the API" --project myapp +# 'ty pipeline' still works as an alias +ty workflow --list # show available workflows +ty workflow "..." --no-execute # stage without starting # TUI: in the new-task form (n), pick a workflow in the "Workflow" selector. ``` @@ -141,13 +142,13 @@ Two steps with the same `deps` run in parallel; a step depending on several join ```bash # Author a workflow from a plain-English description (LLM → YAML you can edit) -ty pipeline new "spike three approaches, pick the best, build it, review and test in parallel" +ty workflow new "spike three approaches, pick the best, build it, review and test in parallel" # Eject the built-in to a YAML file to tweak its models / prompts / steps -ty pipeline edit # writes ~/.config/task/workflows/plan-code-review.yaml +ty workflow edit # writes ~/.config/task/workflows/plan-code-review.yaml ``` -Custom workflows appear in `ty pipeline --list`, the `--definition` flag, and the TUI new-task selector automatically. Configuration lives entirely in these files — edit them by hand any time. +Custom workflows appear in `ty workflow --list`, the `--definition` flag, and the TUI new-task selector automatically. Configuration lives entirely in these files — edit them by hand any time. ## Project Context diff --git a/REVIEW.md b/REVIEW.md new file mode 100644 index 00000000..81de9994 --- /dev/null +++ b/REVIEW.md @@ -0,0 +1,58 @@ +# Review — Unify "workflow" vs "pipeline" nomenclature (task 4664) + +**Verdict:** The user-facing rename is done well and matches PLAN.md closely. The +CLI command is `ty workflow` with a working `pipeline` alias (verified at runtime: +`ty pipeline`, `ty pipeline new`, `ty pipeline edit` all resolve). Docs, MCP tool +name + dispatch alias, and help text are all consistent. `go build ./...` passes, +`gofmt` is clean, and `internal/pipeline` + `cmd` tests pass. + +There is **one blocking issue**: a test was not updated to match the renamed MCP +tool, so `go test ./internal/mcp/...` fails — which the PLAN.md gate requires to be +green. + +--- + +## Blocking + +1. **`internal/mcp/server_test.go:104` — `TestToolsList` fails.** + The `want` map still asserts that `taskyou_create_pipeline` is advertised in + `tools/list`. The tool was renamed to `taskyou_create_workflow` and the old + name is intentionally **not** re-advertised (PLAN.md Stage 2 / verification: + "tools/list should advertise the new name and NOT the old one"). The test now + fails: + ``` + --- FAIL: TestToolsList (0.01s) + server_test.go:130: expected tool "taskyou_create_pipeline" in tools/list + ``` + **Fix:** change the map key on line 104 from `"taskyou_create_pipeline"` to + `"taskyou_create_workflow"`. (Optionally add a separate assertion that a + `tools/call` with the old `taskyou_create_pipeline` name still dispatches, to + lock in the backward-compat alias — nice-to-have, not required.) + +--- + +## Nits (optional) + +2. **`internal/mcp/server.go:262` — MCP tool description still says "phase + tasks" / "The first phase is queued immediately".** + Not a "pipeline" leak, but it's inconsistent with the "step" vocabulary used + everywhere else in this change (README, CLI help, and the docs reference all + say *steps*). Purely cosmetic and arguably out of scope for this task; flag it + only if the Verify step wants a fully consistent pass. Leave otherwise. + +--- + +## Confirmed correct (no action) + +- **CLI alias + subcommands** resolve via cobra as claimed — `ty pipeline`, + `ty pipeline new`, `ty pipeline edit` all produce the renamed command's help. +- **Data/behavior left untouched** as required: the `"pipeline"` task tag, the + `pipeline/` branch prefix, the fallback slug, and the `internal/pipeline` Go + package/identifiers are all unchanged. +- **Backward-compat MCP dispatch** — `case "taskyou_create_workflow", + "taskyou_create_pipeline":` keeps old callers working while advertising only + the new name. +- **All remaining "pipeline" strings in user-facing files are intentional alias + notes** (README.md:117, docs/mcp-tools-reference.md:135, skills/taskyou/SKILL.md:65,254). +- `docs/`, `README.md`, and code-comment wording (`definition_file.go`, + `generate.go`) updated to `ty workflow`. diff --git a/VERIFY.md b/VERIFY.md new file mode 100644 index 00000000..e417d795 --- /dev/null +++ b/VERIFY.md @@ -0,0 +1,19 @@ +# Verify — workflow/pipeline nomenclature rename + +## What was verified +The user-facing rename of "pipeline" → "workflow" (CLI command + `taskyou_create_workflow` +MCP tool, help text, docs), with the `pipeline` CLI alias kept for back-compat. + +## Review finding addressed +REVIEW.md flagged one **blocking** issue: `internal/mcp/server_test.go` still asserted the +old MCP tool name `taskyou_create_pipeline` in `TestToolsList`, so `go test ./internal/mcp/...` +failed. Fixed by updating the assertion to `taskyou_create_workflow` (the tool's new name; +the old name is intentionally not re-advertised). + +## Evidence (run by hand, not just trusting CI) +- `go build ./...` → clean. +- `go test ./...` → all packages PASS (previously `internal/mcp` failed on TestToolsList). +- `ty workflow --list` and `ty pipeline --list` (alias) both resolve — back-compat intact. + +## Verdict +Change does what the goal asked; suite is green. Ready for human review/merge. diff --git a/cmd/task/main.go b/cmd/task/main.go index 2d4d5dfd..33b3eeec 100644 --- a/cmd/task/main.go +++ b/cmd/task/main.go @@ -811,14 +811,15 @@ Examples: }) rootCmd.AddCommand(createCmd) - // Pipeline subcommand - create a multi-phase pipeline task + // Workflow subcommand - create a multi-phase workflow task pipelineCmd := &cobra.Command{ - Use: "pipeline [goal]", - Short: "Create a multi-model plan → code → review pipeline for a goal", + Use: "workflow [goal]", + Aliases: []string{"pipeline"}, + Short: "Create a multi-model plan → code → review workflow for a goal", Long: `Create a workflow: one goal broken into a small DAG of step tasks, each routed to its own executor and model, that hand work forward on a single shared branch and advance automatically — sequential where steps depend on each other, parallel -where they don't. +where they don't. (the 'pipeline' command name still works as an alias) The default 'plan-code-review' workflow runs five steps on one branch: Plan (Claude / Opus) — writes PLAN.md, no code @@ -828,16 +829,16 @@ The default 'plan-code-review' workflow runs five steps on one branch: Collect (Claude / Sonnet) — merges reviews, applies fixes, opens the PR Workflows are defined in YAML files you can edit; define your own (add a QA step, -a different shape) with 'task pipeline new ""' or 'task pipeline edit'. +a different shape) with 'ty workflow new ""' or 'ty workflow edit'. Each step commits and pushes the shared branch, so the workflow needs a project that uses git worktrees and has a remote to push to. Examples: - task pipeline "Add rate limiting to the API" --project myapp - task pipeline "Refactor the auth module" -p myapp --definition my-workflow - task pipeline new "plan, build, security review + QA in parallel, then finalize" - task pipeline --list # show available workflows`, + ty workflow "Add rate limiting to the API" --project myapp + ty workflow "Refactor the auth module" -p myapp --definition my-workflow + ty workflow new "plan, build, security review + QA in parallel, then finalize" + ty workflow --list # show available workflows`, Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { listDefs, _ := cmd.Flags().GetBool("list") @@ -861,7 +862,7 @@ Examples: } fmt.Printf("%s %s\n %s\n steps: %s\n", successStyle.Render(d.Name), dimStyle.Render("("+origin+")"), d.Description, strings.Join(stepLabels, " · ")) } - fmt.Println(dimStyle.Render("Custom workflows: " + pipeline.WorkflowsDir() + "/*.yaml · create with: task pipeline new \"\"")) + fmt.Println(dimStyle.Render("Custom workflows: " + pipeline.WorkflowsDir() + "/*.yaml · create with: ty workflow new \"\"")) return } @@ -969,7 +970,7 @@ Examples: } pipelineCmd.Flags().String("body", "", "Goal text (alternative to the positional argument)") pipelineCmd.Flags().StringP("project", "p", "", "Project name (auto-detected from cwd if not specified)") - pipelineCmd.Flags().StringP("definition", "d", pipeline.DefaultDefinition, "Pipeline definition to use") + pipelineCmd.Flags().StringP("definition", "d", pipeline.DefaultDefinition, "Workflow definition to use") pipelineCmd.Flags().String("permission-mode", "", "Permission mode for every phase: default, accept-edits, auto, dangerous (defaults to the project's setting)") pipelineCmd.Flags().Bool("dangerous", false, "Run every phase in dangerous mode (alias for --permission-mode dangerous)") pipelineCmd.Flags().Bool("no-execute", false, "Stage the workflow without queuing the root step") @@ -980,7 +981,7 @@ Examples: return pipeline.DefinitionNames(), cobra.ShellCompDirectiveNoFileComp }) - // Pipeline new subcommand - author a custom workflow from a free-text description + // Workflow new subcommand - author a custom workflow from a free-text description pipelineNewCmd := &cobra.Command{ Use: "new [description]", Short: "Create a custom workflow from a free-text description (LLM → YAML)", @@ -994,9 +995,9 @@ $TY_WORKFLOWS_DIR) and can also be dropped in a project's .taskyou/workflows/. Edit the file by hand any time — it's just YAML. Examples: - task pipeline new "spike three approaches, build the best, then write tests" - task pipeline new "plan, implement, security review, then QA in a browser" --name secure-flow - task pipeline new "..." --print # print the YAML without saving`, + ty workflow new "spike three approaches, build the best, then write tests" + ty workflow new "plan, implement, security review, then QA in a browser" --name secure-flow + ty workflow new "..." --print # print the YAML without saving`, Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { desc, _ := cmd.Flags().GetString("body") @@ -1061,7 +1062,7 @@ Examples: fmt.Printf(" %-12s %s/%s%s\n", s.Name, s.Executor, model, dep) } fmt.Println(dimStyle.Render("Saved to " + path + " — edit it any time.")) - fmt.Println(dimStyle.Render("Run it with: task pipeline \"\" --definition " + def.Name)) + fmt.Println(dimStyle.Render("Run it with: ty workflow \"\" --definition " + def.Name)) }, } pipelineNewCmd.Flags().String("body", "", "Workflow description (alternative to the positional argument)") @@ -1069,7 +1070,7 @@ Examples: pipelineNewCmd.Flags().Bool("print", false, "Print the YAML without saving") pipelineCmd.AddCommand(pipelineNewCmd) - // Pipeline edit subcommand - write a workflow to a YAML file for editing + // Workflow edit subcommand - write a workflow to a YAML file for editing pipelineEditCmd := &cobra.Command{ Use: "edit [name]", Short: "Write a workflow to a YAML file you can edit (ejects the built-in)", @@ -1079,9 +1080,9 @@ change models, prompts, or steps by hand. A custom file shadows the built-in of the same name. Examples: - task pipeline edit # eject the default workflow to edit - task pipeline edit plan-code-review # same, explicit - task pipeline edit --print # print the YAML instead of writing it`, + ty workflow edit # eject the default workflow to edit + ty workflow edit plan-code-review # same, explicit + ty workflow edit --print # print the YAML instead of writing it`, Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { name := pipeline.DefaultDefinition @@ -1119,7 +1120,7 @@ Examples: os.Exit(1) } fmt.Println(successStyle.Render("Wrote " + def.Name + " to " + path)) - fmt.Println(dimStyle.Render("Edit it, then run: task pipeline \"\" --definition " + def.Name)) + fmt.Println(dimStyle.Render("Edit it, then run: ty workflow \"\" --definition " + def.Name)) }, } pipelineEditCmd.Flags().Bool("print", false, "Print the YAML instead of writing a file") diff --git a/docs/mcp-tools-reference.md b/docs/mcp-tools-reference.md index ff6af8e0..cdae5194 100644 --- a/docs/mcp-tools-reference.md +++ b/docs/mcp-tools-reference.md @@ -128,10 +128,12 @@ Create a new task in the system. } ``` -### taskyou_create_pipeline +### taskyou_create_workflow Create a multi-step **workflow** for a goal: the goal is split into a DAG of step tasks (default `plan-code-review`: plan → code → two parallel reviewers → collect), each on its own executor/model, sharing one git branch and advancing automatically. Use this instead of a single task when a goal benefits from a plan/code/review split. The first step is queued immediately. Requires a git-worktree project with a remote. See [Workflows](../README.md#workflows). +`taskyou_create_pipeline` is still accepted as a backward-compatible alias for this tool. + **Parameters:** - `goal` (string, required) - The overall goal, threaded into every step's prompt - `project` (string, optional) - Project name (defaults to current project) @@ -141,7 +143,7 @@ Create a multi-step **workflow** for a goal: the goal is split into a DAG of ste **Example:** ```json { - "name": "taskyou_create_pipeline", + "name": "taskyou_create_workflow", "arguments": { "goal": "Add rate limiting to the API", "definition": "plan-code-review" diff --git a/internal/mcp/server.go b/internal/mcp/server.go index 8b18e151..26d22502 100644 --- a/internal/mcp/server.go +++ b/internal/mcp/server.go @@ -258,8 +258,8 @@ func (s *Server) handleRequest(req *jsonRPCRequest) { }, }, { - Name: "taskyou_create_pipeline", - Description: "Create a multi-model pipeline for a goal: one goal is split into an ordered chain of phase tasks (default 'plan-code-review': Opus plans → Sonnet codes → two reviewers run in parallel → collect opens the PR), each routed to its own executor/model, all on one shared git branch. Each step runs on its own executor/model; define custom workflows as YAML (ty pipeline new). Steps advance automatically — sequential where they depend on each other, parallel where they don't. Use this instead of a single task when a goal benefits from a plan/code/review split across different models. The first phase is queued immediately. Requires a git-worktree project with a remote to push to.", + Name: "taskyou_create_workflow", + Description: "Create a multi-model workflow for a goal: one goal is split into an ordered chain of phase tasks (default 'plan-code-review': Opus plans → Sonnet codes → two reviewers run in parallel → collect opens the PR), each routed to its own executor/model, all on one shared git branch. Each step runs on its own executor/model; define custom workflows as YAML (ty workflow new). Steps advance automatically — sequential where they depend on each other, parallel where they don't. Use this instead of a single task when a goal benefits from a plan/code/review split across different models. The first phase is queued immediately. Requires a git-worktree project with a remote to push to.", InputSchema: map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ @@ -273,7 +273,7 @@ func (s *Server) handleRequest(req *jsonRPCRequest) { }, "definition": map[string]interface{}{ "type": "string", - "description": "Pipeline definition name (defaults to 'plan-code-review').", + "description": "Workflow definition name (defaults to 'plan-code-review').", "enum": pipeline.DefinitionNames(), }, "permission_mode": map[string]interface{}{ @@ -577,7 +577,7 @@ func (s *Server) handleToolCall(id interface{}, params *toolCallParams) { }, }) - case "taskyou_create_pipeline": + case "taskyou_create_workflow", "taskyou_create_pipeline": goal, _ := params.Arguments["goal"].(string) if strings.TrimSpace(goal) == "" { s.sendError(id, -32602, "goal is required") @@ -603,7 +603,7 @@ func (s *Server) handleToolCall(id interface{}, params *toolCallParams) { Execute: true, }) if err != nil { - s.sendError(id, -32603, fmt.Sprintf("Failed to create pipeline: %v", err)) + s.sendError(id, -32603, fmt.Sprintf("Failed to create workflow: %v", err)) return } diff --git a/internal/mcp/server_test.go b/internal/mcp/server_test.go index 823b646a..9a567a8f 100644 --- a/internal/mcp/server_test.go +++ b/internal/mcp/server_test.go @@ -101,7 +101,7 @@ func TestToolsList(t *testing.T) { "taskyou_needs_input": false, "taskyou_show_task": false, "taskyou_create_task": false, - "taskyou_create_pipeline": false, + "taskyou_create_workflow": false, "taskyou_list_tasks": false, "taskyou_get_project_context": false, "taskyou_set_project_context": false, diff --git a/internal/pipeline/definition_file.go b/internal/pipeline/definition_file.go index 88570a76..5f3635c2 100644 --- a/internal/pipeline/definition_file.go +++ b/internal/pipeline/definition_file.go @@ -10,7 +10,7 @@ import ( ) // Custom workflows are authored as plain YAML files — one workflow per file — -// so a user (or the LLM in `ty pipeline new`) can define a whole new flow (add a +// so a user (or the LLM in `ty workflow new`) can define a whole new flow (add a // QA step, a different shape) without touching Go. Files live in a global dir // (~/.config/task/workflows) and an optional per-project dir // (/.taskyou/workflows); a project file shadows a global one of the same @@ -28,7 +28,7 @@ type stepYAML struct { Deps []string `yaml:"deps,omitempty"` Prompt string `yaml:"prompt"` // Verbatim marks a step whose prompt IS the full instruction (no DAG-derived - // git handoff is added). It's set when `ty pipeline edit` ejects a built-in + // git handoff is added). It's set when `ty workflow edit` ejects a built-in // workflow, so the ejected file behaves identically to the built-in. Verbatim bool `yaml:"verbatim,omitempty"` } @@ -107,7 +107,7 @@ func ParseDefinition(data []byte) (Definition, error) { return def, nil } -// Marshal renders a Definition back to YAML (used by `ty pipeline new`). +// Marshal renders a Definition back to YAML (used by `ty workflow new`). func Marshal(def Definition) ([]byte, error) { doc := definitionYAML{Name: def.Name, Description: def.Description} for _, s := range def.Steps { diff --git a/internal/pipeline/generate.go b/internal/pipeline/generate.go index 2e8b0019..e36a722e 100644 --- a/internal/pipeline/generate.go +++ b/internal/pipeline/generate.go @@ -14,7 +14,7 @@ import ( // GenerateDefinition turns a free-text description of a workflow into a validated // Definition (and its YAML), using Claude. It's the engine behind -// `ty pipeline new ""`: the user describes the flow in English and +// `ty workflow new ""`: the user describes the flow in English and // gets a ready-to-edit workflow file, instead of authoring YAML by hand. func GenerateDefinition(ctx context.Context, apiKey, description string) (Definition, []byte, error) { if strings.TrimSpace(apiKey) == "" { diff --git a/skills/taskyou/SKILL.md b/skills/taskyou/SKILL.md index 12926c2c..737e1d46 100644 --- a/skills/taskyou/SKILL.md +++ b/skills/taskyou/SKILL.md @@ -62,8 +62,8 @@ Use `ty` (short) or `taskyou` (full) — both work identically. | List by status | `ty list --status --json` | | View task details | `ty show --json --logs` | | Create task | `ty create "title" --body "description"` | -| Create a workflow | `ty pipeline "goal" --project ` (plan → code → parallel review → collect) | -| List / author workflows | `ty pipeline --list` · `ty pipeline new ""` · `ty pipeline edit` | +| Create a workflow | `ty workflow "goal" --project ` (plan → code → parallel review → collect; `ty pipeline` still works as an alias) | +| List / author workflows | `ty workflow --list` · `ty workflow new ""` · `ty workflow edit` | | Execute task | `ty execute ` | | Retry with feedback | `ty retry --feedback "..."` | | Change status | `ty status ` | @@ -249,8 +249,9 @@ the worktree, not the executor inside it. **Task introspection:** - `taskyou_show_task` — Get details of any task in the current project. - `taskyou_create_task` — Create a follow-up task. -- `taskyou_create_pipeline` — Spin up a multi-step workflow (plan → code → +- `taskyou_create_workflow` — Spin up a multi-step workflow (plan → code → parallel review → collect) for a goal, when it warrants more than one task. + (`taskyou_create_pipeline` still works as an alias.) - `taskyou_list_tasks` — See other active tasks in this project. ## Best Practices