diff --git a/.pql/changelog/ticket_history/2026-06.sql b/.pql/changelog/ticket_history/2026-06.sql index 2d8397dd..b4a1cf5e 100644 --- a/.pql/changelog/ticket_history/2026-06.sql +++ b/.pql/changelog/ticket_history/2026-06.sql @@ -3380,3 +3380,18 @@ INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, chang INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6RDM2EKZX132GPV7M', 'status', 'backlog', 'cancelled', NULL, '2026-06-10 15:14:17', '2026-06-10 15:14:17', '2026-06-10 15:14:17', NULL, '992ba3fca9faf99417aaa1a7afa9e6be', 2) ON CONFLICT(hash) DO NOTHING; INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM42M9RK4399B4F4WSG', 'status', 'in_progress', 'done', NULL, '2026-06-10 15:17:59', '2026-06-10 15:17:59', '2026-06-10 15:17:59', NULL, '61000cdb8bb01686c6001f57d16ae717', 2) ON CONFLICT(hash) DO NOTHING; INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM60QRRNEEWG84VWKXC', 'status', 'in_progress', 'done', NULL, '2026-06-10 15:17:59', '2026-06-10 15:17:59', '2026-06-10 15:17:59', NULL, '81990604a08fbedc28075b95538625d6', 2) ON CONFLICT(hash) DO NOTHING; +INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB493JEW32CH0H3771TNHF7G', 'description', NULL, 'Filed 2026-06-10 from a user request: when the agent fans out multiple subagents (Task/Agent tool), each spawned subagent should get its OWN collapsing activity card. The space is worth it — a fan-out of N agents should read as N cards, not one lumped card. + +CURRENT BEHAVIOUR (confirmed): multiple Task/Agent spawns are MERGED into a single shared ''Activity / N steps'' cluster. groupConversation() in lib/builtin/claude/src/activity_cluster.dart:120-147 walks items and coalesces every consecutive _isFoldable item into one FoldedCluster. _isFoldable (:149-172, AssistantToolUse case at :161-164) only distinguishes diff tools (Edit/Write/MultiEdit/NotebookEdit/Update -> stay first-class) from everything else (Task/Agent/Bash/Read/... -> all foldable). The Task tool is treated identically to a Bash/Read call; there is NO subagent-aware grouping key (not toolUseId, not parent_tool_use_id). So 4 spawned agents render as one ''Activity 4 steps'' card. + +What recent work already does (do NOT redo): T-263 folds the subagent PROMPT into the Agent card; T-264 nests the subagent''s RUN items under the parent Agent card (the ''agent run'' collapser); T-338 routes sidechain items to their parent via parent_tool_use_id. All of that is about what shows INSIDE one agent''s card. This ticket is the complement: stop merging DISTINCT agent spawns into a shared cluster. + +SCOPE / DESIGN: +- An AssistantToolUse where _isAgentTool(name) (Task/Agent) should break the current Activity cluster and render as its own first-class collapsing card (its own ClideCollapserCard with the prompt + nested ''agent run'' from T-263/T-264), rather than folding into the generic Activity cluster with sibling tool calls. +- Decide grouping precisely in groupConversation/_isFoldable: an Agent tool-use is a cluster boundary (like a sticky item) OR emits its own single-item card. Adjacent non-agent foldables (Bash/Read/Grep) keep clustering into the normal Activity card as today. +- Label each subagent card by its task/description (the Agent call''s label) so parallel fan-outs are distinguishable, not ''Activity N steps''. +- Keep collapsed-by-default behaviour and the FoldLevel semantics; this changes the grouping boundary, not the fold mechanics. + +Refs: lib/builtin/claude/src/activity_cluster.dart (groupConversation, _isFoldable, isDiffTool), lib/builtin/claude/src/conversation_view.dart (_ActivityCard at ~833, _toolUseCollapser ~615-657, _isAgentTool ~378). Related: T-230 (clustering), T-263, T-264, T-338. + +Tests: a groupConversation case asserting that two consecutive Agent tool-uses yield two separate cards (not one FoldedCluster), while two consecutive Bash calls still yield one Activity cluster.', NULL, '2026-06-10 15:27:01', '2026-06-10 15:27:01', '2026-06-10 15:27:01', NULL, '59b702a540ce65892ea2c6fce5d1a045', 2) ON CONFLICT(hash) DO NOTHING; diff --git a/.pql/changelog/ticket_idmap/2026-06.sql b/.pql/changelog/ticket_idmap/2026-06.sql index 4e22533a..e105d131 100644 --- a/.pql/changelog/ticket_idmap/2026-06.sql +++ b/.pql/changelog/ticket_idmap/2026-06.sql @@ -165,3 +165,5 @@ INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_ INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3JAXDKZMS0805MMEYB6820', 'T-338', '2026-06-10 13:47:04', '2026-06-10 13:47:04', NULL, 'be9b536d471a6008cc854092dfa6aaa4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3JM0AXK1CTWD720RV1AVZ0', 'T-339', '2026-06-10 13:48:18', '2026-06-10 13:48:18', NULL, 'e76a2ce5d3149bb7ca0ec8a45f5c57a2', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3KS499THAD899M0NWN7E3R', 'T-340', '2026-06-10 13:53:23', '2026-06-10 13:53:23', NULL, 'bdd164a73576f6ca5151c8a62640526f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); +INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB44SKPKTHFMV6WD28GZYPXM', 'T-341', '2026-06-10 15:07:43', '2026-06-10 15:07:43', NULL, '113520f8f3a640fa2f470200ea9f45d8', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); +INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB493JEW32CH0H3771TNHF7G', 'T-342', '2026-06-10 15:26:33', '2026-06-10 15:26:33', NULL, '13a646741953f113356c4bcda162c3c9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); diff --git a/.pql/changelog/tickets/2026-06.sql b/.pql/changelog/tickets/2026-06.sql index c64a6294..4ddc41c1 100644 --- a/.pql/changelog/tickets/2026-06.sql +++ b/.pql/changelog/tickets/2026-06.sql @@ -2861,3 +2861,19 @@ INSERT INTO tickets (record_id, type, parent_record_id, title, description, stat 3. A regression test exercises a representative subset (e.g. shift+shift → quick-open command — see Q-9 if the search-everywhere overlay needs its own intent). Correction (2026-06-10): ''see Q-9'' is stale (Q-9 is Lua runtime vendoring). The double-Shift ''Search Everywhere'' chord is NOT expressible by the current matcher (bare/double modifiers unsupported) — tracked in T-341. This preset maps quick-open to Ctrl+Shift+N and the palette to Ctrl+Shift+A as the expressible IntelliJ equivalents.', 'done', 'medium', NULL, NULL, NULL, '2026-04-24 06:34:16', '2026-06-10 15:17:59', NULL, '58c6bc49c1ec261dfffc3d5d60fc44a5', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB493JEW32CH0H3771TNHF7G', 'story', '06FB0TNQM5TWC00GW0P3X02HZW', 'Give each spawned subagent its own collapsing activity card (don''t merge Task spawns)', NULL, 'backlog', 'medium', NULL, NULL, NULL, '2026-06-10 15:26:33', '2026-06-10 15:26:33', NULL, '49ed852675b4f44fcef84d079146f207', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB493JEW32CH0H3771TNHF7G', 'story', '06FB0TNQM5TWC00GW0P3X02HZW', 'Give each spawned subagent its own collapsing activity card (don''t merge Task spawns)', 'Filed 2026-06-10 from a user request: when the agent fans out multiple subagents (Task/Agent tool), each spawned subagent should get its OWN collapsing activity card. The space is worth it — a fan-out of N agents should read as N cards, not one lumped card. + +CURRENT BEHAVIOUR (confirmed): multiple Task/Agent spawns are MERGED into a single shared ''Activity / N steps'' cluster. groupConversation() in lib/builtin/claude/src/activity_cluster.dart:120-147 walks items and coalesces every consecutive _isFoldable item into one FoldedCluster. _isFoldable (:149-172, AssistantToolUse case at :161-164) only distinguishes diff tools (Edit/Write/MultiEdit/NotebookEdit/Update -> stay first-class) from everything else (Task/Agent/Bash/Read/... -> all foldable). The Task tool is treated identically to a Bash/Read call; there is NO subagent-aware grouping key (not toolUseId, not parent_tool_use_id). So 4 spawned agents render as one ''Activity 4 steps'' card. + +What recent work already does (do NOT redo): T-263 folds the subagent PROMPT into the Agent card; T-264 nests the subagent''s RUN items under the parent Agent card (the ''agent run'' collapser); T-338 routes sidechain items to their parent via parent_tool_use_id. All of that is about what shows INSIDE one agent''s card. This ticket is the complement: stop merging DISTINCT agent spawns into a shared cluster. + +SCOPE / DESIGN: +- An AssistantToolUse where _isAgentTool(name) (Task/Agent) should break the current Activity cluster and render as its own first-class collapsing card (its own ClideCollapserCard with the prompt + nested ''agent run'' from T-263/T-264), rather than folding into the generic Activity cluster with sibling tool calls. +- Decide grouping precisely in groupConversation/_isFoldable: an Agent tool-use is a cluster boundary (like a sticky item) OR emits its own single-item card. Adjacent non-agent foldables (Bash/Read/Grep) keep clustering into the normal Activity card as today. +- Label each subagent card by its task/description (the Agent call''s label) so parallel fan-outs are distinguishable, not ''Activity N steps''. +- Keep collapsed-by-default behaviour and the FoldLevel semantics; this changes the grouping boundary, not the fold mechanics. + +Refs: lib/builtin/claude/src/activity_cluster.dart (groupConversation, _isFoldable, isDiffTool), lib/builtin/claude/src/conversation_view.dart (_ActivityCard at ~833, _toolUseCollapser ~615-657, _isAgentTool ~378). Related: T-230 (clustering), T-263, T-264, T-338. + +Tests: a groupConversation case asserting that two consecutive Agent tool-uses yield two separate cards (not one FoldedCluster), while two consecutive Bash calls still yield one Activity cluster.', 'backlog', 'medium', NULL, NULL, NULL, '2026-06-10 15:26:33', '2026-06-10 15:27:01', NULL, 'd82afb6688c82c068d6020a279652736', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);