About cawplan-ux-tracking
A skill for querying CawPlan tickets that need UX follow-up, for users organizing work by product, version, team, or priority. It defines filtering, pagination, and verification of UX completion records.
Key features
- 01Query pending UX tickets by product or version
- 02Filter by priority or team
- 03Summarize counts with the stats command
- 04Paginate through complete results
- 05Verify designers' UX completion records
Use cases
- 01Review tickets needing UX follow-up in a version
- 02Count pending tickets by priority
- 03List UX-pending work across a team
- 04Summarize UX completion by designer
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ cawcut/ skill-cawplan --skill cawplan-ux-trackingAfter installing, type/cawplan-ux-trackingin Claude Code to confirm it loaded.
Bundled filesreferences/QUERY_RESILIENCE.md
Details
From the project READMECawPlan UX Tracking
Bootstrap
cawplan skill check
Background
Tickets have ux values NOT_REQUIRED, PENDING, and READY; only PENDING needs UX follow-up.
Use cawplan tickets search, not tickets poll, because poll does not return ux.
Every workflow passes --excluded_status_categories COMPLETE,CANCELED: UX can remain PENDING after a ticket closes. Use category filters, not product-line-specific status keys.
UX queries need the full window:
--start_date 2000-01-01 --end_date <today>
Pagination: increment page_num while page_num * page_size < total; use total as the completion signal. In the hosted agent each page is its own tool call (no shell loops or jq) and a turn has roughly 16 calls: use --page_size 100, and if the pages do not fit, report a partial result (see references/QUERY_RESILIENCE.md).
Counts only ("how many tickets still need UX, by priority/version"): use cawplan tickets stats with the same filters and --group_by priority (or version, assignee) instead of paging and counting.
Follow-ups and failures: follow references/QUERY_RESILIENCE.md. In a follow-up such as "now only CRITICAL+HIGH", keep the earlier product/version scope and add only the new filter. Reuse the IDs when they are visible in your context; otherwise resolve the scope name from the earlier answer again. Never drop the scope, and never pass a product name as --product_ids. If a command is rejected or a page fails, report what was verified as a partial result and do not show commands or error text to the user.
Entry Routing
| Input | Flow |
|---|---|
| A specific product + version ("这个版本需要UX跟进的ticket") | A — Version scope |
| A specific product, no version given, not framed by priority or team | A — Version scope, but ask the user whether they mean a specific version or all versions of the product — "all versions" runs Workflow A step 2 with --product_ids and no --version_ids, no priority filter added (that's Workflow B's filter, not applicable here just because the version was dropped) |
| High-priority + no specific version, or explicitly cross-version | B — Priority scope |
| A Team / product line ("某个team尚未提供UX的清单") | C — Team scope |
| A product's UX members' design completion ("汇总 CawCut Cloud UX Team 本周的 UX 完成情况") | D — Product UX completion |
Workflow A — Version scope
-
Resolve product + version (same pattern as
cawplan-plan-tracksteps 1-2):cawplan products list --search <product-name-word> cawplan versions list <product_id>Pass the search text as one unquoted token (
--search CawPlan, never--search "CawPlan"): the hosted agent rejects quoted values. For a name with spaces, search one distinctive word and match the full name in the results. The supplied product must be an exact accessible-name match (case-insensitive after trimming whitespace), a unique short-form/token-prefix match, or a candidate the user explicitly confirms. If no unique match exists, show the candidates and ask which product they mean before listing versions or querying tickets; never use the closest product name. -
Fetch:
cawplan tickets search --version_ids <version_id> --ux PENDING --excluded_status_categories COMPLETE,CANCELED --start_date 2000-01-01 --end_date <today> --page_size 100 --page_num 1Page through fully (see Pagination above).
For "all versions of this product" (per Entry Routing), drop
--version_idsand use--product_ids <product_id>instead — everything else in this step is unchanged, and no priority filter is added just because there's no version.
Workflow B — Priority scope
- If the user gave a product/version, resolve it the same way as Workflow A and add
--product_ids/--version_ids. If they didn't, ask whether to scope to a product or search across everything they have access to — don't silently assume "everything." - Fetch:
Page through fully (see Pagination above), then sortcawplan tickets search --priority CRITICAL,HIGH --ux PENDING --excluded_status_categories COMPLETE,CANCELED --start_date 2000-01-01 --end_date <today> --page_size 100 --page_num 1 [--product_ids <id>] [--version_ids <id>]CRITICAL→HIGH.
Workflow C — Team scope
- Resolve the Team name to a
product_line_id— same pattern ascawplan-product-report's Team workflow:cawplan product-lines list --page_size 100, match by name client-side. Require an exact name match (case-insensitive after trimming whitespace), a unique short-form/token-prefix match, or explicit user confirmation of a candidate. Ask to disambiguate on multiple matches; if no unique name match exists, list candidates and ask which Team the user means rather than guessing the closest one. - Fetch:
Page through fully (see Pagination above), then sortcawplan tickets search --product_line_ids <product_line_id> --ux PENDING --excluded_status_categories COMPLETE,CANCELED --start_date 2000-01-01 --end_date <today> --page_size 100 --page_num 1CRITICAL→HIGH→MEDIUM→LOW.
Workflow D — Product UX completion
UX Team here means the product's configured members.designers roster, not a CawPlan product
line. If the product is omitted, ask which product's UX members should be reported.
-
Resolve the product and complete the product-access gate used by Workflow A:
cawplan products list --search <product-name-word-or-product_id>Read the matched product's
members.designers[]roster and collect itsuser_idvalues and display names. If it has no Designers, report that the product has no configured UX roster and stop. Membership is product-scoped; use this returned roster, not a workspace-wide keyword search. Default the date window to the current week only when the user does not provide one. -
Fetch every UX change made by the roster in the window with one bulk call (window at most 90 days; split longer ranges):
cawplan tickets changes --product_ids <product_id> --fields ux --actor_ids <designer_user_ids_csv> --start_date <window_start> --end_date <window_end>Keep only events whose
newisREADY. Each event'sactoris the history actor, itsatthe change time, and the response'sticketsmap carries the display ID, title and version for the output. Do not count a Ticket because its currentuxisREADY, because it is assigned to a Designer, or because a non-Designer changed its UX field. If the result istruncated, continue with--cursoror split the window before reporting.Fallback (only if
tickets changesis unavailable, seereferences/QUERY_RESILIENCE.md): fetch candidates withcawplan tickets search --product_ids <product_id> --ux PENDING,READY --start_date 2000-01-01 --end_date <today> --updated_start_date <window_start> --updated_end_date <today> --page_size 100 --page_num 1paged fully (no terminal-status exclusion: a Ticket may have been marked
READYand later closed or moved back toPENDING;updated_atis only a candidate filter). Then, for every candidate, fetchcawplan tickets history <product_id> <version_id> <ticket_id>and keep only anUPDATEDentry whosechanged_fields.uxchanges toREADY(aREADYstring or an object withnew: READY), whosecreated_atis in the window, and whoseuser_idis in the roster. Say that the slower path was used, and report a partial result if not every candidate could be checked. -
Deduplicate by Ticket, retaining its latest in-window UX-Ready event. Group the retained Tickets by that event's actor (
actor.user_id/actor.display_name, or the history entry'suser_id/user_display_nameon the fallback path): this actor is the product roster's Designer who completed the UX work. Never group, count, or infer the Designer from the Ticket's reporter or ordinary assignees.
Output
- One row per matching ticket: display ID, title, type, priority, product/version, assignee.
- Workflow B/C: sorted by priority descending, as above.
- State the search window and that terminal categories are excluded.
- If nothing matches, say so plainly — don't return an empty table with no comment.
- If any page, batch or check could not be completed, say what was verified and what was not
before the table (see
references/QUERY_RESILIENCE.md). Write the answer by the rules inreferences/QUERY_RESILIENCE.md§5: no CLI commands, internal field names or reasoning text. - For Workflow D, show each configured Designer's UX-Ready ticket count and the Ticket list
(display ID, title, product/version, UX-Ready timestamp). State the requested window, the
product used for the UX roster, and that counts are based on history-verified
ux → READYevents.
References
references/CAWPLAN_OPEN_API.mdreferences/QUERY_RESILIENCE.md