diff --git a/agent-teams-controller/src/internal/maintenance.js b/agent-teams-controller/src/internal/maintenance.js
index e650fc6e..c933ace9 100644
--- a/agent-teams-controller/src/internal/maintenance.js
+++ b/agent-teams-controller/src/internal/maintenance.js
@@ -82,7 +82,7 @@ function isAutomatedCommentNotification(message) {
if (!text) return false;
if (text.includes('Reply to this comment using:')) return true;
- if (text.startsWith('Comment on task #')) return true;
+ if (text.startsWith('**Comment on task')) return true;
if (text.startsWith('New comment from user on your task #')) return true;
return false;
}
diff --git a/agent-teams-controller/src/internal/tasks.js b/agent-teams-controller/src/internal/tasks.js
index 47417436..acb1e522 100644
--- a/agent-teams-controller/src/internal/tasks.js
+++ b/agent-teams-controller/src/internal/tasks.js
@@ -65,7 +65,8 @@ function buildAssignmentMessage(context, task, options = {}) {
function buildCommentNotificationMessage(context, task, comment) {
const taskLabel = `#${task.displayId || task.id}`;
return [
- `Comment on task ${taskLabel} "${task.subject}":`,
+ `**Comment on task ${taskLabel}**`,
+ `> ${task.subject}`,
``,
comment.text,
``,
diff --git a/agent-teams-controller/test/controller.test.js b/agent-teams-controller/test/controller.test.js
index 30219aea..322611ef 100644
--- a/agent-teams-controller/test/controller.test.js
+++ b/agent-teams-controller/test/controller.test.js
@@ -416,7 +416,7 @@ describe('agent-teams-controller API', () => {
timestamp: '2026-02-23T11:00:00.000Z',
read: false,
text:
- `Comment on task #${task.displayId} "Ship migration":\n\nHeads up\n\n` +
+ `**Comment on task #${task.displayId}**\n> Ship migration\n\nHeads up\n\n` +
'\nReply to this comment using:\nnode "tool.js" --team my-team task comment 1 --text "..." --from "bob"\n',
},
],
diff --git a/src/main/services/team/TeamMemberLogsFinder.ts b/src/main/services/team/TeamMemberLogsFinder.ts
index d8147674..998ee010 100644
--- a/src/main/services/team/TeamMemberLogsFinder.ts
+++ b/src/main/services/team/TeamMemberLogsFinder.ts
@@ -259,6 +259,7 @@ export class TeamMemberLogsFinder {
if (s) results.push(s);
}
const totalFiles = candidates.length;
+ const step2Count = results.length; // count before step 3 (owner fallback)
const tScan = performance.now();
const normalizedOwner =
@@ -350,13 +351,11 @@ export class TeamMemberLogsFinder {
const tTotal = performance.now();
console.log(
- `[perf] findLogsForTask(${taskId}@${teamName}) ` +
- `total=${(tTotal - t0).toFixed(0)}ms | ` +
- `discovery=${(tDiscovery - t0).toFixed(0)}ms | ` +
- `lead=${(tLead - tDiscovery).toFixed(0)}ms | ` +
- `scan=${(tScan - tLead).toFixed(0)}ms (${totalFiles} files, ${mentionHits} hits) | ` +
- `owner=${(tOwner - tScan).toFixed(0)}ms | ` +
- `sessions=${sessionIds.length} | results=${sorted.length}`
+ `[findLogsForTask] task=${taskId}@${teamName} | ` +
+ `step2=${step2Count} (scan ${mentionHits}/${totalFiles} files) | ` +
+ `step3=${sorted.length - step2Count} (owner=${normalizedOwner ?? 'none'}, includeOwner=${includeOwnerSessions}) | ` +
+ `total=${sorted.length} | ` +
+ `${(tTotal - t0).toFixed(0)}ms`
);
return sorted;
@@ -975,6 +974,12 @@ export class TeamMemberLogsFinder {
const b = block as Record;
if (b.type !== 'tool_use') continue;
+ // Skip read-only task tools — they reference taskId but don't indicate
+ // that this session actually WORKED on the task. Agents commonly call
+ // task_get to check dependencies from other tasks, producing false matches.
+ const toolName = typeof b.name === 'string' ? b.name : '';
+ if (toolName === 'task_get' || toolName === 'mcp__agent-teams__task_get') continue;
+
const input = b.input as Record | undefined;
if (!input) continue;
diff --git a/src/renderer/components/chat/viewers/MarkdownViewer.tsx b/src/renderer/components/chat/viewers/MarkdownViewer.tsx
index 092f2301..0618f3fa 100644
--- a/src/renderer/components/chat/viewers/MarkdownViewer.tsx
+++ b/src/renderer/components/chat/viewers/MarkdownViewer.tsx
@@ -812,6 +812,7 @@ export const MarkdownViewer: React.FC = ({
components={components}
urlTransform={allowCustomProtocols}
allowElement={isAllowedElement}
+ unwrapDisallowed
>
{content}
diff --git a/src/renderer/components/team/kanban/KanbanBoard.tsx b/src/renderer/components/team/kanban/KanbanBoard.tsx
index 270def53..1728a6e4 100644
--- a/src/renderer/components/team/kanban/KanbanBoard.tsx
+++ b/src/renderer/components/team/kanban/KanbanBoard.tsx
@@ -104,8 +104,8 @@ type KanbanViewMode = 'grid' | 'columns';
const COLUMNS: { id: KanbanColumnId; title: string }[] = [
{ id: 'todo', title: 'TODO' },
{ id: 'in_progress', title: 'IN PROGRESS' },
- { id: 'done', title: 'DONE' },
{ id: 'review', title: 'REVIEW' },
+ { id: 'done', title: 'DONE' },
{ id: 'approved', title: 'APPROVED' },
];
diff --git a/src/renderer/components/team/kanban/KanbanGridLayout.tsx b/src/renderer/components/team/kanban/KanbanGridLayout.tsx
index 7159f93f..75c3b944 100644
--- a/src/renderer/components/team/kanban/KanbanGridLayout.tsx
+++ b/src/renderer/components/team/kanban/KanbanGridLayout.tsx
@@ -23,7 +23,7 @@ const DEFAULT_ITEM_HEIGHT = Math.max(
);
const DEFAULT_MIN_HEIGHT = 10;
const DEFAULT_MIN_WIDTH = 3;
-const GRID_SCOPE_KEY = 'kanban-grid-layout:global';
+const GRID_SCOPE_KEY = 'kanban-grid-layout:global:v2';
const SKELETON_HIDE_DELAY_MS = 500;
const RESIZE_HANDLES: ResizeHandleAxis[] = ['s', 'w', 'e', 'n', 'sw', 'nw', 'se', 'ne'];
const WidthAwareGridLayout = WidthProvider(ReactGridLayout);
@@ -54,16 +54,19 @@ interface LoadingKanbanGridLayoutProps {
readonly visibleItems: PersistedGridLayoutItem[];
}
+const ITEMS_PER_FIRST_ROW = 3;
+const SECOND_ROW_ITEM_WIDTH = 6;
+
function buildDefaultItems(itemIds: string[]): PersistedGridLayoutItem[] {
- return itemIds.map((id, index) => ({
- id,
- x: (index % 3) * DEFAULT_ITEM_WIDTH,
- y: Math.floor(index / 3) * DEFAULT_ITEM_HEIGHT,
- w: DEFAULT_ITEM_WIDTH,
- h: DEFAULT_ITEM_HEIGHT,
- minW: DEFAULT_MIN_WIDTH,
- minH: DEFAULT_MIN_HEIGHT,
- }));
+ return itemIds.map((id, index) => {
+ const isSecondRow = index >= ITEMS_PER_FIRST_ROW;
+ const w = isSecondRow ? SECOND_ROW_ITEM_WIDTH : DEFAULT_ITEM_WIDTH;
+ const x = isSecondRow
+ ? (index - ITEMS_PER_FIRST_ROW) * SECOND_ROW_ITEM_WIDTH
+ : index * DEFAULT_ITEM_WIDTH;
+ const y = isSecondRow ? DEFAULT_ITEM_HEIGHT : 0;
+ return { id, x, y, w, h: DEFAULT_ITEM_HEIGHT, minW: DEFAULT_MIN_WIDTH, minH: DEFAULT_MIN_HEIGHT };
+ });
}
function toReactGridLayoutItem(item: PersistedGridLayoutItem): LayoutItem {
diff --git a/src/renderer/components/ui/MentionSuggestionList.tsx b/src/renderer/components/ui/MentionSuggestionList.tsx
index eed589bb..e845a40e 100644
--- a/src/renderer/components/ui/MentionSuggestionList.tsx
+++ b/src/renderer/components/ui/MentionSuggestionList.tsx
@@ -188,6 +188,9 @@ export const MentionSuggestionList = ({
>
+ {!isTask && !isFileOrFolder && s.subtitle ? (
+ {s.subtitle}
+ ) : null}
{isTask && s.ownerName ? (
) : null}
@@ -213,12 +216,12 @@ export const MentionSuggestionList = ({
title={s.isOnline ? 'Online' : 'Offline'}
/>
) : null}
- {s.subtitle && !isTask ? (
+ {s.subtitle && isFileOrFolder ? (
- {isFileOrFolder ? '\u200E' + s.subtitle : s.subtitle}
+ {'\u200E' + s.subtitle}
) : null}