Bug fixes
Custom field display for dropdowns and labels
cup task <id> now correctly renders dropdown and labels custom field values instead of showing raw orderindex numbers or UUIDs.
The CustomField.type_config.options[].id field was typed as number but ClickUp's API returns string UUIDs. interactive.ts was doing a broken o.id === Number(field.value) comparison that never matched, so users saw the raw stored value (e.g. 2) instead of the option name (e.g. "High"). Dropdowns now match on orderindex (which is what the API actually stores as the value), and labels match on the string option IDs.
bulk status I/O correctness
cup bulk status <status> <taskIds...> was writing failure messages to stdout. Piping the command (cup bulk status done t1 t2 > ids.txt) would route error lines into the output file. Fixed by routing through the shared outputBulkResult helper that every other bulk subcommand already uses - failures now go to stderr.
Safety improvements
Config file validators
~/.config/cup/config.json is user-editable. Previously the parser used unchecked as FiltersMap / as FavoritesMap casts, so a malformed entry (e.g. filter.command as a string instead of an array) could crash cup filter run with an opaque error. The parser now validates entry shapes and silently drops malformed ones, preserving the rest of the config.
Code quality refactors
runInBatches discriminated union
The bulk operation helper at src/util/batch.ts now returns {item, ok: true, result} | {item, ok: false, error} instead of a struct with two optional fields. This eliminates nonsense states and gives proper TypeScript narrowing. Moved out of src/commands/bulk.ts into a general-purpose util. Added a validation that concurrency is a positive integer.
Shared type guards
isRecord was duplicated identically in src/api.ts and src/config.ts. Deduplicated into src/util/guards.ts.
Minor type cleanups
VALID_TYPESinsrc/commands/favorite.tsis now inferred asSet<FavoriteType>instead of widened toReadonlySet<string>VALID_GROUP_BY_FIELDSinsrc/commands/view-update.tsis aSetnow, eliminating the awkwardas (typeof VALID_GROUP_BY_FIELDS)[number]cast onincludes()
What's not in this release
Large refactors flagged in code review but deferred to future releases:
- Shell completion rewrite (zsh/fish completions drift every release; proper fix is metadata-driven generation)
bulksubcommand pattern normalization (mixed positional/flag style is a breaking change)request<T>generic architecture (mix of runtime validation and generic trust creates redundant casts)
1013 tests (990 -> 1013).