diff --git a/src/main/services/team/TeamProvisioningService.ts b/src/main/services/team/TeamProvisioningService.ts
index 31c3e9cd..1bf08701 100644
--- a/src/main/services/team/TeamProvisioningService.ts
+++ b/src/main/services/team/TeamProvisioningService.ts
@@ -171,7 +171,8 @@ const FS_MONITOR_POLL_MS = 2000;
const TASK_WAIT_FALLBACK_MS = 15_000;
const STALL_CHECK_INTERVAL_MS = 10_000;
const STALL_WARNING_THRESHOLD_MS = 20_000;
-const APP_TEAM_RUNTIME_DISALLOWED_TOOLS = 'TeamDelete,TodoWrite,TaskCreate,TaskUpdate';
+const APP_TEAM_RUNTIME_DISALLOWED_TOOLS =
+ 'TeamDelete,TodoWrite,TaskCreate,TaskUpdate,Agent,mcp__agent-teams__team_launch,mcp__agent-teams__team_stop';
const TEAM_JSON_READ_TIMEOUT_MS = 5_000;
const TEAM_CONFIG_MAX_BYTES = 10 * 1024 * 1024;
const TEAM_INBOX_MAX_BYTES = 2 * 1024 * 1024;
diff --git a/src/renderer/components/team/ClaudeLogsPanel.tsx b/src/renderer/components/team/ClaudeLogsPanel.tsx
index 74e969be..b3417a7e 100644
--- a/src/renderer/components/team/ClaudeLogsPanel.tsx
+++ b/src/renderer/components/team/ClaudeLogsPanel.tsx
@@ -50,6 +50,8 @@ export const ClaudeLogsPanel = ({
pendingNewCount,
isAlive,
filteredText,
+ totalGroupCount,
+ filteredGroupCount,
showMoreVisible,
searchQuery,
setSearchQuery,
@@ -70,10 +72,17 @@ export const ClaudeLogsPanel = ({
{/* Toolbar */}
- {data.total > 0 ? (
+ {totalGroupCount > 0 ? (
<>
- {Math.min(data.total, data.lines.length)} of{' '}
- {data.total}
+ {filteredGroupCount} of{' '}
+ {totalGroupCount} groups
+ {data.total !== totalGroupCount ? (
+ <>
+ {' '}
+ · {data.total}{' '}
+ raw lines
+ >
+ ) : null}
>
) : isAlive ? (
'No logs yet.'
diff --git a/src/renderer/components/team/useClaudeLogsController.ts b/src/renderer/components/team/useClaudeLogsController.ts
index 430ad446..61a4922e 100644
--- a/src/renderer/components/team/useClaudeLogsController.ts
+++ b/src/renderer/components/team/useClaudeLogsController.ts
@@ -19,6 +19,7 @@ import {
setTeamClaudeLogsSidebarUiState,
} from './sidebar/teamSidebarUiState';
import { DEFAULT_CLAUDE_LOGS_FILTER } from './ClaudeLogsFilterPopover';
+import { parseStreamJsonToGroups } from '@renderer/utils/streamJsonParser';
import type { ClaudeLogsFilterState } from './ClaudeLogsFilterPopover';
import type { ClaudeLogsViewerState } from './CliLogsRichView';
@@ -59,6 +60,8 @@ export interface ClaudeLogsController {
filteredText: string;
online: boolean;
badge: number | undefined;
+ totalGroupCount: number;
+ filteredGroupCount: number;
showMoreVisible: boolean;
lastLogPreview: LastLogPreview | null;
@@ -585,7 +588,6 @@ export function useClaudeLogsController(teamName: string): ClaudeLogsController
// ── Computed values ───────────────────────────────────────────────────
const online = useMemo(() => isRecent(data.updatedAt), [data.updatedAt]);
- const badge = data.total > 0 ? data.total : undefined;
const showMoreVisible = data.hasMore || loadingMore;
const lastLogPreview = useMemo(
@@ -593,6 +595,8 @@ export function useClaudeLogsController(teamName: string): ClaudeLogsController
[data.lines]
);
+ const normalizedText = useMemo(() => normalizeToStreamJsonText(data.lines), [data.lines]);
+
const filteredText = useMemo(() => {
if (data.lines.length === 0) return '';
const isDefault =
@@ -601,11 +605,19 @@ export function useClaudeLogsController(teamName: string): ClaudeLogsController
[...DEFAULT_CLAUDE_LOGS_FILTER.streams].every((s) => filter.streams.has(s)) &&
[...DEFAULT_CLAUDE_LOGS_FILTER.kinds].every((k) => filter.kinds.has(k));
- if (!searchQuery.trim() && isDefault) {
- return normalizeToStreamJsonText(data.lines);
- }
+ if (!searchQuery.trim() && isDefault) return normalizedText;
return filterStreamJsonText(data.lines, searchQuery, filter);
- }, [data.lines, searchQuery, filter]);
+ }, [data.lines, normalizedText, searchQuery, filter]);
+
+ const totalGroupCount = useMemo(
+ () => parseStreamJsonToGroups(normalizedText).length,
+ [normalizedText]
+ );
+ const filteredGroupCount = useMemo(
+ () => parseStreamJsonToGroups(filteredText).length,
+ [filteredText]
+ );
+ const badge = totalGroupCount > 0 ? totalGroupCount : undefined;
// ── Container ref callback ────────────────────────────────────────────
const containerRefCallback = useCallback((el: HTMLDivElement | null) => {
@@ -647,6 +659,8 @@ export function useClaudeLogsController(teamName: string): ClaudeLogsController
filteredText,
online,
badge,
+ totalGroupCount,
+ filteredGroupCount,
showMoreVisible,
lastLogPreview,
searchQuery,