Skip to content

Display task titles in CLI UI instead of class type names - #665

Merged
sroussey merged 3 commits into
mainfrom
claude/unknown-sec-form-12g32br-cy56lf
Aug 1, 2026
Merged

Display task titles in CLI UI instead of class type names#665
sroussey merged 3 commits into
mainfrom
claude/unknown-sec-form-12g32br-cy56lf

Conversation

@sroussey

@sroussey sroussey commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

This change improves the CLI task display by showing task instance titles (when configured) instead of always showing the class type name. This allows users to distinguish between multiple instances of the same task class (e.g., two "DownloadTask" instances downloading different files).

Key Changes

  • New cliTaskLabel() function in taskGraphCliSubscriptions.ts that returns a task's instance title if set, falling back to the class type name, or "Unknown" as a last resort
  • Updated CliTaskLine interface to include a label field (display name) separate from type (class identity)
  • Refactored task listener registration to use taskLabel instead of taskType for user-facing messages (e.g., completion logs)
  • Updated all task row components (ChatTaskRow, DefaultTaskRow, StreamingTextRow, SubtaskRows, TaskStatusLine, TaskStatusProgressRow) to use the new label prop instead of type
  • Enhanced IExecuteContext.own() signature to accept an optional TaskConfig parameter, allowing callers to configure owned tasks/graphs/workflows (particularly useful for naming anonymous owned workflows)
  • Added comprehensive test coverage for cliTaskLabel() behavior with 5 test cases covering title preference, fallback logic, and edge cases

Implementation Details

  • The label field is computed once when tasks are registered and stored in CliTaskLine for efficient rendering
  • Empty string titles are treated as unset (same as undefined), matching the Task base class convention
  • The change is backward compatible—all existing code paths continue to work, with improved UX for configured task titles
  • Test file added at examples/cli/src/test/cliTaskLabel.test.ts with full coverage of the labeling logic

https://claude.ai/code/session_01D9HvGjLQ2SGHo1nYxSUrUa

claude added 2 commits August 1, 2026 19:44
The workflow progress UI rendered `task.type` for every row, so two
instances of one class — the two `BootstrapDownloadTask`s in `sec
bootstrap`, fetching submissions.zip and companyfacts.zip — showed as two
identical rows, and the `title` callers already set was never displayed.

`CliTaskLine` now carries a `label` (the instance `title`, else the class
type name) alongside `type`, which stays as the renderer-dispatch key so
`pickRenderer` / `isRedundantSubgraph` keep matching on class identity.
`TaskStatusLine`/`TaskStatusProgressRow` take `label` — that prop was
always a display string (iteration rows pass `#1`), so the rename removes
the last place a class name was hardcoded as UI text.

`IExecuteContext.own` gains an optional config. A graph or workflow is
adapted into a wrapper task the caller never sees, so this is the only way
to name one; without it every `context.own(new Workflow())` renders as the
same anonymous `Own[Workflow]` row.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D9HvGjLQ2SGHo1nYxSUrUa
Missed in the label rename: DefaultTaskRow's per-iteration row still
passed `type`, which no longer exists on TaskStatusProgressRowProps.
Vitest transpiles TSX without typechecking, so only `build-types` caught it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D9HvGjLQ2SGHo1nYxSUrUa
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 62.21% 27912 / 44867
🔵 Statements 62.08% 28933 / 46604
🔵 Functions 62.37% 5313 / 8518
🔵 Branches 51.12% 13733 / 26860
File CoverageNo changed files found.
Generated in workflow #2820 for commit a21a1ed by the Vitest Coverage Report Action

…er row

A task that owns a workflow produces a wrapper row whose children are the
actual work, and SubtaskRows stopped at that wrapper — so `sec bootstrap`
showed a lone "Own[Workflow]" line with the pipeline inside it invisible.

Rows now recurse: each subtask renders its own subgraph beneath it, to a
bounded depth (the breadth cap otherwise multiplies into more rows, and
more attach pollers, than a terminal can use). To make that affordable,
`useSubtaskRows` stops its 150ms attach poll once a childless task has
settled — previously every leaf kept waking for the life of the run, which
recursion would have multiplied.

The four graph wrappers also get plain titles. They inherited "Group" from
GraphAsTask, so with rows now labelled by title an unnamed subgraph would
have read "Group" rather than the kind of subgraph it is.

Covered by a test that fails when the recursion is disabled.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D9HvGjLQ2SGHo1nYxSUrUa
@sroussey
sroussey merged commit 78e5e09 into main Aug 1, 2026
14 checks passed
@sroussey
sroussey deleted the claude/unknown-sec-form-12g32br-cy56lf branch August 1, 2026 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants